http://git-wip-us.apache.org/repos/asf/ambari/blob/11a09c57/ambari-web/app/utils/configs/config_property_helper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/configs/config_property_helper.js b/ambari-web/app/utils/configs/config_property_helper.js new file mode 100644 index 0000000..76b294f --- /dev/null +++ b/ambari-web/app/utils/configs/config_property_helper.js @@ -0,0 +1,554 @@ +/** + * 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'); + +module.exports = { + + initialValue: function (configProperty, localDB, dependencies) { + var masterComponentHostsInDB = localDB.masterComponentHosts; + var slaveComponentHostsInDB = localDB.slaveComponentHosts; + var isOnlyFirstOneNeeded = true; + var hostWithPort = "([\\w|\\.]*)(?=:)"; + var hostWithPrefix = ":\/\/" + hostWithPort; + switch (configProperty.get('name')) { + case 'namenode_host': + configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'NAMENODE').mapProperty('hostName')); + break; + case 'dfs.namenode.rpc-address': + case 'dfs.http.address': + case 'dfs.namenode.http-address': + case 'dfs.https.address': + case 'dfs.namenode.https-address': + var nnHost = masterComponentHostsInDB.findProperty('component', 'NAMENODE').hostName; + this.setDefaultValue(configProperty, hostWithPort,nnHost); + break; + case 'fs.default.name': + case 'fs.defaultFS': + case 'hbase.rootdir': + case 'instance.volumes': + var nnHost = masterComponentHostsInDB.filterProperty('component', 'NAMENODE').mapProperty('hostName'); + this.setDefaultValue(configProperty, hostWithPrefix,'://' + nnHost); + break; + case 'snamenode_host': + // Secondary NameNode does not exist when NameNode HA is enabled + var snn = masterComponentHostsInDB.findProperty('component', 'SECONDARY_NAMENODE'); + if (snn) { + configProperty.set('value', snn.hostName); + } + break; + case 'dfs.secondary.http.address': + case 'dfs.namenode.secondary.http-address': + var snnHost = masterComponentHostsInDB.findProperty('component', 'SECONDARY_NAMENODE'); + if (snnHost) { + this.setDefaultValue(configProperty, hostWithPort,snnHost.hostName); + } + break; + case 'datanode_hosts': + configProperty.set('value', slaveComponentHostsInDB.findProperty('componentName', 'DATANODE').hosts.mapProperty('hostName')); + break; + case 'nfsgateway_hosts': + var gwyHost = slaveComponentHostsInDB.findProperty('componentName', 'NFS_GATEWAY'); + if(gwyHost) { + configProperty.set('value', gwyHost.hosts.mapProperty('hostName')); + } + break; + case 'hs_host': + configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'HISTORYSERVER').mapProperty('hostName')); + break; + case 'yarn.log.server.url': + var hsHost = masterComponentHostsInDB.filterProperty('component', 'HISTORYSERVER').mapProperty('hostName'); + this.setDefaultValue(configProperty, hostWithPrefix,'://' + hsHost); + break; + case 'mapreduce.jobhistory.webapp.address': + case 'mapreduce.jobhistory.address': + var hsHost = masterComponentHostsInDB.filterProperty('component', 'HISTORYSERVER').mapProperty('hostName'); + this.setDefaultValue(configProperty, hostWithPort,hsHost); + break; + case 'rm_host': + configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'RESOURCEMANAGER').hostName); + break; + case 'ats_host': + var atsHost = masterComponentHostsInDB.findProperty('component', 'APP_TIMELINE_SERVER'); + if (atsHost) + configProperty.set('value', atsHost.hostName); + else + configProperty.set('value', 'false'); + break; + case 'yarn.resourcemanager.hostname': + var rmHost = masterComponentHostsInDB.findProperty('component', 'RESOURCEMANAGER').hostName; + configProperty.set('defaultValue',rmHost); + configProperty.set('value',configProperty.get('defaultValue')); + break; + case 'yarn.resourcemanager.resource-tracker.address': + case 'yarn.resourcemanager.webapp.https.address': + case 'yarn.resourcemanager.webapp.address': + case 'yarn.resourcemanager.scheduler.address': + case 'yarn.resourcemanager.address': + case 'yarn.resourcemanager.admin.address': + var rmHost = masterComponentHostsInDB.findProperty('component', 'RESOURCEMANAGER').hostName; + this.setDefaultValue(configProperty, hostWithPort,rmHost); + break; + case 'yarn.timeline-service.webapp.address': + case 'yarn.timeline-service.webapp.https.address': + case 'yarn.timeline-service.address': + var atsHost = masterComponentHostsInDB.findProperty('component', 'APP_TIMELINE_SERVER'); + if (atsHost && atsHost.hostName) { + this.setDefaultValue(configProperty, hostWithPort,atsHost.hostName); + } + break; + case 'nm_hosts': + configProperty.set('value', slaveComponentHostsInDB.findProperty('componentName', 'NODEMANAGER').hosts.mapProperty('hostName')); + break; + case 'jobtracker_host': + configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'JOBTRACKER').hostName); + break; + case 'mapred.job.tracker': + case 'mapred.job.tracker.http.address': + var jtHost = masterComponentHostsInDB.findProperty('component', 'JOBTRACKER').hostName; + this.setDefaultValue(configProperty, hostWithPort,jtHost); + break; + case 'mapreduce.history.server.http.address': + var jtHost = masterComponentHostsInDB.findProperty('component', 'HISTORYSERVER').hostName; + this.setDefaultValue(configProperty, hostWithPort,jtHost); + break; + case 'tasktracker_hosts': + configProperty.set('value', slaveComponentHostsInDB.findProperty('componentName', 'TASKTRACKER').hosts.mapProperty('hostName')); + break; + case 'hbasemaster_host': + configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'HBASE_MASTER').mapProperty('hostName')); + break; + case 'regionserver_hosts': + configProperty.set('value', slaveComponentHostsInDB.findProperty('componentName', 'HBASE_REGIONSERVER').hosts.mapProperty('hostName')); + break; + case 'hivemetastore_host': + configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'HIVE_METASTORE').mapProperty('hostName')); + break; + case 'hive_ambari_host': + configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'HIVE_SERVER').hostName); + break; + case 'hive_master_hosts': + var hostNames = masterComponentHostsInDB.filter(function (masterComponent) { + return ['HIVE_METASTORE', 'HIVE_SERVER'].contains(masterComponent.component); + }); + configProperty.set('value', hostNames.mapProperty('hostName').uniq().join(',')); + break; + case 'hive_database': + var newMySQLDBOption = configProperty.get('options').findProperty('displayName', 'New MySQL Database'); + if (newMySQLDBOption) { + var isNewMySQLDBOptionHidden = !App.get('supports.alwaysEnableManagedMySQLForHive') && App.get('router.currentState.name') != 'configs' && + !App.get('isManagedMySQLForHiveEnabled'); + if (isNewMySQLDBOptionHidden && configProperty.get('value') == 'New MySQL Database') { + configProperty.set('value', 'Existing MySQL Database'); + } + Em.set(newMySQLDBOption, 'hidden', isNewMySQLDBOptionHidden); + } + break; + case 'oozieserver_host': + configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'OOZIE_SERVER').mapProperty('hostName')); + break; + case 'oozie.base.url': + var oozieHost = masterComponentHostsInDB.findProperty('component', 'OOZIE_SERVER').hostName; + this.setDefaultValue(configProperty, hostWithPrefix,'://' + oozieHost); + break; + case 'webhcatserver_host': + configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'WEBHCAT_SERVER').hostName); + break; + case 'oozie_ambari_host': + configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'OOZIE_SERVER').hostName); + break; + case 'hadoop_host': + configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'NAMENODE').mapProperty('hostName')); + break; + case 'hive_existing_mysql_host': + case 'hive_existing_postgresql_host': + case 'hive_existing_oracle_host': + case 'hive_existing_mssql_server_host': + case 'hive_existing_mssql_server_2_host': + var hiveServerHost = masterComponentHostsInDB.findProperty('component', 'HIVE_SERVER').hostName; + configProperty.set('value', hiveServerHost).set('defaultValue', hiveServerHost); + break; + case 'hive.metastore.uris': + var hiveMSUris = this.getHiveMetastoreUris(masterComponentHostsInDB, dependencies['hive.metastore.uris']); + if (hiveMSUris) { + this.setDefaultValue(configProperty, "(.*)", hiveMSUris); + } + break; + case 'oozie_existing_mysql_host': + case 'oozie_existing_postgresql_host': + case 'oozie_existing_oracle_host': + case 'oozie_existing_mssql_server_host': + case 'oozie_existing_mssql_server_2_host': + var oozieServerHost = masterComponentHostsInDB.findProperty('component', 'OOZIE_SERVER').hostName; + configProperty.set('value', oozieServerHost).set('defaultValue', oozieServerHost); + break; + case 'storm.zookeeper.servers': + case 'zookeeperserver_hosts': + configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName')); + break; + case 'nimbus.host': + configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'NIMBUS').hostName); + break; + case 'falconserver_host': + configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'FALCON_SERVER').hostName); + break; + case 'drpcserver_host': + var drpcHost = masterComponentHostsInDB.findProperty('component', 'DRPC_SERVER'); + if (drpcHost) { + configProperty.set('value', drpcHost.hostName); + } + break; + case 'stormuiserver_host': + configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'STORM_UI_SERVER').hostName); + break; + case 'storm_rest_api_host': + var stormRresApiHost = masterComponentHostsInDB.findProperty('component', 'STORM_REST_API'); + if(stormRresApiHost) { + configProperty.set('value', stormRresApiHost.hostName); + } + break; + case 'supervisor_hosts': + configProperty.set('value', slaveComponentHostsInDB.findProperty('componentName', 'SUPERVISOR').hosts.mapProperty('hostName')); + break; + case 'knox_gateway_host': + configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'KNOX_GATEWAY').mapProperty('hostName')); + break; + case 'kafka_broker_hosts': + configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'KAFKA_BROKER').mapProperty('hostName')); + break; + case 'kafka.ganglia.metrics.host': + var gangliaHost = masterComponentHostsInDB.findProperty('component', 'GANGLIA_SERVER'); + if (gangliaHost) { + configProperty.set('value', gangliaHost.hostName); + } + break; + case 'hbase.zookeeper.quorum': + if (configProperty.get('filename') == 'hbase-site.xml') { + var zkHosts = masterComponentHostsInDB.filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName'); + this.setDefaultValue(configProperty, "(\\w*)", zkHosts); + } + break; + case 'yarn.resourcemanager.zk-address': + var value = masterComponentHostsInDB.findProperty('component', 'ZOOKEEPER_SERVER').hostName + ':' + dependencies.clientPort; + configProperty.setProperties({ + value: value, + defaultValue: value + }); + break; + case 'zookeeper.connect': + case 'hive.zookeeper.quorum': + case 'templeton.zookeeper.hosts': + case 'hadoop.registry.zk.quorum': + case 'hive.cluster.delegation.token.store.zookeeper.connectString': + case 'instance.zookeeper.host': // for accumulo + var zkHosts = masterComponentHostsInDB.filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName'); + var zkHostPort = zkHosts; + var regex = "\\w*:(\\d+)"; //regex to fetch the port + var portValue = configProperty.get('defaultValue').match(new RegExp(regex)); + if (!portValue) return; + if (portValue[1]) { + for ( var i = 0; i < zkHosts.length; i++ ) { + zkHostPort[i] = zkHosts[i] + ":" + portValue[1]; + } + } + this.setDefaultValue(configProperty, "(.*)", zkHostPort); + break; + case 'templeton.hive.properties': + var hiveMSUris = this.getHiveMetastoreUris(masterComponentHostsInDB, dependencies['hive.metastore.uris']).replace(',', '\\,'); + if (/\/\/localhost:/g.test(configProperty.get('value'))) { + configProperty.set('defaultValue', configProperty.get('value') + ',hive.metastore.execute.setugi=true'); + } + this.setDefaultValue(configProperty, "(hive\\.metastore\\.uris=)([^\\,]+)", "$1" + hiveMSUris); + break; + case 'dfs.name.dir': + case 'dfs.namenode.name.dir': + case 'dfs.data.dir': + case 'dfs.datanode.data.dir': + case 'yarn.nodemanager.local-dirs': + case 'yarn.nodemanager.log-dirs': + case 'mapred.local.dir': + case 'log.dirs': // for Kafka Broker + this.unionAllMountPoints(configProperty, !isOnlyFirstOneNeeded, localDB); + break; + case 'hbase.tmp.dir': + if (configProperty.get('filename') == 'hbase-site.xml') { + this.unionAllMountPoints(configProperty, isOnlyFirstOneNeeded, localDB); + } + break; + case 'fs.checkpoint.dir': + case 'dfs.namenode.checkpoint.dir': + case 'yarn.timeline-service.leveldb-timeline-store.path': + case 'dataDir': + case 'oozie_data_dir': + case 'storm.local.dir': + case '*.falcon.graph.storage.directory': + case '*.falcon.graph.serialize.path': + this.unionAllMountPoints(configProperty, isOnlyFirstOneNeeded, localDB); + break; + case '*.broker.url': + var falconServerHost = masterComponentHostsInDB.findProperty('component', 'FALCON_SERVER').hostName; + this.setDefaultValue(configProperty, 'localhost', falconServerHost); + break; + case 'RANGER_HOST': + var rangerAdminHost = masterComponentHostsInDB.findProperty('component', 'RANGER_ADMIN'); + if(rangerAdminHost) { + configProperty.set('value', rangerAdminHost.hostName); + } else { + configProperty.set('isVisible', 'false'); + configProperty.set('isRequired', 'false'); + } + break; + } + }, + + /** + * Get hive.metastore.uris initial value + * @param hosts + * @param defaultValue + * @returns {string} + */ + getHiveMetastoreUris: function (hosts, defaultValue) { + var hiveMSHosts = hosts.filterProperty('component', 'HIVE_METASTORE').mapProperty('hostName'), + hiveMSUris = hiveMSHosts, + regex = "\\w*:(\\d+)", + portValue = defaultValue && defaultValue.match(new RegExp(regex)); + + if (!portValue) return ''; + if (portValue[1]) { + for (var i = 0; i < hiveMSHosts.length; i++) { + hiveMSUris[i] = "thrift://" + hiveMSHosts[i] + ":" + portValue[1]; + } + } + return hiveMSUris.join(','); + }, + + /** + * @param regex : String + * @param replaceWith : String + * @param configProperty + */ + setDefaultValue: function(configProperty, regex, replaceWith) { + var defaultValue = configProperty.get('defaultValue'); + var re = new RegExp(regex); + defaultValue = defaultValue.replace(re,replaceWith); + configProperty.set('defaultValue',defaultValue); + configProperty.set('value',configProperty.get('defaultValue')); + }, + + unionAllMountPoints: function (configProperty, isOnlyFirstOneNeeded, localDB) { + var hostname = ''; + var mountPointsPerHost = []; + var mountPointAsRoot; + var masterComponentHostsInDB = localDB.masterComponentHosts; + var slaveComponentHostsInDB = localDB.slaveComponentHosts; + var hostsInfo = localDB.hosts; // which we are setting in installerController in step3. + //all hosts should be in local storage without using App.Host model + App.Host.find().forEach(function(item){ + if(!hostsInfo[item.get('id')]){ + hostsInfo[item.get('id')] = { + name: item.get('id'), + cpu: item.get('cpu'), + memory: item.get('memory'), + disk_info: item.get('diskInfo'), + bootStatus: "REGISTERED", + isInstalled: true + }; + } + }); + var temp = ''; + var setOfHostNames = []; + var components = []; + switch (configProperty.get('name')) { + case 'dfs.namenode.name.dir': + case 'dfs.name.dir': + components = masterComponentHostsInDB.filterProperty('component', 'NAMENODE'); + components.forEach(function (component) { + setOfHostNames.push(component.hostName); + }, this); + break; + case 'fs.checkpoint.dir': + case 'dfs.namenode.checkpoint.dir': + components = masterComponentHostsInDB.filterProperty('component', 'SECONDARY_NAMENODE'); + components.forEach(function (component) { + setOfHostNames.push(component.hostName); + }, this); + break; + case 'dfs.data.dir': + case 'dfs.datanode.data.dir': + temp = slaveComponentHostsInDB.findProperty('componentName', 'DATANODE'); + temp.hosts.forEach(function (host) { + setOfHostNames.push(host.hostName); + }, this); + break; + case 'mapred.local.dir': + temp = slaveComponentHostsInDB.findProperty('componentName', 'TASKTRACKER') || slaveComponentHostsInDB.findProperty('componentName', 'NODEMANAGER'); + temp.hosts.forEach(function (host) { + setOfHostNames.push(host.hostName); + }, this); + break; + case 'yarn.nodemanager.log-dirs': + case 'yarn.nodemanager.local-dirs': + temp = slaveComponentHostsInDB.findProperty('componentName', 'NODEMANAGER'); + temp.hosts.forEach(function (host) { + setOfHostNames.push(host.hostName); + }, this); + break; + case 'yarn.timeline-service.leveldb-timeline-store.path': + components = masterComponentHostsInDB.filterProperty('component', 'APP_TIMELINE_SERVER'); + components.forEach(function (component) { + setOfHostNames.push(component.hostName); + }, this); + break; + case 'dataDir': + components = masterComponentHostsInDB.filterProperty('component', 'ZOOKEEPER_SERVER'); + components.forEach(function (component) { + setOfHostNames.push(component.hostName); + }, this); + break; + case 'oozie_data_dir': + components = masterComponentHostsInDB.filterProperty('component', 'OOZIE_SERVER'); + components.forEach(function (component) { + setOfHostNames.push(component.hostName); + }, this); + break; + case 'hbase.tmp.dir': + temp = slaveComponentHostsInDB.findProperty('componentName', 'HBASE_REGIONSERVER'); + temp.hosts.forEach(function (host) { + setOfHostNames.push(host.hostName); + }, this); + break; + case 'storm.local.dir': + temp = slaveComponentHostsInDB.findProperty('componentName', 'SUPERVISOR'); + temp.hosts.forEach(function (host) { + setOfHostNames.push(host.hostName); + }, this); + components = masterComponentHostsInDB.filterProperty('component', 'NIMBUS'); + components.forEach(function (component) { + setOfHostNames.push(component.hostName); + }, this); + break; + case '*.falcon.graph.storage.directory': + case '*.falcon.graph.serialize.path': + components = masterComponentHostsInDB.filterProperty('component', 'FALCON_SERVER'); + components.forEach(function (component) { + setOfHostNames.push(component.hostName); + }, this); + break; + case 'log.dirs': + components = masterComponentHostsInDB.filterProperty('component', 'KAFKA_BROKER'); + components.forEach(function (component) { + setOfHostNames.push(component.hostName); + }, this); + break; + } + + // In Add Host Wizard, if we did not select this slave component for any host, then we don't process any further. + if (setOfHostNames.length === 0) { + return; + } + + var allMountPoints = []; + for (var i = 0; i < setOfHostNames.length; i++) { + hostname = setOfHostNames[i]; + + mountPointsPerHost = hostsInfo[hostname].disk_info; + + mountPointAsRoot = mountPointsPerHost.findProperty('mountpoint', '/'); + + // If Server does not send any host details information then atleast one mountpoint should be presumed as root + // This happens in a single container Linux Docker environment. + if (!mountPointAsRoot) { + mountPointAsRoot = {mountpoint: '/'}; + } + + mountPointsPerHost = mountPointsPerHost.filter(function (mPoint) { + return !(['/', '/home'].contains(mPoint.mountpoint) + || ['/etc/resolv.conf', '/etc/hostname', '/etc/hosts'].contains(mPoint.mountpoint) // docker specific mount points + || mPoint.mountpoint && (mPoint.mountpoint.startsWith('/boot') || mPoint.mountpoint.startsWith('/mnt')) + || ['devtmpfs', 'tmpfs', 'vboxsf', 'CDFS'].contains(mPoint.type) + || mPoint.available == 0); + }); + + mountPointsPerHost.forEach(function (mPoint) { + if( !allMountPoints.findProperty("mountpoint", mPoint.mountpoint)) { + allMountPoints.push(mPoint); + } + }, this); + } + if (allMountPoints.length == 0) { + allMountPoints.push(mountPointAsRoot); + } + configProperty.set('value', ''); + var winRegex = /^([a-z]):\\?$/; + if (!isOnlyFirstOneNeeded) { + allMountPoints.forEach(function (eachDrive) { + var mPoint = configProperty.get('value'); + if (!mPoint) { + mPoint = ""; + } + if (eachDrive.mountpoint === "/") { + mPoint += configProperty.get('defaultDirectory') + "\n"; + } else if(winRegex.test(eachDrive.mountpoint.toLowerCase())) { + switch (configProperty.get('name')) { + case 'dfs.name.dir': + case 'dfs.namenode.name.dir': + case 'dfs.data.dir': + case 'dfs.datanode.data.dir': + var winDriveUrl = eachDrive.mountpoint.toLowerCase().replace(winRegex, "file:///$1:"); + mPoint += winDriveUrl + configProperty.get('defaultDirectory') + "\n"; + break; + default: + var winDrive = eachDrive.mountpoint.toLowerCase().replace(winRegex, "$1:"); + var winDir = configProperty.get('defaultDirectory').replace(/\//g, "\\"); + mPoint += winDrive + winDir + "\n"; + } + } else { + mPoint += eachDrive.mountpoint + configProperty.get('defaultDirectory') + "\n"; + } + configProperty.set('value', mPoint); + configProperty.set('defaultValue', mPoint); + }, this); + } else { + var mPoint = allMountPoints[0].mountpoint; + if (mPoint === "/") { + mPoint = configProperty.get('defaultDirectory'); + } else if(winRegex.test(mPoint.toLowerCase())) { + switch (configProperty.get('name')) { + case 'fs.checkpoint.dir': + case 'dfs.namenode.checkpoint.dir': + var winDriveUrl = mPoint.toLowerCase().replace(winRegex, "file:///$1:"); + mPoint = winDriveUrl + configProperty.get('defaultDirectory') + "\n"; + break; + case 'zk_data_dir': + var winDrive = mPoint.toLowerCase().replace(winRegex, "$1:"); + var winDir = configProperty.get('defaultDirectory').replace(/\//g, "\\\\"); + mPoint = winDrive + winDir + "\n"; + break; + default: + var winDrive = mPoint.toLowerCase().replace(winRegex, "$1:"); + var winDir = configProperty.get('defaultDirectory').replace(/\//g, "\\"); + mPoint = winDrive + winDir + "\n"; + } + } else { + mPoint = mPoint + configProperty.get('defaultDirectory'); + } + configProperty.set('value', mPoint); + configProperty.set('defaultValue', mPoint); + } + } +}; \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/11a09c57/ambari-web/test/models/configs/objects/service_config_category_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/models/configs/objects/service_config_category_test.js b/ambari-web/test/models/configs/objects/service_config_category_test.js new file mode 100644 index 0000000..449c874 --- /dev/null +++ b/ambari-web/test/models/configs/objects/service_config_category_test.js @@ -0,0 +1,184 @@ + +/** + * 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 configPropertyHelper = require('utils/configs/config_property_helper'); + +require('models/configs/objects/service_config_category'); +require('models/configs/objects/service_config_property'); + +var serviceConfigCategory, + nameCases = [ + { + name: 'DataNode', + primary: 'DATANODE' + }, + { + name: 'TaskTracker', + primary: 'TASKTRACKER' + }, + { + name: 'RegionServer', + primary: 'HBASE_REGIONSERVER' + }, + { + name: 'name', + primary: null + } + ], + components = [ + { + name: 'NameNode', + master: true + }, + { + name: 'SNameNode', + master: true + }, + { + name: 'JobTracker', + master: true + }, + { + name: 'HBase Master', + master: true + }, + { + name: 'Oozie Master', + master: true + }, + { + name: 'Hive Metastore', + master: true + }, + { + name: 'WebHCat Server', + master: true + }, + { + name: 'ZooKeeper Server', + master: true + }, + { + name: 'Ganglia', + master: true + }, + { + name: 'DataNode', + slave: true + }, + { + name: 'TaskTracker', + slave: true + }, + { + name: 'RegionServer', + slave: true + } + ], + masters = components.filterProperty('master'), + slaves = components.filterProperty('slave'), + groupsData = { + groups: [ + Em.Object.create({ + errorCount: 1 + }), + Em.Object.create({ + errorCount: 2 + }) + ] + }; + +describe('App.ServiceConfigCategory', function () { + + beforeEach(function () { + serviceConfigCategory = App.ServiceConfigCategory.create(); + }); + + describe('#primaryName', function () { + nameCases.forEach(function (item) { + it('should return ' + item.primary, function () { + serviceConfigCategory.set('name', item.name); + expect(serviceConfigCategory.get('primaryName')).to.equal(item.primary); + }) + }); + }); + + describe('#isForMasterComponent', function () { + masters.forEach(function (item) { + it('should be true for ' + item.name, function () { + serviceConfigCategory.set('name', item.name); + expect(serviceConfigCategory.get('isForMasterComponent')).to.be.true; + }); + }); + it('should be false', function () { + serviceConfigCategory.set('name', 'name'); + expect(serviceConfigCategory.get('isForMasterComponent')).to.be.false; + }); + }); + + describe('#isForSlaveComponent', function () { + slaves.forEach(function (item) { + it('should be true for ' + item.name, function () { + serviceConfigCategory.set('name', item.name); + expect(serviceConfigCategory.get('isForSlaveComponent')).to.be.true; + }); + }); + it('should be false', function () { + serviceConfigCategory.set('name', 'name'); + expect(serviceConfigCategory.get('isForSlaveComponent')).to.be.false; + }); + }); + + describe('#slaveErrorCount', function () { + it('should be 0', function () { + serviceConfigCategory.set('slaveConfigs', []); + expect(serviceConfigCategory.get('slaveErrorCount')).to.equal(0); + }); + it('should sum all errorCount values', function () { + serviceConfigCategory.set('slaveConfigs', groupsData); + expect(serviceConfigCategory.get('slaveErrorCount')).to.equal(3); + }); + }); + + describe('#errorCount', function () { + it('should sum all errors for category', function () { + serviceConfigCategory.reopen({ + slaveErrorCount: 1 + }); + expect(serviceConfigCategory.get('errorCount')).to.equal(1); + serviceConfigCategory.set('nonSlaveErrorCount', 2); + expect(serviceConfigCategory.get('errorCount')).to.equal(3); + serviceConfigCategory.set('slaveErrorCount', 0); + expect(serviceConfigCategory.get('errorCount')).to.equal(2); + }); + }); + + describe('#isAdvanced', function () { + it('should be true', function () { + serviceConfigCategory.set('name', 'Advanced'); + expect(serviceConfigCategory.get('isAdvanced')).to.be.true; + }); + it('should be false', function () { + serviceConfigCategory.set('name', 'name'); + expect(serviceConfigCategory.get('isAdvanced')).to.be.false; + }); + }); + +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/11a09c57/ambari-web/test/models/configs/objects/service_config_property_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/models/configs/objects/service_config_property_test.js b/ambari-web/test/models/configs/objects/service_config_property_test.js new file mode 100644 index 0000000..9235d6e --- /dev/null +++ b/ambari-web/test/models/configs/objects/service_config_property_test.js @@ -0,0 +1,474 @@ +/** + * 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 configPropertyHelper = require('utils/configs/config_property_helper'); + +require('models/configs/objects/service_config_category'); +require('models/configs/objects/service_config_property'); + +var serviceConfigProperty, + serviceConfigPropertyInit, + configsData = [ + Ember.Object.create({ + category: 'c0', + overrides: [ + { + error: true, + errorMessage: 'error' + }, + { + error: true + }, + {} + ] + }), + Ember.Object.create({ + category: 'c1', + isValid: false, + isVisible: true + }), + Ember.Object.create({ + category: 'c0', + isValid: true, + isVisible: true + }), + Ember.Object.create({ + category: 'c1', + isValid: false, + isVisible: false + }) + ], + + components = [ + { + name: 'NameNode', + master: true + }, + { + name: 'SNameNode', + master: true + }, + { + name: 'JobTracker', + master: true + }, + { + name: 'HBase Master', + master: true + }, + { + name: 'Oozie Master', + master: true + }, + { + name: 'Hive Metastore', + master: true + }, + { + name: 'WebHCat Server', + master: true + }, + { + name: 'ZooKeeper Server', + master: true + }, + { + name: 'Ganglia', + master: true + }, + { + name: 'DataNode', + slave: true + }, + { + name: 'TaskTracker', + slave: true + }, + { + name: 'RegionServer', + slave: true + } + ], + overridableFalseData = [ + { + isOverridable: false + }, + { + isEditable: false, + overrides: configsData[0].overrides + }, + { + displayType: 'masterHost' + } + ], + overridableTrueData = [ + { + isOverridable: true, + isEditable: true + }, { + isOverridable: true, + overrides: [] + }, + { + isOverridable: true + } + ], + overriddenFalseData = [ + { + overrides: null, + isOriginalSCP: true + }, + { + overrides: [], + isOriginalSCP: true + } + ], + overriddenTrueData = [ + { + overrides: configsData[0].overrides + }, + { + isOriginalSCP: false + } + ], + removableFalseData = [ + { + isEditable: false + }, + { + hasOverrides: true + }, + { + isUserProperty: false, + isOriginalSCP: true + } + ], + removableTrueData = [ + { + isEditable: true, + hasOverrides: false, + isUserProperty: true + }, + { + isEditable: true, + hasOverrides: false, + isOriginalSCP: false + } + ], + initPropertyData = [ + { + initial: { + displayType: 'password', + value: 'value' + }, + result: { + retypedPassword: 'value' + } + }, + { + initial: { + id: 'puppet var', + value: '', + defaultValue: 'default' + }, + result: { + value: 'default' + } + } + ], + notDefaultFalseData = [ + { + isEditable: false + }, + { + defaultValue: null + }, + { + value: 'value', + defaultValue: 'value' + } + ], + notDefaultTrueData = { + isEditable: true, + value: 'value', + defaultValue: 'default' + }, + types = ['masterHost', 'slaveHosts', 'masterHosts', 'slaveHost', 'radio button'], + classCases = [ + { + initial: { + displayType: 'checkbox' + }, + viewClass: App.ServiceConfigCheckbox + }, + { + initial: { + displayType: 'checkbox', + dependentConfigPattern: 'somPattern' + }, + viewClass: App.ServiceConfigCheckboxWithDependencies + }, + { + initial: { + displayType: 'password' + }, + viewClass: App.ServiceConfigPasswordField + }, + { + initial: { + displayType: 'combobox' + }, + viewClass: App.ServiceConfigComboBox + }, + { + initial: { + displayType: 'radio button' + }, + viewClass: App.ServiceConfigRadioButtons + }, + { + initial: { + displayType: 'directories' + }, + viewClass: App.ServiceConfigTextArea + }, + { + initial: { + displayType: 'content' + }, + viewClass: App.ServiceConfigTextAreaContent + + }, + { + initial: { + displayType: 'multiLine' + }, + viewClass: App.ServiceConfigTextArea + }, + { + initial: { + displayType: 'custom' + }, + viewClass: App.ServiceConfigBigTextArea + }, + { + initial: { + displayType: 'masterHost' + }, + viewClass: App.ServiceConfigMasterHostView + }, + { + initial: { + displayType: 'masterHosts' + }, + viewClass: App.ServiceConfigMasterHostsView + }, + { + initial: { + displayType: 'slaveHosts' + }, + viewClass: App.ServiceConfigSlaveHostsView + }, + { + initial: { + unit: true, + displayType: 'type' + }, + viewClass: App.ServiceConfigTextFieldWithUnit + }, + { + initial: { + unit: false, + displayType: 'type' + }, + viewClass: App.ServiceConfigTextField + }, + { + initial: { + unit: false, + displayType: 'supportTextConnection' + }, + viewClass: App.checkConnectionView + } + ]; + +describe('App.ServiceConfigProperty', function () { + + beforeEach(function () { + serviceConfigProperty = App.ServiceConfigProperty.create(); + }); + + describe('#overrideErrorTrigger', function () { + it('should be an increment', function () { + serviceConfigProperty.set('overrides', configsData[0].overrides); + expect(serviceConfigProperty.get('overrideErrorTrigger')).to.equal(1); + serviceConfigProperty.set('overrides', []); + expect(serviceConfigProperty.get('overrideErrorTrigger')).to.equal(2); + }); + }); + + describe('#isPropertyOverridable', function () { + overridableFalseData.forEach(function (item) { + it('should be false', function () { + Em.keys(item).forEach(function (prop) { + serviceConfigProperty.set(prop, item[prop]); + }); + expect(serviceConfigProperty.get('isPropertyOverridable')).to.be.false; + }); + }); + overridableTrueData.forEach(function (item) { + it('should be true', function () { + Em.keys(item).forEach(function (prop) { + serviceConfigProperty.set(prop, item[prop]); + }); + expect(serviceConfigProperty.get('isPropertyOverridable')).to.be.true; + }); + }); + }); + + describe('#isOverridden', function () { + overriddenFalseData.forEach(function (item) { + it('should be false', function () { + Em.keys(item).forEach(function (prop) { + serviceConfigProperty.set(prop, item[prop]); + }); + expect(serviceConfigProperty.get('isOverridden')).to.be.false; + }); + }); + overriddenTrueData.forEach(function (item) { + it('should be true', function () { + Em.keys(item).forEach(function (prop) { + serviceConfigProperty.set(prop, item[prop]); + }); + expect(serviceConfigProperty.get('isOverridden')).to.be.true; + }); + }); + }); + + describe('#isRemovable', function () { + removableFalseData.forEach(function (item) { + it('should be false', function () { + Em.keys(item).forEach(function (prop) { + serviceConfigProperty.set(prop, item[prop]); + }); + expect(serviceConfigProperty.get('isRemovable')).to.be.false; + }); + }); + removableTrueData.forEach(function (item) { + it('should be true', function () { + Em.keys(item).forEach(function (prop) { + serviceConfigProperty.set(prop, item[prop]); + }); + expect(serviceConfigProperty.get('isRemovable')).to.be.true; + }); + }); + }); + + describe('#init', function () { + initPropertyData.forEach(function (item) { + it('should set initial data', function () { + serviceConfigPropertyInit = App.ServiceConfigProperty.create(item.initial); + Em.keys(item.result).forEach(function (prop) { + expect(serviceConfigPropertyInit.get(prop)).to.equal(item.result[prop]); + }); + }); + }); + }); + + describe('#isNotDefaultValue', function () { + notDefaultFalseData.forEach(function (item) { + it('should be false', function () { + Em.keys(item).forEach(function (prop) { + serviceConfigProperty.set(prop, item[prop]); + }); + expect(serviceConfigProperty.get('isNotDefaultValue')).to.be.false; + }); + }); + it('should be true', function () { + Em.keys(notDefaultTrueData).forEach(function (prop) { + serviceConfigProperty.set(prop, notDefaultTrueData[prop]); + }); + expect(serviceConfigProperty.get('isNotDefaultValue')).to.be.true; + }); + }); + + describe('#cantBeUndone', function () { + types.forEach(function (item) { + it('should be true', function () { + serviceConfigProperty.set('displayType', item); + expect(serviceConfigProperty.get('cantBeUndone')).to.be.true; + }); + }); + it('should be false', function () { + serviceConfigProperty.set('displayType', 'type'); + expect(serviceConfigProperty.get('cantBeUndone')).to.be.false; + }); + }); + + describe('#isValid', function () { + it('should be true', function () { + serviceConfigProperty.set('errorMessage', ''); + expect(serviceConfigProperty.get('isValid')).to.be.true; + }); + it('should be false', function () { + serviceConfigProperty.set('errorMessage', 'message'); + expect(serviceConfigProperty.get('isValid')).to.be.false; + }); + }); + + describe('#viewClass', function () { + classCases.forEach(function (item) { + it ('should be ' + item.viewClass, function () { + Em.keys(item.initial).forEach(function (prop) { + serviceConfigProperty.set(prop, item.initial[prop]); + }); + expect(serviceConfigProperty.get('viewClass')).to.eql(item.viewClass); + }); + }); + }); + + describe('#validate', function () { + it('not required', function () { + serviceConfigProperty.setProperties({ + isRequired: false, + value: '' + }); + expect(serviceConfigProperty.get('errorMessage')).to.be.empty; + expect(serviceConfigProperty.get('error')).to.be.false; + }); + it('should validate', function () { + serviceConfigProperty.setProperties({ + isRequired: true, + value: 'value' + }); + expect(serviceConfigProperty.get('errorMessage')).to.be.empty; + expect(serviceConfigProperty.get('error')).to.be.false; + }); + it('should fail', function () { + serviceConfigProperty.setProperties({ + isRequired: true, + value: 'value' + }); + serviceConfigProperty.set('value', ''); + expect(serviceConfigProperty.get('errorMessage')).to.equal('This is required'); + expect(serviceConfigProperty.get('error')).to.be.true; + }); + }); + +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/11a09c57/ambari-web/test/models/configs/objects/service_config_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/models/configs/objects/service_config_test.js b/ambari-web/test/models/configs/objects/service_config_test.js new file mode 100644 index 0000000..cfa015c --- /dev/null +++ b/ambari-web/test/models/configs/objects/service_config_test.js @@ -0,0 +1,165 @@ +/** + * 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 configPropertyHelper = require('utils/configs/config_property_helper'); + +require('models/configs/objects/service_config'); + +var serviceConfig, + group, + configsData = [ + Ember.Object.create({ + category: 'c0', + overrides: [ + { + error: true, + errorMessage: 'error' + }, + { + error: true + }, + {} + ] + }), + Ember.Object.create({ + category: 'c1', + isValid: false, + isVisible: true + }), + Ember.Object.create({ + category: 'c0', + isValid: true, + isVisible: true + }), + Ember.Object.create({ + category: 'c1', + isValid: false, + isVisible: false + }) + ], + configCategoriesData = [ + Em.Object.create({ + name: 'c0', + slaveErrorCount: 1 + }), + Em.Object.create({ + name: 'c1', + slaveErrorCount: 2 + }) + ], + components = [ + { + name: 'NameNode', + master: true + }, + { + name: 'SNameNode', + master: true + }, + { + name: 'JobTracker', + master: true + }, + { + name: 'HBase Master', + master: true + }, + { + name: 'Oozie Master', + master: true + }, + { + name: 'Hive Metastore', + master: true + }, + { + name: 'WebHCat Server', + master: true + }, + { + name: 'ZooKeeper Server', + master: true + }, + { + name: 'Ganglia', + master: true + }, + { + name: 'DataNode', + slave: true + }, + { + name: 'TaskTracker', + slave: true + }, + { + name: 'RegionServer', + slave: true + } + ], + masters = components.filterProperty('master'), + slaves = components.filterProperty('slave'), + groupNoErrorsData = [].concat(configsData.slice(2)), + groupErrorsData = [configsData[1]]; + +describe('App.ServiceConfig', function () { + + beforeEach(function () { + serviceConfig = App.ServiceConfig.create(); + }); + + describe('#errorCount', function () { + it('should be 0', function () { + serviceConfig.setProperties({ + configs: [], + configCategories: [] + }); + expect(serviceConfig.get('errorCount')).to.equal(0); + }); + it('should sum counts of all errors', function () { + serviceConfig.setProperties({ + configs: configsData, + configCategories: configCategoriesData + }); + expect(serviceConfig.get('errorCount')).to.equal(6); + expect(serviceConfig.get('configCategories').findProperty('name', 'c0').get('nonSlaveErrorCount')).to.equal(2); + expect(serviceConfig.get('configCategories').findProperty('name', 'c1').get('nonSlaveErrorCount')).to.equal(1); + }); + }); + +}); + +describe('App.Group', function () { + + beforeEach(function () { + group = App.Group.create(); + }); + + describe('#errorCount', function () { + it('should be 0', function () { + group.set('properties', groupNoErrorsData); + expect(group.get('errorCount')).to.equal(0); + }); + it('should be 1', function () { + group.set('properties', groupErrorsData); + expect(group.get('errorCount')).to.equal(1); + }); + }); + +});
