stack_service.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  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('models/configs/objects/service_config_category');
  21. /**
  22. * This model loads all services supported by the stack
  23. * The model maps to the http://hostname:8080/api/v1/stacks/HDP/versions/${versionNumber}/services?fields=StackServices/*,serviceComponents/*
  24. * @type {*}
  25. */
  26. App.StackService = DS.Model.extend({
  27. serviceName: DS.attr('string'),
  28. serviceType: DS.attr('string'),
  29. displayName: DS.attr('string'),
  30. comments: DS.attr('string'),
  31. configTypes: DS.attr('object'),
  32. serviceVersion: DS.attr('string'),
  33. serviceCheckSupported: DS.attr('boolean'),
  34. stackName: DS.attr('string'),
  35. stackVersion: DS.attr('string'),
  36. selection: DS.attr('string'),
  37. isMandatory: DS.attr('boolean', {defaultValue: false}),
  38. isSelected: DS.attr('boolean', {defaultValue: true}),
  39. isInstalled: DS.attr('boolean', {defaultValue: false}),
  40. isInstallable: DS.attr('boolean', {defaultValue: true}),
  41. isServiceWithWidgets: DS.attr('boolean', {defaultValue: false}),
  42. stack: DS.belongsTo('App.Stack'),
  43. serviceComponents: DS.hasMany('App.StackServiceComponent'),
  44. configs: DS.attr('array'),
  45. requiredServices: DS.attr('array', {defaultValue: []}),
  46. isDisabled: Em.computed.or('isMandatory', 'isInstalled'),
  47. /**
  48. * @type {String[]}
  49. */
  50. configTypeList: function() {
  51. var configTypes = Object.keys(this.get('configTypes') || {});
  52. //Falcon has dependency on oozie-site but oozie-site advanced/custom section should not be shown on Falcon page
  53. if (this.get('serviceName') === 'FALCON') {
  54. configTypes = configTypes.without('oozie-site');
  55. }
  56. return configTypes;
  57. }.property('configTypes'),
  58. /**
  59. * contains array of serviceNames that have configs that
  60. * depends on configs from current service
  61. * @type {String[]}
  62. */
  63. dependentServiceNames: DS.attr('array', {defaultValue: []}),
  64. // Is the service a distributed filesystem
  65. isDFS: function () {
  66. return this.get('serviceType') === 'HCFS' || ['HDFS', 'GLUSTERFS'].contains(this.get('serviceName'));
  67. }.property('serviceName', 'serviceType'),
  68. // Primary DFS. used if there is more than one DFS in a stack.
  69. // Only one service in the stack should be tagged as primary DFS.
  70. isPrimaryDFS: Em.computed.equal('serviceName', 'HDFS'),
  71. configTypesRendered: function () {
  72. var configTypes = this.get('configTypes');
  73. var renderedConfigTypes = $.extend(true, {}, configTypes);
  74. if (this.get('serviceName') == 'FALCON') {
  75. delete renderedConfigTypes['oozie-site'];
  76. }
  77. return renderedConfigTypes
  78. }.property('serviceName', 'configTypes'),
  79. displayNameOnSelectServicePage: function () {
  80. var displayName = this.get('displayName');
  81. var services = this.get('coSelectedServices').slice();
  82. var serviceDisplayNames = services.map(function (item) {
  83. return App.format.role(item, true);
  84. }, this);
  85. if (!!serviceDisplayNames.length) {
  86. serviceDisplayNames.unshift(displayName);
  87. displayName = serviceDisplayNames.join(" + ");
  88. }
  89. return displayName;
  90. }.property('coSelectedServices', 'serviceName'),
  91. isHiddenOnSelectServicePage: function () {
  92. var hiddenServices = ['MAPREDUCE2'];
  93. return hiddenServices.contains(this.get('serviceName')) || !this.get('isInstallable') || this.get('doNotShowAndInstall');
  94. }.property('serviceName', 'isInstallable'),
  95. doNotShowAndInstall: function () {
  96. var skipServices = [];
  97. if(!App.supports.installGanglia) {
  98. skipServices.push('GANGLIA');
  99. }
  100. if(App.router.get('clusterInstallCompleted') != true){
  101. skipServices.push('RANGER', 'RANGER_KMS');
  102. }
  103. return skipServices.contains(this.get('serviceName'));
  104. }.property('serviceName'),
  105. // Is the service required for monitoring of other hadoop ecosystem services
  106. isMonitoringService: Em.computed.existsIn('serviceName', ['GANGLIA']),
  107. // Is the service required for reporting host metrics
  108. isHostMetricsService: Em.computed.existsIn('serviceName', ['GANGLIA', 'AMBARI_METRICS']),
  109. // Is the service required for reporting hadoop service metrics
  110. isServiceMetricsService: Em.computed.existsIn('serviceName', ['GANGLIA']),
  111. coSelectedServices: function () {
  112. var coSelectedServices = App.StackService.coSelected[this.get('serviceName')];
  113. if (!!coSelectedServices) {
  114. return coSelectedServices;
  115. } else {
  116. return [];
  117. }
  118. }.property('serviceName'),
  119. hasClient: Em.computed.someBy('serviceComponents', 'isClient', true),
  120. hasMaster: Em.computed.someBy('serviceComponents', 'isMaster', true),
  121. hasSlave: Em.computed.someBy('serviceComponents', 'isSlave', true),
  122. hasNonMastersWithCustomAssignment: function () {
  123. var serviceComponents = this.get('serviceComponents');
  124. return serviceComponents.rejectProperty('isMaster').rejectProperty('cardinality', 'ALL').length > 0;
  125. }.property('serviceName'),
  126. isClientOnlyService: Em.computed.everyBy('serviceComponents', 'isClient', true),
  127. isNoConfigTypes: function () {
  128. var configTypes = this.get('configTypes');
  129. return !(configTypes && !!Object.keys(configTypes).length);
  130. }.property('configTypes'),
  131. customReviewHandler: function () {
  132. return App.StackService.reviewPageHandlers[this.get('serviceName')];
  133. }.property('serviceName'),
  134. hasHeatmapSection: Em.computed.existsIn('serviceName', ['HDFS', 'YARN', 'HBASE']),
  135. /**
  136. * configCategories are fetched from App.StackService.configCategories.
  137. * Also configCategories that does not match any serviceComponent of a service and not included in the permissible default pattern are omitted
  138. */
  139. configCategories: function () {
  140. var configCategories = [];
  141. var configTypes = this.get('configTypes');
  142. var serviceComponents = this.get('serviceComponents');
  143. if (configTypes && Object.keys(configTypes).length) {
  144. var pattern = ["General", "CapacityScheduler", "FaultTolerance", "Isolation", "Performance", "HIVE_SERVER2", "KDC", "Kadmin","^Advanced", "Env$", "^Custom", "Falcon - Oozie integration", "FalconStartupSite", "FalconRuntimeSite", "MetricCollector", "Settings$", "AdvancedHawqCheck", "LogsearchAdminJson"];
  145. configCategories = App.StackService.configCategories.call(this).filter(function (_configCategory) {
  146. var serviceComponentName = _configCategory.get('name');
  147. var isServiceComponent = serviceComponents.someProperty('componentName', serviceComponentName);
  148. if (isServiceComponent) return isServiceComponent;
  149. var result = false;
  150. pattern.forEach(function (_pattern) {
  151. var regex = new RegExp(_pattern);
  152. if (regex.test(serviceComponentName)) result = true;
  153. });
  154. return result;
  155. });
  156. }
  157. return configCategories;
  158. }.property('serviceName', 'configTypes', 'serviceComponents')
  159. });
  160. App.StackService.FIXTURES = [];
  161. App.StackService.displayOrder = [
  162. 'HDFS',
  163. 'GLUSTERFS',
  164. 'YARN',
  165. 'MAPREDUCE2',
  166. 'TEZ',
  167. 'GANGLIA',
  168. 'HIVE',
  169. 'HAWQ',
  170. 'PXF',
  171. 'HBASE',
  172. 'PIG',
  173. 'SQOOP',
  174. 'OOZIE',
  175. 'ZOOKEEPER',
  176. 'FALCON',
  177. 'STORM',
  178. 'FLUME',
  179. 'ACCUMULO',
  180. 'AMBARI_INFRA',
  181. 'AMBARI_METRICS',
  182. 'ATLAS',
  183. 'KAFKA',
  184. 'KNOX',
  185. 'LOGSEARCH',
  186. 'RANGER',
  187. 'RANGER_KMS',
  188. 'SMARTSENSE',
  189. 'SPARK',
  190. 'SPARK2',
  191. 'ZEPPELIN'
  192. ];
  193. App.StackService.componentsOrderForService = {
  194. 'HAWQ': ['HAWQMASTER', 'HAWQSTANDBY']
  195. };
  196. //@TODO: Write unit test for no two keys in the object should have any intersecting elements in their values
  197. App.StackService.coSelected = {
  198. 'YARN': ['MAPREDUCE2']
  199. };
  200. App.StackService.reviewPageHandlers = {
  201. 'HIVE': {
  202. 'Database': 'loadHiveDbValue'
  203. },
  204. 'OOZIE': {
  205. 'Database': 'loadOozieDbValue'
  206. }
  207. };
  208. App.StackService.configCategories = function () {
  209. var serviceConfigCategories = [];
  210. switch (this.get('serviceName')) {
  211. case 'HDFS':
  212. serviceConfigCategories.pushObject(App.ServiceConfigCategory.create({ name: 'NAMENODE', displayName: 'NameNode', showHost: true}));
  213. if (!App.get('isHaEnabled')) {
  214. serviceConfigCategories.pushObject(App.ServiceConfigCategory.create({ name: 'SECONDARY_NAMENODE', displayName: 'Secondary NameNode', showHost: true}));
  215. }
  216. serviceConfigCategories.pushObjects([
  217. App.ServiceConfigCategory.create({ name: 'DATANODE', displayName: 'DataNode', showHost: true}),
  218. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
  219. App.ServiceConfigCategory.create({ name: 'NFS_GATEWAY', displayName: 'NFS Gateway', showHost: true})
  220. ]);
  221. break;
  222. case 'GLUSTERFS':
  223. serviceConfigCategories.pushObjects([
  224. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  225. ]);
  226. break;
  227. case 'YARN':
  228. serviceConfigCategories.pushObjects([
  229. App.ServiceConfigCategory.create({ name: 'RESOURCEMANAGER', displayName: 'Resource Manager', showHost: true}),
  230. App.ServiceConfigCategory.create({ name: 'NODEMANAGER', displayName: 'Node Manager', showHost: true}),
  231. App.ServiceConfigCategory.create({ name: 'APP_TIMELINE_SERVER', displayName: 'Application Timeline Server', showHost: true}),
  232. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
  233. App.ServiceConfigCategory.create({ name: 'FaultTolerance', displayName: 'Fault Tolerance'}),
  234. App.ServiceConfigCategory.create({ name: 'Isolation', displayName: 'Isolation'}),
  235. App.ServiceConfigCategory.create({ name: 'CapacityScheduler', displayName: 'Scheduler', siteFileName: 'capacity-scheduler.xml'})
  236. ]);
  237. break;
  238. case 'MAPREDUCE2':
  239. serviceConfigCategories.pushObjects([
  240. App.ServiceConfigCategory.create({ name: 'HISTORYSERVER', displayName: 'History Server', showHost: true}),
  241. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  242. ]);
  243. break;
  244. case 'HIVE':
  245. serviceConfigCategories.pushObjects([
  246. App.ServiceConfigCategory.create({ name: 'HIVE_METASTORE', displayName: 'Hive Metastore', showHost: true}),
  247. App.ServiceConfigCategory.create({ name: 'WEBHCAT_SERVER', displayName: 'WebHCat Server', showHost: true}),
  248. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
  249. App.ServiceConfigCategory.create({ name: 'Performance', displayName: 'Performance'}),
  250. App.ServiceConfigCategory.create({ name: 'HIVE_SERVER2', displayName: 'Hive Server2'}),
  251. App.ServiceConfigCategory.create({ name: 'HIVE_CLIENT', displayName: 'Hive Client'})
  252. ]);
  253. break;
  254. case 'HBASE':
  255. serviceConfigCategories.pushObjects([
  256. App.ServiceConfigCategory.create({ name: 'HBASE_MASTER', displayName: 'HBase Master', showHost: true}),
  257. App.ServiceConfigCategory.create({ name: 'HBASE_REGIONSERVER', displayName: 'RegionServer', showHost: true}),
  258. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  259. ]);
  260. break;
  261. case 'ZOOKEEPER':
  262. serviceConfigCategories.pushObjects([
  263. App.ServiceConfigCategory.create({ name: 'ZOOKEEPER_SERVER', displayName: 'ZooKeeper Server', showHost: true})
  264. ]);
  265. break;
  266. case 'OOZIE':
  267. serviceConfigCategories.pushObjects([
  268. App.ServiceConfigCategory.create({ name: 'OOZIE_SERVER', displayName: 'Oozie Server', showHost: true}),
  269. App.ServiceConfigCategory.create({ name: 'Falcon - Oozie integration', displayName: 'Falcon - Oozie integration'})
  270. ]);
  271. break;
  272. case 'FALCON':
  273. serviceConfigCategories.pushObjects([
  274. App.ServiceConfigCategory.create({ name: 'FALCON_SERVER', displayName: 'Falcon Server', showHost: true}),
  275. App.ServiceConfigCategory.create({ name: 'Falcon - Oozie integration', displayName: 'Falcon - Oozie integration'}),
  276. App.ServiceConfigCategory.create({ name: 'FalconStartupSite', displayName: 'Falcon startup.properties'}),
  277. App.ServiceConfigCategory.create({ name: 'FalconRuntimeSite', displayName: 'Falcon runtime.properties'}),
  278. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  279. ]);
  280. break;
  281. case 'STORM':
  282. serviceConfigCategories.pushObjects([
  283. App.ServiceConfigCategory.create({ name: 'NIMBUS', displayName: 'Nimbus', showHost: true}),
  284. App.ServiceConfigCategory.create({ name: 'SUPERVISOR', displayName: 'Supervisor', showHost: true}),
  285. App.ServiceConfigCategory.create({ name: 'STORM_UI_SERVER', displayName: 'Storm UI Server', showHost: true}),
  286. App.ServiceConfigCategory.create({ name: 'STORM_REST_API', displayName: 'Storm REST API Server', showHost: true}),
  287. App.ServiceConfigCategory.create({ name: 'DRPC_SERVER', displayName: 'DRPC Server', showHost: true}),
  288. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  289. ]);
  290. break;
  291. case 'TEZ':
  292. serviceConfigCategories.pushObjects([
  293. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  294. ]);
  295. break;
  296. case 'FLUME':
  297. serviceConfigCategories.pushObjects([
  298. App.ServiceConfigCategory.create({ name: 'FLUME_HANDLER', displayName: 'flume.conf', siteFileName: 'flume-conf', canAddProperty: false})
  299. ]);
  300. break;
  301. case 'KNOX':
  302. serviceConfigCategories.pushObjects([
  303. App.ServiceConfigCategory.create({ name: 'KNOX_GATEWAY', displayName: 'Knox Gateway', showHost: true})
  304. ]);
  305. break;
  306. case 'KAFKA':
  307. serviceConfigCategories.pushObjects([
  308. App.ServiceConfigCategory.create({ name: 'KAFKA_BROKER', displayName: 'Kafka Broker', showHost: true})
  309. ]);
  310. break;
  311. case 'KERBEROS':
  312. serviceConfigCategories.pushObjects([
  313. App.ServiceConfigCategory.create({ name: 'KDC', displayName: 'KDC'}),
  314. App.ServiceConfigCategory.create({ name: 'Kadmin', displayName: 'Kadmin'}),
  315. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  316. ]);
  317. break;
  318. case 'AMBARI_METRICS':
  319. serviceConfigCategories.pushObjects([
  320. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
  321. App.ServiceConfigCategory.create({ name: 'MetricCollector', displayName: 'Metric Collector'})
  322. ]);
  323. break;
  324. case 'RANGER':
  325. serviceConfigCategories.pushObjects([
  326. App.ServiceConfigCategory.create({ name: 'RANGER_ADMIN', displayName: 'Admin Settings', showHost: true}),
  327. App.ServiceConfigCategory.create({ name: 'DBSettings', displayName: 'DB Settings'}),
  328. App.ServiceConfigCategory.create({ name: 'RangerSettings', displayName: 'Ranger Settings'}),
  329. App.ServiceConfigCategory.create({ name: 'UnixAuthenticationSettings', displayName: 'Unix Authentication Settings'}),
  330. App.ServiceConfigCategory.create({ name: 'ADSettings', displayName: 'AD Settings'}),
  331. App.ServiceConfigCategory.create({ name: 'LDAPSettings', displayName: 'LDAP Settings'}),
  332. App.ServiceConfigCategory.create({ name: 'KnoxSSOSettings', displayName: 'Knox SSO Settings'}),
  333. App.ServiceConfigCategory.create({ name: 'SolrKerberosSettings', displayName: 'Solr Kerberos Settings'})
  334. ]);
  335. break;
  336. case 'ACCUMULO':
  337. serviceConfigCategories.pushObjects([
  338. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  339. ]);
  340. break;
  341. case 'PIG':
  342. break;
  343. case 'SQOOP':
  344. break;
  345. case 'HAWQ':
  346. serviceConfigCategories.pushObjects([
  347. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
  348. App.ServiceConfigCategory.create({ name: 'AdvancedHawqCheck', displayName: 'Advanced HAWQ Check'})
  349. ]);
  350. break;
  351. case 'LOGSEARCH':
  352. serviceConfigCategories.pushObjects([
  353. App.ServiceConfigCategory.create({ name: 'LogsearchAdminJson', displayName: 'Advanced logsearch-admin-json'})
  354. ]);
  355. break;
  356. default:
  357. serviceConfigCategories.pushObjects([
  358. App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'})
  359. ]);
  360. }
  361. serviceConfigCategories.pushObject(App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}));
  362. var configTypes = this.get('configTypeList');
  363. // Add Advanced section for every configType to all the services
  364. configTypes.forEach(function (type) {
  365. serviceConfigCategories.pushObject(App.ServiceConfigCategory.create({
  366. name: 'Advanced ' + type,
  367. displayName: Em.I18n.t('common.advanced') + " " + type,
  368. canAddProperty: false
  369. }));
  370. }, this);
  371. // Add custom section for every configType to all the services
  372. configTypes.forEach(function (type) {
  373. if (Em.getWithDefault(this.get('configTypes')[type] || {}, 'supports.adding_forbidden', 'true') === 'false') {
  374. serviceConfigCategories.pushObject(App.ServiceConfigCategory.create({
  375. name: 'Custom ' + type,
  376. displayName: Em.I18n.t('common.custom') + " " + type,
  377. siteFileName: type + '.xml',
  378. canAddProperty: true
  379. }));
  380. }
  381. }, this);
  382. return serviceConfigCategories;
  383. };