stack_service.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  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. require('utils/helper');
  20. require('mixins/models/service_mixin');
  21. require('models/service_config');
  22. //TODO after moving validation/recommendation to BE belove requirements must be deleted
  23. require('utils/configs/defaults_providers/yarn_defaults_provider');
  24. require('utils/configs/defaults_providers/tez_defaults_provider');
  25. require('utils/configs/defaults_providers/hive_defaults_provider');
  26. require('utils/configs/defaults_providers/storm_defaults_provider');
  27. require('utils/configs/defaults_providers/oozie_defaults_provider');
  28. require('utils/configs/validators/yarn_configs_validator');
  29. require('utils/configs/validators/hive_configs_validator');
  30. require('utils/configs/validators/tez_configs_validator');
  31. require('utils/configs/validators/mapreduce2_configs_validator');
  32. require('utils/configs/validators/storm_configs_validator');
  33. /**
  34. * This model loads all services supported by the stack
  35. * The model maps to the http://hostname:8080/api/v1/stacks2/HDP/versions/${versionNumber}/stackServices?fields=StackServices/*,serviceComponents/*
  36. * @type {*}
  37. */
  38. App.StackService = DS.Model.extend(App.ServiceModelMixin, {
  39. comments: DS.attr('string'),
  40. configTypes: DS.attr('object'),
  41. serviceVersion: DS.attr('string'),
  42. serviceCheckSupported: DS.attr('boolean'),
  43. stackName: DS.attr('string'),
  44. stackVersion: DS.attr('string'),
  45. isSelected: DS.attr('boolean', {defaultValue: true}),
  46. isInstalled: DS.attr('boolean', {defaultValue: false}),
  47. serviceComponents: DS.hasMany('App.StackServiceComponent'),
  48. configs: DS.attr('array'),
  49. // Is the service a distributed filesystem
  50. isDFS: function () {
  51. var dfsServices = ['HDFS', 'GLUSTERFS'];
  52. return dfsServices.contains(this.get('serviceName'));
  53. }.property('serviceName'),
  54. // Primary DFS. used if there is more than one DFS in a stack.
  55. // Only one service in the stack should be tagged as primary DFS.
  56. isPrimaryDFS: function () {
  57. return this.get('serviceName') === 'HDFS';
  58. }.property('serviceName'),
  59. configTypesRendered: function () {
  60. var configTypes = this.get('configTypes');
  61. if (this.get('serviceName') == 'HDFS' || this.get('serviceName') == 'GLUSTERFS') return configTypes;
  62. else {
  63. var renderedConfigTypes = $.extend(true, {}, configTypes);
  64. delete renderedConfigTypes['core-site'];
  65. return renderedConfigTypes
  66. }
  67. }.property('serviceName', 'configTypes'),
  68. displayNameOnSelectServicePage: function () {
  69. var displayName = this.get('displayName');
  70. var services = this.get('coSelectedServices').slice();
  71. var serviceDisplayNames = services.map(function (item) {
  72. return App.format.role(item);
  73. }, this);
  74. if (!!serviceDisplayNames.length) {
  75. serviceDisplayNames.unshift(displayName);
  76. displayName = serviceDisplayNames.join(" + ");
  77. }
  78. return displayName;
  79. }.property('coSelectedServices', 'serviceName'),
  80. isHiddenOnSelectServicePage: function () {
  81. var hiddenServices = ['MAPREDUCE2', 'HCATALOG', 'WEBHCAT'];
  82. return hiddenServices.contains(this.get('serviceName'));
  83. }.property('serviceName'),
  84. dependentServices: function () {
  85. var serviceName = this.get('serviceName');
  86. var dependentServices = [];
  87. if (App.get('isHadoop2Stack')) {
  88. dependentServices = App.StackService.dependency['HDP-2'][serviceName];
  89. } else {
  90. dependentServices = App.StackService.dependency['HDP-1'][serviceName];
  91. }
  92. return dependentServices;
  93. }.property('serviceName'),
  94. /**
  95. * other services on which the service is dependent
  96. */
  97. serviceDependency: function () {
  98. var serviceName = this.get('serviceName');
  99. var serviceDependencyMap, key, serviceDependencies = [];
  100. if (App.get('isHadoop2Stack')) {
  101. serviceDependencyMap = App.StackService.dependency['HDP-2'];
  102. } else {
  103. serviceDependencyMap = App.StackService.dependency['HDP-1'];
  104. }
  105. for (key in serviceDependencyMap) {
  106. if (serviceDependencyMap[key].contains(serviceName)) serviceDependencies.pushObject(key);
  107. }
  108. return serviceDependencies;
  109. }.property('serviceName'),
  110. // Is the service required for monitoring of other hadoop ecosystem services
  111. isMonitoringService: function () {
  112. var services = ['NAGIOS', 'GANGLIA'];
  113. return services.contains(this.get('serviceName'));
  114. }.property('serviceName'),
  115. coSelectedServices: function () {
  116. var coSelectedServices = App.StackService.coSelected[this.get('serviceName')];
  117. if (!!coSelectedServices) {
  118. return coSelectedServices;
  119. } else {
  120. return [];
  121. }
  122. }.property('serviceName'),
  123. hasClient: function () {
  124. var serviceComponents = this.get('serviceComponents');
  125. return serviceComponents.someProperty('isClient');
  126. }.property('serviceName'),
  127. hasMaster: function () {
  128. var serviceComponents = this.get('serviceComponents');
  129. return serviceComponents.someProperty('isMaster');
  130. }.property('serviceName'),
  131. hasSlave: function () {
  132. var serviceComponents = this.get('serviceComponents');
  133. return serviceComponents.someProperty('isSlave');
  134. }.property('serviceName'),
  135. isClientOnlyService: function () {
  136. var serviceComponents = this.get('serviceComponents');
  137. return serviceComponents.everyProperty('isClient');
  138. }.property('serviceName'),
  139. isNoConfigTypes: function () {
  140. var configTypes = this.get('configTypes');
  141. return !(configTypes && !!Object.keys(configTypes).length);
  142. }.property('configTypes'),
  143. customReviewHandler: function () {
  144. return App.StackService.reviewPageHandlers[this.get('serviceName')];
  145. }.property('serviceName'),
  146. //TODO after moving validation/recommendation to BE defaultsProviders must be deleted
  147. defaultsProviders: function () {
  148. var defaultConfigsHandler = App.StackService.defaultConfigsHandler[this.get('serviceName')];
  149. return defaultConfigsHandler && defaultConfigsHandler.defaultsProviders;
  150. }.property('serviceName'),
  151. //TODO after moving validation/recommendation to BE configsValidator must be deleted
  152. configsValidator: function () {
  153. var defaultConfigsHandler = App.StackService.defaultConfigsHandler[this.get('serviceName')];
  154. return defaultConfigsHandler && defaultConfigsHandler.configsValidator;
  155. }.property('serviceName'),
  156. /**
  157. * configCategories are fetched from App.StackService.configCategories.
  158. * Also configCategories that does not match any serviceComponent of a service and not included in the permissible default pattern are omitted
  159. */
  160. configCategories: function () {
  161. var configCategories = [];
  162. var serviceName = this.get('serviceName');
  163. var configTypes = this.get('configTypes');
  164. var serviceComponents = this.get('serviceComponents');
  165. if (configTypes && Object.keys(configTypes).length) {
  166. var pattern = ["General", "CapacityScheduler", "^Advanced", "Env$", "^Custom", "Falcon - Oozie integration", "FalconStartupSite", "FalconRuntimeSite"];
  167. configCategories = App.StackService.configCategories.call(this).filter(function (_configCategory) {
  168. var serviceComponentName = _configCategory.get('name');
  169. var isServiceComponent = serviceComponents.someProperty('componentName', serviceComponentName);
  170. if (isServiceComponent) return isServiceComponent;
  171. var result = false;
  172. pattern.forEach(function (_pattern) {
  173. var regex = new RegExp(_pattern);
  174. if (regex.test(serviceComponentName)) result = true;
  175. });
  176. return result;
  177. });
  178. }
  179. return configCategories;
  180. }.property('serviceName', 'configTypes', 'serviceComponents')
  181. });
  182. App.StackService.FIXTURES = [];
  183. App.StackService.displayOrder = [
  184. 'HDFS',
  185. 'GLUSTERFS',
  186. 'MAPREDUCE',
  187. 'MAPREDUCE2',
  188. 'YARN',
  189. 'TEZ',
  190. 'NAGIOS',
  191. 'GANGLIA',
  192. 'HIVE',
  193. 'HCATALOG',
  194. 'WEBHCAT',
  195. 'HBASE',
  196. 'PIG',
  197. 'SQOOP',
  198. 'OOZIE',
  199. 'ZOOKEEPER',
  200. 'HUE',
  201. 'FALCON',
  202. 'STORM',
  203. 'FLUME'
  204. ];
  205. App.StackService.dependency = {
  206. 'HDP-1': {
  207. 'HDFS': ['MAPREDUCE', 'HBASE', 'SQOOP'],
  208. 'MAPREDUCE': ['PIG', 'OOZIE', 'HIVE'],
  209. 'ZOOKEEPER': ['HBASE', 'HIVE', 'WEBHCAT']
  210. },
  211. 'HDP-2': {
  212. 'ZOOKEEPER': ['HDFS', 'HBASE', 'HIVE', 'WEBHCAT', 'STORM'],
  213. 'HDFS': ['YARN', 'HBASE', 'FLUME', 'SQOOP'],
  214. 'YARN': ['PIG', 'OOZIE', 'HIVE', 'TEZ'],
  215. 'TEZ': ['YARN'],
  216. 'OOZIE': ['FALCON']
  217. }
  218. };
  219. //@TODO: Write unit test for no two keys in the object should have any intersecting elements in their values
  220. App.StackService.coSelected = {
  221. 'YARN': ['MAPREDUCE2'],
  222. 'HIVE': ['HCATALOG', 'WEBHCAT']
  223. };
  224. App.StackService.reviewPageHandlers = {
  225. 'HIVE': {
  226. 'Database': 'loadHiveDbValue'
  227. },
  228. 'NAGIOS': {
  229. 'Administrator': 'loadNagiosAdminValue'
  230. },
  231. 'OOZIE': {
  232. 'Database': 'loadOozieDbValue'
  233. }
  234. };
  235. //TODO after moving validation/recommendation to BE defaultConfigsHandler must be deleted
  236. App.StackService.defaultConfigsHandler = {
  237. YARN: {defaultsProviders: [App.YARNDefaultsProvider.create()], configsValidator: App.YARNConfigsValidator},
  238. MAPREDUCE2: {defaultsProviders: [App.YARNDefaultsProvider.create()], configsValidator: App.MapReduce2ConfigsValidator},
  239. HIVE: {defaultsProviders: [App.HiveDefaultsProvider.create()], configsValidator: App.HiveConfigsValidator},
  240. STORM: {defaultsProviders: [App.STORMDefaultsProvider.create()], configsValidator: App.STORMConfigsValidator},
  241. TEZ: {defaultsProviders: [App.TezDefaultsProvider.create()], configsValidator: App.TezConfigsValidator}
  242. };
  243. App.StackService.configCategories = function () {
  244. var serviceConfigCategories = [];
  245. switch (this.get('serviceName')) {
  246. case 'HDFS':
  247. serviceConfigCategories.pushObjects([
  248. App.ServiceConfigCategory.create({ name: 'NAMENODE', displayName: 'NameNode'}),
  249. App.ServiceConfigCategory.create({ name: 'SECONDARY_NAMENODE', displayName: 'Secondary NameNode'}),
  250. App.ServiceConfigCategory.create({ name: 'DATANODE', displayName: 'DataNode'}),
  251. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  252. ]);
  253. break;
  254. case 'GLUSTERFS':
  255. serviceConfigCategories.pushObjects([
  256. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  257. ]);
  258. break;
  259. case 'MAPREDUCE':
  260. serviceConfigCategories.pushObjects([
  261. App.ServiceConfigCategory.create({ name: 'HISTORYSERVER', displayName: 'History Server'}),
  262. App.ServiceConfigCategory.create({ name: 'JOBTRACKER', displayName: 'JobTracker'}),
  263. App.ServiceConfigCategory.create({ name: 'TASKTRACKER', displayName: 'TaskTracker'}),
  264. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  265. ]);
  266. break;
  267. case 'YARN':
  268. serviceConfigCategories.pushObjects([
  269. App.ServiceConfigCategory.create({ name: 'RESOURCEMANAGER', displayName: 'Resource Manager'}),
  270. App.ServiceConfigCategory.create({ name: 'NODEMANAGER', displayName: 'Node Manager'}),
  271. App.ServiceConfigCategory.create({ name: 'APP_TIMELINE_SERVER', displayName: 'Application Timeline Server'}),
  272. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
  273. App.ServiceConfigCategory.create({ name: 'CapacityScheduler', displayName: 'Scheduler', isCustomView: true, siteFileName: 'capacity-scheduler.xml'})
  274. ]);
  275. break;
  276. case 'MAPREDUCE2':
  277. serviceConfigCategories.pushObjects([
  278. App.ServiceConfigCategory.create({ name: 'HISTORYSERVER', displayName: 'History Server'})
  279. ]);
  280. break;
  281. case 'HIVE':
  282. serviceConfigCategories.pushObjects([
  283. App.ServiceConfigCategory.create({ name: 'HIVE_METASTORE', displayName: 'Hive Metastore'})
  284. ]);
  285. break;
  286. case 'WEBHCAT':
  287. serviceConfigCategories.pushObjects([
  288. App.ServiceConfigCategory.create({ name: 'WEBHCAT_SERVER', displayName: 'WebHCat Server'})
  289. ]);
  290. break;
  291. case 'HBASE':
  292. serviceConfigCategories.pushObjects([
  293. App.ServiceConfigCategory.create({ name: 'HBASE_MASTER', displayName: 'HBase Master'}),
  294. App.ServiceConfigCategory.create({ name: 'HBASE_REGIONSERVER', displayName: 'RegionServer'}),
  295. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  296. ]);
  297. break;
  298. case 'ZOOKEEPER':
  299. serviceConfigCategories.pushObjects([
  300. App.ServiceConfigCategory.create({ name: 'ZOOKEEPER_SERVER', displayName: 'ZooKeeper Server'})
  301. ]);
  302. break;
  303. case 'OOZIE':
  304. serviceConfigCategories.pushObjects([
  305. App.ServiceConfigCategory.create({ name: 'OOZIE_SERVER', displayName: 'Oozie Server'})
  306. ]);
  307. break;
  308. case 'FALCON':
  309. serviceConfigCategories.pushObjects([
  310. App.ServiceConfigCategory.create({ name: 'FALCON_SERVER', displayName: 'Falcon Server'}),
  311. App.ServiceConfigCategory.create({ name: 'Falcon - Oozie integration', displayName: 'Falcon - Oozie integration'}),
  312. App.ServiceConfigCategory.create({ name: 'FalconStartupSite', displayName: 'Falcon startup.properties'}),
  313. App.ServiceConfigCategory.create({ name: 'FalconRuntimeSite', displayName: 'Falcon runtime.properties'}),
  314. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  315. ]);
  316. break;
  317. case 'STORM':
  318. serviceConfigCategories.pushObjects([
  319. App.ServiceConfigCategory.create({ name: 'NIMBUS', displayName: 'Nimbus'}),
  320. App.ServiceConfigCategory.create({ name: 'SUPERVISOR', displayName: 'Supervisor'}),
  321. App.ServiceConfigCategory.create({ name: 'STORM_UI_SERVER', displayName: 'Storm UI Server'}),
  322. App.ServiceConfigCategory.create({ name: 'STORM_REST_API', displayName: 'Storm REST API Server'}),
  323. App.ServiceConfigCategory.create({ name: 'DRPC_SERVER', displayName: 'DRPC Server'}),
  324. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  325. ]);
  326. break;
  327. case 'TEZ':
  328. serviceConfigCategories.pushObjects([
  329. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  330. ]);
  331. break;
  332. case 'FLUME':
  333. serviceConfigCategories.pushObjects([
  334. App.ServiceConfigCategory.create({ name: 'FLUME_HANDLER', displayName: 'flume.conf', siteFileName: 'flume-conf', canAddProperty: false})
  335. ]);
  336. break;
  337. case 'PIG':
  338. break;
  339. case 'SQOOP':
  340. break;
  341. case 'HCATALOG':
  342. break;
  343. default:
  344. serviceConfigCategories.pushObjects([
  345. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  346. ]);
  347. }
  348. serviceConfigCategories.pushObject(App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}));
  349. var configTypes = Object.keys(this.get('configTypes'));
  350. if (this.get('serviceName') !== 'HDFS') {
  351. configTypes = configTypes.without('core-site');
  352. }
  353. //Falcon has dependency on oozie-site but oozie-site advanced/custom section should not be shown on Falcon page
  354. if (this.get('serviceName') !== 'OOZIE') {
  355. configTypes = configTypes.without('oozie-site');
  356. }
  357. //Hive has dependency on tez-site but tez-site advanced/custom section should not be shown on Hive page
  358. if (this.get('serviceName') !== 'TEZ') {
  359. configTypes = configTypes.without('tez-site');
  360. }
  361. //oozie has dependency on yarn-site but yarn-site advanced/custom section should not be shown on Oozie page
  362. if (this.get('serviceName') !== 'YARN') {
  363. configTypes = configTypes.without('yarn-site');
  364. }
  365. // Add Advanced section for every configType to all the services
  366. configTypes.forEach(function (type) {
  367. var displayName = 'Advanced ' + type;
  368. var canAddProperty = false;
  369. var advancedSection;
  370. advancedSection = App.ServiceConfigCategory.create({ name: 'Advanced ' + type, displayName: displayName,
  371. canAddProperty: canAddProperty});
  372. serviceConfigCategories.pushObject(advancedSection);
  373. }, this);
  374. // Add custom section for every configType to all the services
  375. configTypes.forEach(function (type) {
  376. var displayName = 'Custom ' + type;
  377. var canAddProperty = true;
  378. var customSection;
  379. var siteFileName = type + '.xml';
  380. var configTypesWithNoCustomSection = ['capacity-scheduler','mapred-queue-acls','flume-conf', 'pig-properties'];
  381. if (type.endsWith('-env') || type.endsWith('-log4j') || configTypesWithNoCustomSection.contains(type)) {
  382. return;
  383. }
  384. customSection = App.ServiceConfigCategory.create({ name: displayName, displayName: displayName, siteFileName: siteFileName,
  385. canAddProperty: canAddProperty});
  386. serviceConfigCategories.pushObject(customSection);
  387. }, this);
  388. return serviceConfigCategories;
  389. };