summary.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with this
  4. * work for additional information regarding copyright ownership. The ASF
  5. * licenses this file to you under the Apache License, Version 2.0 (the
  6. * "License"); you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  14. * License for the specific language governing permissions and limitations under
  15. * the License.
  16. */
  17. var App = require('app');
  18. App.MainServiceInfoSummaryController = Em.Controller.extend({
  19. name: 'mainServiceInfoSummaryController',
  20. selectedFlumeAgent: null,
  21. /**
  22. * Indicates whether Ranger plugins status update polling is active
  23. * @type {boolean}
  24. */
  25. isRangerUpdateWorking: false,
  26. /**
  27. * Indicates whether array with initial Ranger plugins data is set
  28. * @type {boolean}
  29. */
  30. isRangerPluginsArraySet: false,
  31. /**
  32. * Indicates whether previous AJAX request for Ranger plugins config properties has failed
  33. * @type {boolean}
  34. */
  35. isPreviousRangerConfigsCallFailed: false,
  36. /**
  37. * Ranger plugins data
  38. * @type {array}
  39. */
  40. rangerPlugins: [
  41. {
  42. serviceName: 'HDFS',
  43. type: 'ranger-hdfs-plugin-properties',
  44. propertyName: 'ranger-hdfs-plugin-enabled'
  45. },
  46. {
  47. serviceName: 'HIVE',
  48. type: 'ranger-hive-plugin-properties',
  49. propertyName: 'ranger-hive-plugin-enabled'
  50. },
  51. {
  52. serviceName: 'HBASE',
  53. type: 'ranger-hbase-plugin-properties',
  54. propertyName: 'ranger-hbase-plugin-enabled'
  55. },
  56. {
  57. serviceName: 'KNOX',
  58. type: 'ranger-knox-plugin-properties',
  59. propertyName: 'ranger-knox-plugin-enabled'
  60. },
  61. {
  62. serviceName: 'STORM',
  63. type: 'ranger-storm-plugin-properties',
  64. propertyName: 'ranger-storm-plugin-enabled'
  65. }
  66. ],
  67. /**
  68. * Set initial Ranger plugins data
  69. * @method setRangerPlugins
  70. */
  71. setRangerPlugins: function () {
  72. if (App.get('router.clusterController.isLoaded') && !this.get('isRangerPluginsArraySet')) {
  73. this.setProperties({
  74. rangerPlugins: this.get('rangerPlugins').map(function (item) {
  75. var stackService = App.StackService.find().findProperty('serviceName', item.serviceName);
  76. var displayName = (stackService) ? stackService.get('displayName') : item.serviceName;
  77. return $.extend(item, {
  78. pluginTitle: Em.I18n.t('services.service.summary.ranger.plugin.title').format(displayName),
  79. isDisplayed: App.Service.find().someProperty('serviceName', item.serviceName),
  80. status: Em.I18n.t('services.service.summary.ranger.plugin.loadingStatus')
  81. });
  82. }),
  83. isRangerPluginsArraySet: true
  84. });
  85. }
  86. }.observes('App.router.clusterController.isLoaded'),
  87. /**
  88. * Get latest config tags
  89. * @method updateRangerPluginsStatus
  90. * @param callback
  91. */
  92. updateRangerPluginsStatus: function (callback) {
  93. App.ajax.send({
  94. name: 'config.tags',
  95. sender: this,
  96. success: 'getRangerPluginsStatus',
  97. callback: callback
  98. });
  99. },
  100. /**
  101. * Get latest Ranger plugins config properties
  102. * @method getRangerPluginsStatus
  103. * @param data
  104. */
  105. getRangerPluginsStatus: function (data) {
  106. var urlParams = [];
  107. this.get('rangerPlugins').forEach(function (item) {
  108. if (App.Service.find().someProperty('serviceName', item.serviceName)) {
  109. var currentTag = data.Clusters.desired_configs[item.type].tag;
  110. var isTagChanged = item.tag != currentTag;
  111. Em.set(item, 'isDisplayed', true);
  112. //Request for properties should be sent either if configs have changed or if previous Ranger plugins config properties has failed
  113. if (isTagChanged || this.get('isPreviousRangerConfigsCallFailed')) {
  114. Em.set(item, 'tag', currentTag);
  115. urlParams.push('(type=' + item.type + '&tag=' + currentTag + ')');
  116. }
  117. } else {
  118. Em.set(item, 'isDisplayed', false);
  119. }
  120. }, this);
  121. if (urlParams.length) {
  122. App.ajax.send({
  123. name: 'reassign.load_configs',
  124. sender: this,
  125. data: {
  126. urlParams: urlParams.join('|')
  127. },
  128. success: 'getRangerPluginsStatusSuccess',
  129. error: 'getRangerPluginsStatusError'
  130. });
  131. }
  132. },
  133. /**
  134. * Set Ranger plugins statuses
  135. * @method getRangerPluginsStatusSuccess
  136. * @param data
  137. */
  138. getRangerPluginsStatusSuccess: function (data) {
  139. this.set('isPreviousRangerConfigsCallFailed', false);
  140. data.items.forEach(function (item) {
  141. var serviceName = this.get('rangerPlugins').findProperty('type', item.type).serviceName;
  142. var propertyName = this.get('rangerPlugins').findProperty('type', item.type).propertyName;
  143. var statusMap = {
  144. Yes: 'alerts.table.state.enabled',
  145. No: 'alerts.table.state.disabled'
  146. };
  147. var statusString = statusMap[item.properties[propertyName]] || 'common.unknown';
  148. Em.set(this.get('rangerPlugins').findProperty('serviceName', serviceName), 'status', Em.I18n.t(statusString));
  149. }, this);
  150. },
  151. /**
  152. * Method executed if Ranger plugins config properties request has failed
  153. * @method getRangerPluginsStatusError
  154. */
  155. getRangerPluginsStatusError: function () {
  156. this.set('isPreviousRangerConfigsCallFailed', true);
  157. },
  158. /**
  159. * Send start command for selected Flume Agent
  160. * @method startFlumeAgent
  161. */
  162. startFlumeAgent: function () {
  163. var selectedFlumeAgent = arguments[0].context;
  164. if (selectedFlumeAgent && selectedFlumeAgent.get('status') === 'NOT_RUNNING') {
  165. var self = this;
  166. App.showConfirmationPopup(function () {
  167. var state = 'STARTED';
  168. var context = Em.I18n.t('services.service.summary.flume.start.context').format(selectedFlumeAgent.get('name'));
  169. self.sendFlumeAgentCommandToServer(state, context, selectedFlumeAgent);
  170. });
  171. }
  172. },
  173. /**
  174. * Send stop command for selected Flume Agent
  175. * @method stopFlumeAgent
  176. */
  177. stopFlumeAgent: function () {
  178. var selectedFlumeAgent = arguments[0].context;
  179. if (selectedFlumeAgent && selectedFlumeAgent.get('status') === 'RUNNING') {
  180. var self = this;
  181. App.showConfirmationPopup(function () {
  182. var state = 'INSTALLED';
  183. var context = Em.I18n.t('services.service.summary.flume.stop.context').format(selectedFlumeAgent.get('name'));
  184. self.sendFlumeAgentCommandToServer(state, context, selectedFlumeAgent);
  185. });
  186. }
  187. },
  188. /**
  189. * Send command for Flume Agent to server
  190. * @param {string} state
  191. * @param {string} context
  192. * @param {Object} agent
  193. * @method sendFlumeAgentCommandToServer
  194. */
  195. sendFlumeAgentCommandToServer: function (state, context, agent) {
  196. App.ajax.send({
  197. name: 'service.flume.agent.command',
  198. sender: this,
  199. data: {
  200. state: state,
  201. context: context,
  202. agentName: agent.get('name'),
  203. host: agent.get('hostName')
  204. },
  205. success: 'commandSuccessCallback'
  206. });
  207. },
  208. /**
  209. * Callback, that shows Background operations popup if request was successful
  210. */
  211. commandSuccessCallback: function () {
  212. console.log('Send request for refresh configs successfully');
  213. // load data (if we need to show this background operations popup) from persist
  214. App.router.get('applicationController').dataLoading().done(function (showPopup) {
  215. if (showPopup) {
  216. App.router.get('backgroundOperationsController').showPopup();
  217. }
  218. });
  219. },
  220. gotoConfigs: function () {
  221. App.router.get('mainServiceItemController').set('routeToConfigs', true);
  222. App.router.transitionTo('main.services.service.configs', this.get('content'));
  223. App.router.get('mainServiceItemController').set('routeToConfigs', false);
  224. },
  225. showServiceAlertsPopup: function (event) {
  226. var service = event.context;
  227. return App.ModalPopup.show({
  228. header: Em.I18n.t('services.service.summary.alerts.popup.header').format(service.get('displayName')),
  229. autoHeight: false,
  230. bodyClass: Em.View.extend({
  231. templateName: require('templates/main/service/info/service_alert_popup'),
  232. classNames: ['service-alerts'],
  233. controllerBinding: 'App.router.mainAlertDefinitionsController',
  234. didInsertElement: function () {
  235. Em.run.next(this, function () {
  236. App.tooltip($(".timeago"));
  237. });
  238. },
  239. alerts: function () {
  240. var serviceDefinitions = this.get('controller.content').filterProperty('service', service);
  241. // definitions should be sorted in order: critical, warning, ok, unknown, other
  242. var criticalDefinitions = [], warningDefinitions = [], okDefinitions = [], unknownDefinitions = [];
  243. serviceDefinitions.forEach(function (definition) {
  244. if (definition.get('isCritical')) {
  245. criticalDefinitions.push(definition);
  246. serviceDefinitions = serviceDefinitions.without(definition);
  247. } else if (definition.get('isWarning')) {
  248. warningDefinitions.push(definition);
  249. serviceDefinitions = serviceDefinitions.without(definition);
  250. } else if (definition.get('isOK')) {
  251. okDefinitions.push(definition);
  252. serviceDefinitions = serviceDefinitions.without(definition);
  253. } else if (definition.get('isUnknown')) {
  254. unknownDefinitions.push(definition);
  255. serviceDefinitions = serviceDefinitions.without(definition);
  256. }
  257. });
  258. serviceDefinitions = criticalDefinitions.concat(warningDefinitions, okDefinitions, unknownDefinitions, serviceDefinitions);
  259. return serviceDefinitions;
  260. }.property('controller.content'),
  261. gotoAlertDetails: function (event) {
  262. if (event && event.context) {
  263. this.get('parentView').hide();
  264. App.router.transitionTo('main.alerts.alertDetails', event.context);
  265. }
  266. },
  267. closePopup: function () {
  268. this.get('parentView').hide();
  269. }
  270. }),
  271. isHideBodyScroll: false,
  272. primary: Em.I18n.t('common.close'),
  273. secondary: null
  274. });
  275. },
  276. /**
  277. * @type {boolean}
  278. */
  279. isWidgetsLoaded: false,
  280. /**
  281. * @type Em.A
  282. */
  283. widgets: function() {
  284. return App.Widget.find().filterProperty('serviceName', this.get('content.serviceName'));
  285. }.property('isWidgetsLoaded'),
  286. /**
  287. * load widgets defined by user
  288. * @returns {$.ajax}
  289. */
  290. loadWidgets: function () {
  291. this.set('isWidgetsLoaded', false);
  292. return App.ajax.send({
  293. name: 'widgets.layout.userDefined.get',
  294. sender: this,
  295. data: {
  296. loginName: App.router.get('loginName'),
  297. sectionName: this.get('content.serviceName') + "_SUMMARY"
  298. },
  299. success: 'loadWidgetsSuccessCallback'
  300. });
  301. },
  302. /**
  303. * success callback of <code>loadWidgets()</code>
  304. * @param {object|null} data
  305. */
  306. loadWidgetsSuccessCallback: function (data) {
  307. if (data.items[0]) {
  308. App.widgetMapper.map(data.items[0], this.get('content.serviceName'));
  309. this.set('isWidgetsLoaded', true);
  310. } else {
  311. this.loadStackWidgetsLayout();
  312. }
  313. },
  314. /**
  315. * load widgets defined by stack
  316. * @returns {$.ajax}
  317. */
  318. loadStackWidgetsLayout: function () {
  319. return App.ajax.send({
  320. name: 'widgets.layout.stackDefined.get',
  321. sender: this,
  322. data: {
  323. stackVersionURL: App.get('stackVersionURL'),
  324. serviceName: this.get('content.serviceName')
  325. },
  326. success: 'loadStackWidgetsLayoutSuccessCallback',
  327. error: 'loadStackWidgetsLayoutErrorCallback'
  328. });
  329. },
  330. /**
  331. * success callback of <code>loadStackWidgetsLayout()</code>
  332. * @param {object|null} data
  333. */
  334. loadStackWidgetsLayoutSuccessCallback: function (data) {
  335. App.widgetMapper.map(data.artifact_data.layouts.findProperty('section_name', (this.get('content.serviceName') + "_SUMMARY")), this.get('content.serviceName'));
  336. this.set('isWidgetsLoaded', true);
  337. }
  338. });