| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| var App = require('app'); |
| var stringUtils = require('utils/string_utils'); |
| require('utils/helper'); |
| require('models/configs/objects/service_config_category'); |
| |
| var Dependency = Ember.Object.extend({ |
| name: Ember.computed('service', function() { |
| return this.get('service.serviceName'); |
| }), |
| |
| displayName: Ember.computed('service', function() { |
| return this.get('service.displayNameOnSelectServicePage'); |
| }), |
| |
| compatibleServices: function(services) { |
| return services.filterProperty('serviceName', this.get('name')); |
| }, |
| |
| isMissing: function(selectedServices) { |
| return Em.isEmpty(this.compatibleServices(selectedServices)); |
| } |
| }); |
| |
| var HcfsDependency = Dependency.extend({ |
| displayName: Ember.computed(function() { |
| return Em.I18n.t('installer.step4.hcfs.displayName'); |
| }), |
| |
| compatibleServices: function(services) { |
| return services.filterProperty("isDFS", true); |
| } |
| }); |
| |
| Dependency.reopenClass({ |
| fromService: function(service) { |
| return service.get('isDFS') |
| ? HcfsDependency.create({service: service}) |
| : Dependency.create({service: service}); |
| } |
| }); |
| |
| var MissingDependency = Ember.Object.extend({ |
| hasMultipleOptions: Ember.computed('compatibleServices', function() { |
| return this.get('compatibleServices').length > 1; |
| }), |
| |
| selectFirstCompatible: function() { |
| this.get('compatibleServices')[0].set('isSelected', true); |
| }, |
| |
| displayOptions: Ember.computed('compatibleServices', function() { |
| return this.get('compatibleServices').mapProperty('serviceName').join(', '); |
| }) |
| }); |
| |
| App.FileSystem = Ember.ObjectProxy.extend({ |
| content: null, |
| services: [], |
| |
| isSelected: function(key, aBoolean) { |
| if (arguments.length > 1) { |
| this.clearAllSelection(); |
| this.get('content').set('isSelected', aBoolean); |
| } |
| return this.get('content.isSelected'); |
| }.property('content.isSelected', 'services.@each.isSelected'), |
| |
| clearAllSelection: function() { |
| this.get('services').setEach('isSelected', false); |
| } |
| }); |
| |
| /** |
| * This model loads all services supported by the stack |
| * The model maps to the http://hostname:8080/api/v1/stacks/HDP/versions/${versionNumber}/services?fields=StackServices/*,serviceComponents/* |
| * @type {*} |
| */ |
| App.StackService = DS.Model.extend({ |
| serviceName: DS.attr('string'), |
| serviceType: DS.attr('string'), |
| displayName: DS.attr('string'), |
| comments: DS.attr('string'), |
| configTypes: DS.attr('object'), |
| serviceVersion: DS.attr('string'), |
| serviceCheckSupported: DS.attr('boolean'), |
| supportDeleteViaUi: DS.attr('boolean'), |
| stackName: DS.attr('string'), |
| stackVersion: DS.attr('string'), |
| selection: DS.attr('string'), |
| isMandatory: DS.attr('boolean', {defaultValue: false}), |
| isSelected: DS.attr('boolean', {defaultValue: true}), |
| isInstalled: DS.attr('boolean', {defaultValue: false}), |
| isInstallable: DS.attr('boolean', {defaultValue: true}), |
| isServiceWithWidgets: DS.attr('boolean', {defaultValue: false}), |
| stack: DS.belongsTo('App.Stack'), |
| serviceComponents: DS.hasMany('App.StackServiceComponent'), |
| configs: DS.attr('array'), |
| requiredServices: DS.attr('array', {defaultValue: []}), |
| |
| isDisabled: function () { |
| return this.get('isInstalled') || (this.get('isMandatory') && !App.get('router.clusterInstallCompleted')); |
| }.property('isMandatory', 'isInstalled', 'App.router.clusterInstallCompleted'), |
| |
| /** |
| * @type {String[]} |
| */ |
| configTypeList: function() { |
| var configTypes = Object.keys(this.get('configTypes') || {}); |
| //Falcon has dependency on oozie-site but oozie-site advanced/custom section should not be shown on Falcon page |
| if (this.get('serviceName') === 'FALCON') { |
| configTypes = configTypes.without('oozie-site'); |
| } |
| return configTypes; |
| }.property('configTypes'), |
| |
| /** |
| * contains array of serviceNames that have configs that |
| * depends on configs from current service |
| * @type {String[]} |
| */ |
| dependentServiceNames: DS.attr('array', {defaultValue: []}), |
| |
| dependencies: function(availableServices) { |
| var result = []; |
| this.get('requiredServices').forEach(function(serviceName) { |
| var service = availableServices.findProperty('serviceName', serviceName); |
| if (service) { |
| result.push(Dependency.fromService(service)); |
| } |
| }); |
| return result; |
| }, |
| |
| /** |
| * Add dependencies which are not already included in selectedServices to the given missingDependencies collection |
| */ |
| collectMissingDependencies: function(selectedServices, availableServices, missingDependencies) { |
| this._missingDependencies(selectedServices, availableServices).forEach(function (dependency) { |
| this._addMissingDependency(dependency, availableServices, missingDependencies); |
| }.bind(this)); |
| }, |
| |
| _missingDependencies: function(selectedServices, availableServices) { |
| return this.dependencies(availableServices).filter(function(dependency) { |
| return dependency.isMissing(selectedServices); |
| }); |
| }, |
| |
| _addMissingDependency: function(dependency, availableServices, missingDependencies) { |
| if(!missingDependencies.someProperty('serviceName', dependency.get('name'))) { |
| missingDependencies.push(MissingDependency.create({ |
| serviceName: dependency.get('name'), |
| displayName: dependency.get('displayName'), |
| compatibleServices: dependency.compatibleServices(availableServices) |
| })); |
| } |
| }, |
| |
| // Is the service a distributed filesystem |
| isDFS: function () { |
| return this.get('serviceType') === 'HCFS' || ['HDFS', 'GLUSTERFS'].contains(this.get('serviceName')); |
| }.property('serviceName', 'serviceType'), |
| |
| // Primary DFS. used if there is more than one DFS in a stack. |
| // Only one service in the stack should be tagged as primary DFS. |
| isPrimaryDFS: Em.computed.equal('serviceName', 'HDFS'), |
| |
| configTypesRendered: function () { |
| var configTypes = this.get('configTypes'); |
| var renderedConfigTypes = $.extend(true, {}, configTypes); |
| if (this.get('serviceName') == 'FALCON') { |
| delete renderedConfigTypes['oozie-site']; |
| } |
| return renderedConfigTypes |
| }.property('serviceName', 'configTypes'), |
| |
| displayNameOnSelectServicePage: function () { |
| var displayName = this.get('displayName'); |
| var services = this.get('coSelectedServices').slice(); |
| var serviceDisplayNames = services.map(function (item) { |
| return App.format.role(item, true); |
| }, this); |
| if (!!serviceDisplayNames.length) { |
| serviceDisplayNames.unshift(displayName); |
| displayName = serviceDisplayNames.join(" + "); |
| } |
| return displayName; |
| }.property('coSelectedServices', 'serviceName'), |
| |
| isHiddenOnSelectServicePage: function () { |
| var hiddenServices = ['MAPREDUCE2']; |
| return hiddenServices.contains(this.get('serviceName')) || !this.get('isInstallable') || this.get('doNotShowAndInstall'); |
| }.property('serviceName', 'isInstallable'), |
| |
| doNotShowAndInstall: function () { |
| var skipServices = []; |
| if(!App.supports.installGanglia) { |
| skipServices.push('GANGLIA'); |
| } |
| return skipServices.contains(this.get('serviceName')); |
| }.property('serviceName'), |
| |
| // Is the service required for monitoring of other hadoop ecosystem services |
| isMonitoringService: Em.computed.existsIn('serviceName', ['GANGLIA']), |
| |
| // Is the service required for reporting host metrics |
| isHostMetricsService: Em.computed.existsIn('serviceName', ['GANGLIA', 'AMBARI_METRICS']), |
| |
| // Is the service required for reporting hadoop service metrics |
| isServiceMetricsService: Em.computed.existsIn('serviceName', ['GANGLIA']), |
| |
| coSelectedServices: function () { |
| var coSelectedServices = App.StackService.coSelected[this.get('serviceName')]; |
| if (!!coSelectedServices) { |
| return coSelectedServices; |
| } else { |
| return []; |
| } |
| }.property('serviceName'), |
| |
| hasClient: Em.computed.someBy('serviceComponents', 'isClient', true), |
| |
| hasMaster: Em.computed.someBy('serviceComponents', 'isMaster', true), |
| |
| hasSlave: Em.computed.someBy('serviceComponents', 'isSlave', true), |
| |
| hasNonMastersWithCustomAssignment: function () { |
| var serviceComponents = this.get('serviceComponents'); |
| return serviceComponents.rejectProperty('isMaster').rejectProperty('cardinality', 'ALL').length > 0; |
| }.property('serviceName'), |
| |
| isClientOnlyService: Em.computed.everyBy('serviceComponents', 'isClient', true), |
| |
| isNoConfigTypes: function () { |
| var configTypes = this.get('configTypes'); |
| return !(configTypes && !!Object.keys(configTypes).length); |
| }.property('configTypes'), |
| |
| customReviewHandler: function () { |
| return App.StackService.reviewPageHandlers[this.get('serviceName')]; |
| }.property('serviceName'), |
| |
| hasHeatmapSection: Em.computed.existsIn('serviceName', ['HDFS', 'YARN', 'HBASE']), |
| |
| /** |
| * configCategories are fetched from App.StackService.configCategories. |
| * Also configCategories that does not match any serviceComponent of a service and not included in the permissible default pattern are omitted |
| */ |
| configCategories: function () { |
| var configCategories = []; |
| var configTypes = this.get('configTypes'); |
| var serviceComponents = this.get('serviceComponents'); |
| if (configTypes && Object.keys(configTypes).length) { |
| var pattern = ["General", "ResourceType", "CapacityScheduler", "ContainerExecutor", "Registry", "FaultTolerance", "Isolation", "Performance", "HIVE_SERVER2", "KDC", "Kadmin","^Advanced", "Env$", "^Custom", "Falcon - Oozie integration", "FalconStartupSite", "FalconRuntimeSite", "MetricCollector", "Settings$", "AdvancedHawqCheck", "LogsearchAdminJson"]; |
| configCategories = App.StackService.configCategories.call(this).filter(function (_configCategory) { |
| var serviceComponentName = _configCategory.get('name'); |
| var isServiceComponent = serviceComponents.someProperty('componentName', serviceComponentName); |
| if (isServiceComponent) return isServiceComponent; |
| var result = false; |
| pattern.forEach(function (_pattern) { |
| var regex = new RegExp(_pattern); |
| if (regex.test(serviceComponentName)) result = true; |
| }); |
| return result; |
| }); |
| } |
| return configCategories; |
| }.property('serviceName', 'configTypes', 'serviceComponents'), |
| |
| /** |
| * Compare specified version with current service version |
| * @param {string} version [description] |
| * @return {number} 0 - equal, -1 - less, +1 - more @see stringUtils#compareVersions |
| */ |
| compareCurrentVersion: function(version) { |
| var toMinor = this.get('serviceVersion').split('.').slice(0, 2).join('.'); |
| return stringUtils.compareVersions(toMinor, version); |
| } |
| }); |
| |
| App.StackService.FIXTURES = []; |
| |
| App.StackService.displayOrder = [ |
| 'HDFS', |
| 'GLUSTERFS', |
| 'YARN', |
| 'MAPREDUCE2', |
| 'TEZ', |
| 'GANGLIA', |
| 'HIVE', |
| 'HAWQ', |
| 'PXF', |
| 'HBASE', |
| 'PIG', |
| 'SQOOP', |
| 'OOZIE', |
| 'ZOOKEEPER', |
| 'FALCON', |
| 'STORM', |
| 'FLUME', |
| 'ACCUMULO', |
| 'AMBARI_INFRA_SOLR', |
| 'AMBARI_METRICS', |
| 'ATLAS', |
| 'KAFKA', |
| 'KNOX', |
| 'LOGSEARCH', |
| 'RANGER', |
| 'RANGER_KMS', |
| 'SMARTSENSE', |
| 'SPARK', |
| 'SPARK2', |
| 'ZEPPELIN' |
| ]; |
| |
| App.StackService.componentsOrderForService = { |
| 'HAWQ': ['HAWQMASTER', 'HAWQSTANDBY'] |
| }; |
| |
| //@TODO: Write unit test for no two keys in the object should have any intersecting elements in their values |
| App.StackService.coSelected = { |
| 'YARN': ['MAPREDUCE2'] |
| }; |
| |
| |
| App.StackService.reviewPageHandlers = { |
| 'HIVE': { |
| 'Database': 'loadHiveDbValue' |
| }, |
| 'OOZIE': { |
| 'Database': 'loadOozieDbValue' |
| } |
| }; |
| |
| App.StackService.configCategories = function () { |
| var serviceConfigCategories = []; |
| switch (this.get('serviceName')) { |
| case 'HDFS': |
| serviceConfigCategories.pushObject(App.ServiceConfigCategory.create({ name: 'NAMENODE', displayName: 'NameNode', showHost: true})); |
| if (!App.get('isHaEnabled')) { |
| serviceConfigCategories.pushObject(App.ServiceConfigCategory.create({ name: 'SECONDARY_NAMENODE', displayName: 'Secondary NameNode', showHost: true})); |
| } |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'DATANODE', displayName: 'DataNode', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}), |
| App.ServiceConfigCategory.create({ name: 'NFS_GATEWAY', displayName: 'NFS Gateway', showHost: true}) |
| ]); |
| break; |
| case 'GLUSTERFS': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}) |
| ]); |
| break; |
| case 'YARN': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'RESOURCEMANAGER', displayName: 'Resource Manager', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'NODEMANAGER', displayName: 'Node Manager', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'APP_TIMELINE_SERVER', displayName: 'Application Timeline Server', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}), |
| App.ServiceConfigCategory.create({ name: 'ResourceTypes', displayName: 'Resource Types'}), |
| App.ServiceConfigCategory.create({ name: 'FaultTolerance', displayName: 'Fault Tolerance'}), |
| App.ServiceConfigCategory.create({ name: 'Isolation', displayName: 'Isolation'}), |
| App.ServiceConfigCategory.create({ name: 'CapacityScheduler', displayName: 'Scheduler', siteFileName: 'capacity-scheduler.xml'}), |
| App.ServiceConfigCategory.create({ name: 'ContainerExecutor', displayName: 'Container Executor', siteFileName: 'container-executor.xml'}), |
| App.ServiceConfigCategory.create({ name: 'Registry', displayName: 'Registry'}) |
| ]); |
| break; |
| case 'MAPREDUCE2': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'HISTORYSERVER', displayName: 'History Server', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}) |
| ]); |
| break; |
| case 'HIVE': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'HIVE_METASTORE', displayName: 'Hive Metastore', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'WEBHCAT_SERVER', displayName: 'WebHCat Server', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}), |
| App.ServiceConfigCategory.create({ name: 'Performance', displayName: 'Performance'}), |
| App.ServiceConfigCategory.create({ name: 'HIVE_SERVER2', displayName: 'Hive Server2'}), |
| App.ServiceConfigCategory.create({ name: 'HIVE_CLIENT', displayName: 'Hive Client'}) |
| ]); |
| break; |
| case 'HBASE': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'HBASE_MASTER', displayName: 'HBase Master', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'HBASE_REGIONSERVER', displayName: 'RegionServer', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}) |
| ]); |
| break; |
| case 'ZOOKEEPER': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'ZOOKEEPER_SERVER', displayName: 'ZooKeeper Server', showHost: true}) |
| ]); |
| break; |
| case 'OOZIE': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'OOZIE_SERVER', displayName: 'Oozie Server', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'Falcon - Oozie integration', displayName: 'Falcon - Oozie integration'}) |
| ]); |
| break; |
| case 'FALCON': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'FALCON_SERVER', displayName: 'Falcon Server', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'Falcon - Oozie integration', displayName: 'Falcon - Oozie integration'}), |
| App.ServiceConfigCategory.create({ name: 'FalconStartupSite', displayName: 'Falcon startup.properties'}), |
| App.ServiceConfigCategory.create({ name: 'FalconRuntimeSite', displayName: 'Falcon runtime.properties'}), |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}) |
| ]); |
| break; |
| case 'STORM': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'NIMBUS', displayName: 'Nimbus', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'SUPERVISOR', displayName: 'Supervisor', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'STORM_UI_SERVER', displayName: 'Storm UI Server', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'STORM_REST_API', displayName: 'Storm REST API Server', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'DRPC_SERVER', displayName: 'DRPC Server', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}) |
| ]); |
| break; |
| case 'TEZ': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}) |
| ]); |
| break; |
| case 'FLUME': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'FLUME_HANDLER', displayName: 'flume.conf', siteFileName: 'flume-conf', canAddProperty: false}) |
| ]); |
| break; |
| case 'KNOX': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'KNOX_GATEWAY', displayName: 'Knox Gateway', showHost: true}) |
| ]); |
| break; |
| case 'KAFKA': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'KAFKA_BROKER', displayName: 'Kafka Broker', showHost: true}) |
| ]); |
| break; |
| case 'KERBEROS': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'KDC', displayName: 'KDC'}), |
| App.ServiceConfigCategory.create({ name: 'Kadmin', displayName: 'Kadmin'}), |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}) |
| ]); |
| break; |
| case 'AMBARI_METRICS': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}), |
| App.ServiceConfigCategory.create({ name: 'MetricCollector', displayName: 'Metric Collector'}) |
| ]); |
| break; |
| case 'RANGER': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'RANGER_ADMIN', displayName: 'Admin Settings', showHost: true}), |
| App.ServiceConfigCategory.create({ name: 'DBSettings', displayName: 'DB Settings'}), |
| App.ServiceConfigCategory.create({ name: 'RangerSettings', displayName: 'Ranger Settings'}), |
| App.ServiceConfigCategory.create({ name: 'UnixAuthenticationSettings', displayName: 'Unix Authentication Settings'}), |
| App.ServiceConfigCategory.create({ name: 'ADSettings', displayName: 'AD Settings'}), |
| App.ServiceConfigCategory.create({ name: 'LDAPSettings', displayName: 'LDAP Settings'}), |
| App.ServiceConfigCategory.create({ name: 'KnoxSSOSettings', displayName: 'Knox SSO Settings'}) |
| ]); |
| break; |
| case 'ACCUMULO': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}) |
| ]); |
| break; |
| case 'PIG': |
| break; |
| case 'SQOOP': |
| break; |
| case 'HAWQ': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}), |
| App.ServiceConfigCategory.create({ name: 'AdvancedHawqCheck', displayName: 'Advanced HAWQ Check'}) |
| ]); |
| break; |
| case 'LOGSEARCH': |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'LogsearchAdminJson', displayName: 'Advanced logsearch-admin-json'}) |
| ]); |
| break; |
| default: |
| serviceConfigCategories.pushObjects([ |
| App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}) |
| ]); |
| } |
| serviceConfigCategories.pushObject(App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'})); |
| |
| var configTypes = this.get('configTypeList'); |
| |
| // Add Advanced section for every configType to all the services |
| configTypes.forEach(function (type) { |
| serviceConfigCategories.pushObject(App.ServiceConfigCategory.create({ |
| name: 'Advanced ' + type, |
| displayName: Em.I18n.t('common.advanced') + " " + type, |
| canAddProperty: false |
| })); |
| }, this); |
| |
| // Add custom section for every configType to all the services |
| configTypes.forEach(function (type) { |
| if (Em.getWithDefault(this.get('configTypes')[type] || {}, 'supports.adding_forbidden', 'true') === 'false') { |
| serviceConfigCategories.pushObject(App.ServiceConfigCategory.create({ |
| name: 'Custom ' + type, |
| displayName: Em.I18n.t('common.custom') + " " + type, |
| siteFileName: type + '.xml', |
| canAddProperty: true |
| })); |
| } |
| }, this); |
| return serviceConfigCategories; |
| }; |