http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/generator/generator-optional.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/generator/generator-optional.js b/modules/web-console/src/main/js/generator/generator-optional.js index 0e23f59..61de1a2 100644 --- a/modules/web-console/src/main/js/generator/generator-optional.js +++ b/modules/web-console/src/main/js/generator/generator-optional.js @@ -18,7 +18,7 @@ // Optional content generation entry point. const $generatorOptional = {}; -$generatorOptional.optionalContent = function (zip, cluster) { +$generatorOptional.optionalContent = function(zip, cluster) { // eslint-disable-line no-unused-vars // No-op. };
http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/generator/generator-properties.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/generator/generator-properties.js b/modules/web-console/src/main/js/generator/generator-properties.js index 1ecaeb6..4773f22 100644 --- a/modules/web-console/src/main/js/generator/generator-properties.js +++ b/modules/web-console/src/main/js/generator/generator-properties.js @@ -32,6 +32,7 @@ $generatorProperties.jdbcUrlTemplate = function(dialect) { return 'jdbc:postgresql://[host]:[port]/[database]'; case 'H2': return 'jdbc:h2:tcp://[host]/[database]'; + default: } return 'jdbc:your_database'; @@ -44,17 +45,17 @@ $generatorProperties.jdbcUrlTemplate = function(dialect) { * @param res Resulting output with generated properties. * @returns {string} Generated content. */ -$generatorProperties.dataSourcesProperties = function (cluster, res) { - var datasources = []; +$generatorProperties.dataSourcesProperties = function(cluster, res) { + const datasources = []; if (cluster.caches && cluster.caches.length > 0) { - _.forEach(cluster.caches, function (cache) { + _.forEach(cluster.caches, function(cache) { if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) { - var storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind]; + const storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind]; - var dialect = storeFactory.connectVia ? (storeFactory.connectVia === 'DataSource' ? storeFactory.dialect : undefined): storeFactory.dialect; + const dialect = storeFactory.connectVia ? (storeFactory.connectVia === 'DataSource' ? storeFactory.dialect : null) : storeFactory.dialect; - var connectViaUrl = cache.cacheStoreFactory.kind === 'CacheJdbcBlobStoreFactory' && storeFactory.connectVia === 'URL'; + const connectViaUrl = cache.cacheStoreFactory.kind === 'CacheJdbcBlobStoreFactory' && storeFactory.connectVia === 'URL'; if (!res && (dialect || connectViaUrl)) { res = $generatorCommon.builder(); @@ -63,13 +64,13 @@ $generatorProperties.dataSourcesProperties = function (cluster, res) { } if (dialect) { - var beanId = storeFactory.dataSourceBean; + const beanId = storeFactory.dataSourceBean; - var dsClsName = $generatorCommon.dataSourceClassName(dialect); + const dsClsName = $generatorCommon.dataSourceClassName(dialect); - var varType = res.importClass(dsClsName); + const varType = res.importClass(dsClsName); - var beanClassName = $generatorCommon.toJavaName(varType, storeFactory.dataSourceBean); + const beanClassName = $generatorCommon.toJavaName(varType, storeFactory.dataSourceBean); if (!_.includes(datasources, beanClassName)) { datasources.push(beanClassName); @@ -111,7 +112,7 @@ $generatorProperties.dataSourcesProperties = function (cluster, res) { * @param res Optional configuration presentation builder object. * @returns Configuration presentation builder object */ -$generatorProperties.sslProperties = function (cluster, res) { +$generatorProperties.sslProperties = function(cluster, res) { if (cluster.sslEnabled && cluster.sslContextFactory) { if (!res) { res = $generatorCommon.builder(); @@ -138,7 +139,7 @@ $generatorProperties.sslProperties = function (cluster, res) { * @param res Optional configuration presentation builder object. * @returns Configuration presentation builder object */ -$generatorProperties.generateProperties = function (cluster, res) { +$generatorProperties.generateProperties = function(cluster, res) { res = $generatorProperties.dataSourcesProperties(cluster, res); res = $generatorProperties.sslProperties(cluster, res); http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/generator/generator-readme.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/generator/generator-readme.js b/modules/web-console/src/main/js/generator/generator-readme.js index c4e2f81..432f1e6 100644 --- a/modules/web-console/src/main/js/generator/generator-readme.js +++ b/modules/web-console/src/main/js/generator/generator-readme.js @@ -18,7 +18,7 @@ // README.txt generation entry point. const $generatorReadme = {}; -$generatorReadme.generatedBy = function (res) { +$generatorReadme.generatedBy = function(res) { res.line('Content of this folder was generated by Apache Ignite Web Console'); res.line('================================================================='); @@ -31,7 +31,7 @@ $generatorReadme.generatedBy = function (res) { * @param res Resulting output with generated readme. * @returns {string} Generated content. */ -$generatorReadme.readme = function (res) { +$generatorReadme.readme = function(res) { if (!res) res = $generatorCommon.builder(); @@ -72,7 +72,7 @@ $generatorReadme.readme = function (res) { * @param res Resulting output with generated readme. * @returns {string} Generated content. */ -$generatorReadme.readmeJdbc = function (res) { +$generatorReadme.readmeJdbc = function(res) { if (!res) res = $generatorCommon.builder(); http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/generator/generator-xml.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/generator/generator-xml.js b/modules/web-console/src/main/js/generator/generator-xml.js index 658553c..4528f36 100644 --- a/modules/web-console/src/main/js/generator/generator-xml.js +++ b/modules/web-console/src/main/js/generator/generator-xml.js @@ -19,16 +19,16 @@ const $generatorXml = {}; // Do XML escape. -$generatorXml.escape = function (s) { - if (typeof(s) !== 'string') +$generatorXml.escape = function(s) { + if (typeof (s) !== 'string') return s; return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); }; // Add constructor argument -$generatorXml.constructorArg = function (res, ix, obj, propName, dflt, opt) { - var v = (obj ? obj[propName] : undefined) || dflt; +$generatorXml.constructorArg = function(res, ix, obj, propName, dflt, opt) { + const v = (obj ? obj[propName] : null) || dflt; if ($generatorCommon.isDefinedAndNotEmpty(v)) res.line('<constructor-arg ' + (ix >= 0 ? 'index="' + ix + '" ' : '') + 'value="' + v + '"/>'); @@ -40,8 +40,8 @@ $generatorXml.constructorArg = function (res, ix, obj, propName, dflt, opt) { }; // Add XML element. -$generatorXml.element = function (res, tag, attr1, val1, attr2, val2) { - var elem = '<' + tag; +$generatorXml.element = function(res, tag, attr1, val1, attr2, val2) { + let elem = '<' + tag; if (attr1) elem += ' ' + attr1 + '="' + val1 + '"'; @@ -56,12 +56,12 @@ $generatorXml.element = function (res, tag, attr1, val1, attr2, val2) { }; // Add property. -$generatorXml.property = function (res, obj, propName, setterName, dflt) { +$generatorXml.property = function(res, obj, propName, setterName, dflt) { if (!_.isNil(obj)) { - var val = obj[propName]; + const val = obj[propName]; if ($generatorCommon.isDefinedAndNotEmpty(val)) { - var missDflt = _.isNil(dflt); + const missDflt = _.isNil(dflt); // Add to result if no default provided or value not equals to default. if (missDflt || (!missDflt && val !== dflt)) { @@ -76,16 +76,16 @@ $generatorXml.property = function (res, obj, propName, setterName, dflt) { }; // Add property for class name. -$generatorXml.classNameProperty = function (res, obj, propName) { - var val = obj[propName]; +$generatorXml.classNameProperty = function(res, obj, propName) { + const val = obj[propName]; if (!_.isNil(val)) $generatorXml.element(res, 'property', 'name', propName, 'value', $generatorCommon.JavaTypes.fullClassName(val)); }; // Add list property. -$generatorXml.listProperty = function (res, obj, propName, listType, rowFactory) { - var val = obj[propName]; +$generatorXml.listProperty = function(res, obj, propName, listType, rowFactory) { + const val = obj[propName]; if (val && val.length > 0) { res.emptyLineIfNeeded(); @@ -94,16 +94,12 @@ $generatorXml.listProperty = function (res, obj, propName, listType, rowFactory) listType = 'list'; if (!rowFactory) - rowFactory = function (val) { - return '<value>' + $generatorXml.escape(val) + '</value>'; - }; + rowFactory = (v) => '<value>' + $generatorXml.escape(v) + '</value>'; res.startBlock('<property name="' + propName + '">'); res.startBlock('<' + listType + '>'); - _.forEach(val, function(v) { - res.line(rowFactory(v)); - }); + _.forEach(val, (v) => res.line(rowFactory(v))); res.endBlock('</' + listType + '>'); res.endBlock('</property>'); @@ -113,23 +109,19 @@ $generatorXml.listProperty = function (res, obj, propName, listType, rowFactory) }; // Add array property -$generatorXml.arrayProperty = function (res, obj, propName, descr, rowFactory) { - var val = obj[propName]; +$generatorXml.arrayProperty = function(res, obj, propName, descr, rowFactory) { + const val = obj[propName]; if (val && val.length > 0) { res.emptyLineIfNeeded(); if (!rowFactory) - rowFactory = function (val) { - return '<bean class="' + val + '"/>'; - }; + rowFactory = (v) => '<bean class="' + v + '"/>'; res.startBlock('<property name="' + propName + '">'); res.startBlock('<list>'); - _.forEach(val, function (v) { - res.append(rowFactory(v)); - }); + _.forEach(val, (v) => res.append(rowFactory(v))); res.endBlock('</list>'); res.endBlock('</property>'); @@ -145,8 +137,8 @@ $generatorXml.arrayProperty = function (res, obj, propName, descr, rowFactory) { * @param desc Bean metadata object. * @param createBeanAlthoughNoProps Always generate bean even it has no properties defined. */ -$generatorXml.beanProperty = function (res, bean, beanPropName, desc, createBeanAlthoughNoProps) { - var props = desc.fields; +$generatorXml.beanProperty = function(res, bean, beanPropName, desc, createBeanAlthoughNoProps) { + const props = desc.fields; if (bean && $generatorCommon.hasProperty(bean, props)) { if (!createBeanAlthoughNoProps) @@ -160,7 +152,7 @@ $generatorXml.beanProperty = function (res, bean, beanPropName, desc, createBean res.startBlock('<bean class="' + desc.className + '">'); - var hasData = false; + let hasData = false; _.forIn(props, function(descr, propName) { if (props.hasOwnProperty(propName)) { @@ -177,14 +169,14 @@ $generatorXml.beanProperty = function (res, bean, beanPropName, desc, createBean break; case 'propertiesAsList': - var val = bean[propName]; + const val = bean[propName]; if (val && val.length > 0) { res.startBlock('<property name="' + propName + '">'); res.startBlock('<props>'); _.forEach(val, function(nameAndValue) { - var eqIndex = nameAndValue.indexOf('='); + const eqIndex = nameAndValue.indexOf('='); if (eqIndex >= 0) { res.line('<prop key="' + $generatorXml.escape(nameAndValue.substring(0, eqIndex)) + '">' + $generatorXml.escape(nameAndValue.substr(eqIndex + 1)) + '</prop>'); @@ -249,9 +241,9 @@ $generatorXml.beanProperty = function (res, bean, beanPropName, desc, createBean * @param obj Object to take bean class name. * @param propName Property name. */ -$generatorXml.simpleBeanProperty = function (res, obj, propName) { +$generatorXml.simpleBeanProperty = function(res, obj, propName) { if (!_.isNil(obj)) { - var val = obj[propName]; + const val = obj[propName]; if ($generatorCommon.isDefinedAndNotEmpty(val)) { res.startBlock('<property name="' + propName + '">'); @@ -264,7 +256,7 @@ $generatorXml.simpleBeanProperty = function (res, obj, propName) { }; // Generate eviction policy. -$generatorXml.evictionPolicy = function (res, evtPlc, propName) { +$generatorXml.evictionPolicy = function(res, evtPlc, propName) { if (evtPlc && evtPlc.kind) { $generatorXml.beanProperty(res, evtPlc[evtPlc.kind.toUpperCase()], propName, $generatorCommon.EVICTION_POLICIES[evtPlc.kind], true); @@ -272,7 +264,7 @@ $generatorXml.evictionPolicy = function (res, evtPlc, propName) { }; // Generate discovery. -$generatorXml.clusterGeneral = function (cluster, res) { +$generatorXml.clusterGeneral = function(cluster, res) { if (!res) res = $generatorCommon.builder(); @@ -284,7 +276,7 @@ $generatorXml.clusterGeneral = function (cluster, res) { res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">'); res.startBlock('<property name="ipFinder">'); - var d = cluster.discovery; + const d = cluster.discovery; switch (d.kind) { case 'Multicast': @@ -306,9 +298,8 @@ $generatorXml.clusterGeneral = function (cluster, res) { case 'Vm': res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">'); - if (d.Vm) { + if (d.Vm) $generatorXml.listProperty(res, d.Vm, 'addresses'); - } res.endBlock('</bean>'); @@ -359,9 +350,8 @@ $generatorXml.clusterGeneral = function (cluster, res) { case 'Jdbc': res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.jdbc.TcpDiscoveryJdbcIpFinder">'); - if (d.Jdbc) { + if (d.Jdbc) res.line('<property name="initSchema" value="' + (!_.isNil(d.Jdbc.initSchema) && d.Jdbc.initSchema) + '"/>'); - } res.endBlock('</bean>'); @@ -370,9 +360,8 @@ $generatorXml.clusterGeneral = function (cluster, res) { case 'SharedFs': res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.sharedfs.TcpDiscoverySharedFsIpFinder">'); - if (d.SharedFs) { + if (d.SharedFs) $generatorXml.property(res, d.SharedFs, 'path'); - } res.endBlock('</bean>'); @@ -391,9 +380,9 @@ $generatorXml.clusterGeneral = function (cluster, res) { $generatorXml.property(res, d.ZooKeeper, 'zkConnectionString'); if (d.ZooKeeper.retryPolicy && d.ZooKeeper.retryPolicy.kind) { - var kind = d.ZooKeeper.retryPolicy.kind; - var retryPolicy = d.ZooKeeper.retryPolicy[kind]; - var customClassDefined = retryPolicy && $generatorCommon.isDefinedAndNotEmpty(retryPolicy.className); + const kind = d.ZooKeeper.retryPolicy.kind; + const retryPolicy = d.ZooKeeper.retryPolicy[kind]; + const customClassDefined = retryPolicy && $generatorCommon.isDefinedAndNotEmpty(retryPolicy.className); if (kind !== 'Custom' || customClassDefined) res.startBlock('<property name="retryPolicy">'); @@ -403,7 +392,7 @@ $generatorXml.clusterGeneral = function (cluster, res) { res.startBlock('<bean class="org.apache.curator.retry.ExponentialBackoffRetry">'); $generatorXml.constructorArg(res, 0, retryPolicy, 'baseSleepTimeMs', 1000); $generatorXml.constructorArg(res, 1, retryPolicy, 'maxRetries', 10); - $generatorXml.constructorArg(res, 2, retryPolicy, 'maxSleepMs', undefined, true); + $generatorXml.constructorArg(res, 2, retryPolicy, 'maxSleepMs', null, true); res.endBlock('</bean>'); break; @@ -452,6 +441,8 @@ $generatorXml.clusterGeneral = function (cluster, res) { res.line('<bean class="' + retryPolicy.className + '"/>'); break; + + default: } if (kind !== 'Custom' || customClassDefined) @@ -485,7 +476,7 @@ $generatorXml.clusterGeneral = function (cluster, res) { }; // Generate atomics group. -$generatorXml.clusterAtomics = function (atomics, res) { +$generatorXml.clusterAtomics = function(atomics, res) { if (!res) res = $generatorCommon.builder(); @@ -497,9 +488,9 @@ $generatorXml.clusterAtomics = function (atomics, res) { res.startBlock('<property name="atomicConfiguration">'); res.startBlock('<bean class="org.apache.ignite.configuration.AtomicConfiguration">'); - var cacheMode = atomics.cacheMode ? atomics.cacheMode : 'PARTITIONED'; + const cacheMode = atomics.cacheMode ? atomics.cacheMode : 'PARTITIONED'; - var hasData = cacheMode !== 'PARTITIONED'; + let hasData = cacheMode !== 'PARTITIONED'; $generatorXml.property(res, atomics, 'cacheMode', null, 'PARTITIONED'); @@ -521,7 +512,7 @@ $generatorXml.clusterAtomics = function (atomics, res) { }; // Generate binary group. -$generatorXml.clusterBinary = function (binary, res) { +$generatorXml.clusterBinary = function(binary, res) { if (!res) res = $generatorCommon.builder(); @@ -537,7 +528,7 @@ $generatorXml.clusterBinary = function (binary, res) { res.startBlock('<property name="typeConfigurations">'); res.startBlock('<list>'); - _.forEach(binary.typeConfigurations, function (type) { + _.forEach(binary.typeConfigurations, function(type) { res.startBlock('<bean class="org.apache.ignite.binary.BinaryTypeConfiguration">'); $generatorXml.property(res, type, 'typeName'); @@ -564,8 +555,90 @@ $generatorXml.clusterBinary = function (binary, res) { return res; }; +// Generate collision group. +$generatorXml.clusterCollision = function(collision, res) { + if (!res) + res = $generatorCommon.builder(); + + if (collision && collision.kind && collision.kind !== 'Noop') { + const spi = collision[collision.kind]; + + if (collision.kind !== 'Custom' || (spi && $generatorCommon.isDefinedAndNotEmpty(spi.class))) { + res.startBlock('<property name="collisionSpi">'); + + switch (collision.kind) { + case 'JobStealing': + res.startBlock('<bean class="org.apache.ignite.spi.collision.jobstealing.JobStealingCollisionSpi">'); + $generatorXml.property(res, spi, 'activeJobsThreshold', null, 95); + $generatorXml.property(res, spi, 'waitJobsThreshold', null, 0); + $generatorXml.property(res, spi, 'messageExpireTime', null, 1000); + $generatorXml.property(res, spi, 'maximumStealingAttempts', null, 5); + $generatorXml.property(res, spi, 'stealingEnabled', null, true); + + if ($generatorCommon.isDefinedAndNotEmpty(spi.externalCollisionListener)) { + res.needEmptyLine = true; + + res.startBlock('<property name="externalCollisionListener">'); + res.line('<bean class="' + spi.externalCollisionListener + ' "/>'); + res.endBlock('</property>'); + } + + if ($generatorCommon.isDefinedAndNotEmpty(spi.stealingAttributes)) { + res.needEmptyLine = true; + + res.startBlock('<property name="stealingAttributes">'); + res.startBlock('<map>'); + + _.forEach(spi.stealingAttributes, function(attr) { + $generatorXml.element(res, 'entry', 'key', attr.name, 'value', attr.value); + }); + + res.endBlock('</map>'); + res.endBlock('</property>'); + } + + res.endBlock('</bean>'); + + break; + + case 'FifoQueue': + res.startBlock('<bean class="org.apache.ignite.spi.collision.fifoqueue.FifoQueueCollisionSpi">'); + $generatorXml.property(res, spi, 'parallelJobsNumber'); + $generatorXml.property(res, spi, 'waitingJobsNumber'); + res.endBlock('</bean>'); + + break; + + case 'PriorityQueue': + res.startBlock('<bean class="org.apache.ignite.spi.collision.priorityqueue.PriorityQueueCollisionSpi">'); + $generatorXml.property(res, spi, 'parallelJobsNumber'); + $generatorXml.property(res, spi, 'waitingJobsNumber'); + $generatorXml.property(res, spi, 'priorityAttributeKey', null, 'grid.task.priority'); + $generatorXml.property(res, spi, 'jobPriorityAttributeKey', null, 'grid.job.priority'); + $generatorXml.property(res, spi, 'defaultPriority', null, 0); + $generatorXml.property(res, spi, 'starvationIncrement', null, 1); + $generatorXml.property(res, spi, 'starvationPreventionEnabled', null, true); + res.endBlock('</bean>'); + + break; + + case 'Custom': + res.line('<bean class="' + spi.class + '"/>'); + + break; + + default: + } + + res.endBlock('</property>'); + } + } + + return res; +}; + // Generate communication group. -$generatorXml.clusterCommunication = function (cluster, res) { +$generatorXml.clusterCommunication = function(cluster, res) { if (!res) res = $generatorCommon.builder(); @@ -595,7 +668,7 @@ $generatorXml.clusterConnector = function(connector, res) { res = $generatorCommon.builder(); if (!_.isNil(connector) && connector.enabled) { - var cfg = _.cloneDeep($generatorCommon.CONNECTOR_CONFIGURATION); + const cfg = _.cloneDeep($generatorCommon.CONNECTOR_CONFIGURATION); if (connector.sslEnabled) { cfg.fields.sslClientAuth = {dflt: false}; @@ -611,14 +684,14 @@ $generatorXml.clusterConnector = function(connector, res) { }; // Generate deployment group. -$generatorXml.clusterDeployment = function (cluster, res) { +$generatorXml.clusterDeployment = function(cluster, res) { if (!res) res = $generatorCommon.builder(); if ($generatorXml.property(res, cluster, 'deploymentMode', null, 'SHARED')) res.needEmptyLine = true; - var p2pEnabled = cluster.peerClassLoadingEnabled; + const p2pEnabled = cluster.peerClassLoadingEnabled; if (!_.isNil(p2pEnabled)) { $generatorXml.property(res, cluster, 'peerClassLoadingEnabled', null, false); @@ -636,7 +709,7 @@ $generatorXml.clusterDeployment = function (cluster, res) { }; // Generate discovery group. -$generatorXml.clusterDiscovery = function (disco, res) { +$generatorXml.clusterDiscovery = function(disco, res) { if (!res) res = $generatorCommon.builder(); @@ -677,7 +750,7 @@ $generatorXml.clusterDiscovery = function (disco, res) { }; // Generate events group. -$generatorXml.clusterEvents = function (cluster, res) { +$generatorXml.clusterEvents = function(cluster, res) { if (!res) res = $generatorCommon.builder(); @@ -720,12 +793,120 @@ $generatorXml.clusterEvents = function (cluster, res) { return res; }; +// Generate failover group. +$generatorXml.clusterFailover = function(cluster, res) { + if (!res) + res = $generatorCommon.builder(); + + if ($generatorCommon.isDefinedAndNotEmpty(cluster.failoverSpi) && _.findIndex(cluster.failoverSpi, function(spi) { + return $generatorCommon.isDefinedAndNotEmpty(spi.kind) && (spi.kind !== 'Custom' || $generatorCommon.isDefinedAndNotEmpty(_.get(spi, spi.kind + '.class'))); + }) >= 0) { + res.startBlock('<property name="failoverSpi">'); + res.startBlock('<list>'); + + _.forEach(cluster.failoverSpi, function(spi) { + if (spi.kind && (spi.kind !== 'Custom' || $generatorCommon.isDefinedAndNotEmpty(_.get(spi, spi.kind + '.class')))) { + const maxAttempts = _.get(spi, spi.kind + '.maximumFailoverAttempts'); + + if ((spi.kind === 'JobStealing' || spi.kind === 'Always') && $generatorCommon.isDefinedAndNotEmpty(maxAttempts) && maxAttempts !== 5) { + res.startBlock('<bean class="' + $generatorCommon.failoverSpiClass(spi) + '">'); + + $generatorXml.property(res, spi[spi.kind], 'maximumFailoverAttempts', null, 5); + + res.endBlock('</bean>'); + } + else + res.line('<bean class="' + $generatorCommon.failoverSpiClass(spi) + '"/>'); + + res.needEmptyLine = true; + } + }); + + res.needEmptyLine = true; + + res.endBlock('</list>'); + res.endBlock('</property>'); + } + + return res; +}; + +// Generate marshaller group. +$generatorXml.clusterLogger = function(logger, res) { + if (!res) + res = $generatorCommon.builder(); + + if ($generatorCommon.loggerConfigured(logger)) { + res.startBlock('<property name="gridLogger">'); + + const log = logger[logger.kind]; + + switch (logger.kind) { + case 'Log4j2': + res.startBlock('<bean class="org.apache.ignite.logger.log4j2.Log4J2Logger">'); + res.line('<constructor-arg value="' + $generatorXml.escape(log.path) + '"/>'); + $generatorXml.property(res, log, 'level'); + res.endBlock('</bean>'); + + break; + + case 'Null': + res.line('<bean class="org.apache.ignite.logger.NullLogger"/>'); + + break; + + case 'Java': + res.line('<bean class="org.apache.ignite.logger.java.JavaLogger"/>'); + + break; + + case 'JCL': + res.line('<bean class="org.apache.ignite.logger.jcl.JclLogger"/>'); + + break; + + case 'SLF4J': + res.line('<bean class="org.apache.ignite.logger.slf4j.Slf4jLogger"/>'); + + break; + + case 'Log4j': + if (log.mode === 'Default' && !$generatorCommon.isDefinedAndNotEmpty(log.level)) + res.line('<bean class="org.apache.ignite.logger.log4j.Log4JLogger"/>'); + else { + res.startBlock('<bean class="org.apache.ignite.logger.log4j.Log4JLogger">'); + + if (log.mode === 'Path') + res.line('<constructor-arg value="' + $generatorXml.escape(log.path) + '"/>'); + + $generatorXml.property(res, log, 'level'); + res.endBlock('</bean>'); + } + + break; + + case 'Custom': + res.line('<bean class="' + log.class + '"/>'); + + break; + + default: + } + + res.endBlock('</property>'); + + res.needEmptyLine = true; + } + + return res; +}; + // Generate marshaller group. -$generatorXml.clusterMarshaller = function (cluster, res) { +$generatorXml.clusterMarshaller = function(cluster, res) { if (!res) res = $generatorCommon.builder(); - var marshaller = cluster.marshaller; + const marshaller = cluster.marshaller; if (marshaller && marshaller.kind) $generatorXml.beanProperty(res, marshaller[marshaller.kind], 'marshaller', $generatorCommon.MARSHALLERS[marshaller.kind], true); @@ -742,7 +923,7 @@ $generatorXml.clusterMarshaller = function (cluster, res) { }; // Generate metrics group. -$generatorXml.clusterMetrics = function (cluster, res) { +$generatorXml.clusterMetrics = function(cluster, res) { if (!res) res = $generatorCommon.builder(); @@ -757,7 +938,7 @@ $generatorXml.clusterMetrics = function (cluster, res) { }; // Generate swap group. -$generatorXml.clusterSwap = function (cluster, res) { +$generatorXml.clusterSwap = function(cluster, res) { if (!res) res = $generatorCommon.builder(); @@ -772,7 +953,7 @@ $generatorXml.clusterSwap = function (cluster, res) { }; // Generate time group. -$generatorXml.clusterTime = function (cluster, res) { +$generatorXml.clusterTime = function(cluster, res) { if (!res) res = $generatorCommon.builder(); @@ -787,7 +968,7 @@ $generatorXml.clusterTime = function (cluster, res) { }; // Generate thread pools group. -$generatorXml.clusterPools = function (cluster, res) { +$generatorXml.clusterPools = function(cluster, res) { if (!res) res = $generatorCommon.builder(); @@ -803,7 +984,7 @@ $generatorXml.clusterPools = function (cluster, res) { }; // Generate transactions group. -$generatorXml.clusterTransactions = function (transactionConfiguration, res) { +$generatorXml.clusterTransactions = function(transactionConfiguration, res) { if (!res) res = $generatorCommon.builder(); @@ -814,6 +995,28 @@ $generatorXml.clusterTransactions = function (transactionConfiguration, res) { return res; }; +// Generate user attributes group. +$generatorXml.clusterUserAttributes = function(cluster, res) { + if (!res) + res = $generatorCommon.builder(); + + if ($generatorCommon.isDefinedAndNotEmpty(cluster.attributes)) { + res.startBlock('<property name="userAttributes">'); + res.startBlock('<map>'); + + _.forEach(cluster.attributes, function(attr) { + $generatorXml.element(res, 'entry', 'key', attr.name, 'value', attr.value); + }); + + res.endBlock('</map>'); + res.endBlock('</property>'); + } + + res.needEmptyLine = true; + + return res; +}; + /** * XML generator for cluster's SSL configuration. * @@ -904,9 +1107,7 @@ $generatorXml.cacheQuery = function(cache, res) { $generatorXml.property(res, cache, 'sqlOnheapRowCacheSize', null, 10240); $generatorXml.property(res, cache, 'longQueryWarningTimeout', null, 3000); - var indexedTypes = _.filter(cache.domains, function (domain) { - return domain.queryMetadata === 'Annotations' - }); + const indexedTypes = _.filter(cache.domains, (domain) => domain.queryMetadata === 'Annotations'); if (indexedTypes.length > 0) { res.startBlock('<property name="indexedTypes">'); @@ -941,9 +1142,9 @@ $generatorXml.cacheStore = function(cache, domains, res) { res = $generatorCommon.builder(); if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) { - var factoryKind = cache.cacheStoreFactory.kind; + const factoryKind = cache.cacheStoreFactory.kind; - var storeFactory = cache.cacheStoreFactory[factoryKind]; + const storeFactory = cache.cacheStoreFactory[factoryKind]; if (storeFactory) { if (factoryKind === 'CacheJdbcPojoStoreFactory') { @@ -956,7 +1157,7 @@ $generatorXml.cacheStore = function(cache, domains, res) { res.line('<bean class="' + $generatorCommon.jdbcDialectClassName(storeFactory.dialect) + '"/>'); res.endBlock('</property>'); - var domainConfigs = _.filter(domains, function (domain) { + const domainConfigs = _.filter(domains, function(domain) { return $generatorCommon.isDefinedAndNotEmpty(domain.databaseTable); }); @@ -964,7 +1165,7 @@ $generatorXml.cacheStore = function(cache, domains, res) { res.startBlock('<property name="types">'); res.startBlock('<list>'); - _.forEach(domainConfigs, function (domain) { + _.forEach(domainConfigs, function(domain) { res.startBlock('<bean class="org.apache.ignite.cache.store.jdbc.JdbcType">'); $generatorXml.property(res, cache, 'name', 'cacheName'); @@ -982,7 +1183,7 @@ $generatorXml.cacheStore = function(cache, domains, res) { } res.endBlock('</bean>'); - res.endBlock("</property>"); + res.endBlock('</property>'); } else if (factoryKind === 'CacheJdbcBlobStoreFactory') { res.startBlock('<property name="cacheStoreFactory">'); @@ -1004,15 +1205,13 @@ $generatorXml.cacheStore = function(cache, domains, res) { $generatorXml.property(res, storeFactory, 'deleteQuery'); res.endBlock('</bean>'); - res.endBlock("</property>"); + res.endBlock('</property>'); } else $generatorXml.beanProperty(res, storeFactory, 'cacheStoreFactory', $generatorCommon.STORE_FACTORIES[factoryKind], true); - if (storeFactory.dataSourceBean && (storeFactory.connectVia ? (storeFactory.connectVia === 'DataSource' ? storeFactory.dialect : undefined) : storeFactory.dialect)) { - if (_.findIndex(res.datasources, function (ds) { - return ds.dataSourceBean === storeFactory.dataSourceBean; - }) < 0) { + if (storeFactory.dataSourceBean && (storeFactory.connectVia ? (storeFactory.connectVia === 'DataSource' ? storeFactory.dialect : null) : storeFactory.dialect)) { + if (_.findIndex(res.datasources, (ds) => ds.dataSourceBean === storeFactory.dataSourceBean) < 0) { res.datasources.push({ dataSourceBean: storeFactory.dataSourceBean, className: $generatorCommon.DATA_SOURCES[storeFactory.dialect], @@ -1053,7 +1252,7 @@ $generatorXml.cacheConcurrency = function(cache, res) { $generatorXml.property(res, cache, 'maxConcurrentAsyncOperations', null, 500); $generatorXml.property(res, cache, 'defaultLockTimeout', null, 0); $generatorXml.property(res, cache, 'atomicWriteOrderMode'); - $generatorXml.property(res, cache, 'writeSynchronizationMode', null, "PRIMARY_SYNC"); + $generatorXml.property(res, cache, 'writeSynchronizationMode', null, 'PRIMARY_SYNC'); res.needEmptyLine = true; @@ -1130,8 +1329,8 @@ $generatorXml.cacheStatistics = function(cache, res) { }; // Generate domain model query fields. -$generatorXml.domainModelQueryFields = function (res, domain) { - var fields = domain.fields; +$generatorXml.domainModelQueryFields = function(res, domain) { + const fields = domain.fields; if (fields && fields.length > 0) { res.emptyLineIfNeeded(); @@ -1139,7 +1338,7 @@ $generatorXml.domainModelQueryFields = function (res, domain) { res.startBlock('<property name="fields">'); res.startBlock('<map>'); - _.forEach(fields, function (field) { + _.forEach(fields, function(field) { $generatorXml.element(res, 'entry', 'key', field.name, 'value', $generatorCommon.JavaTypes.fullClassName(field.className)); }); @@ -1151,8 +1350,8 @@ $generatorXml.domainModelQueryFields = function (res, domain) { }; // Generate domain model query fields. -$generatorXml.domainModelQueryAliases = function (res, domain) { - var aliases = domain.aliases; +$generatorXml.domainModelQueryAliases = function(res, domain) { + const aliases = domain.aliases; if (aliases && aliases.length > 0) { res.emptyLineIfNeeded(); @@ -1160,7 +1359,7 @@ $generatorXml.domainModelQueryAliases = function (res, domain) { res.startBlock('<property name="aliases">'); res.startBlock('<map>'); - _.forEach(aliases, function (alias) { + _.forEach(aliases, function(alias) { $generatorXml.element(res, 'entry', 'key', alias.field, 'value', alias.alias); }); @@ -1172,8 +1371,8 @@ $generatorXml.domainModelQueryAliases = function (res, domain) { }; // Generate domain model indexes. -$generatorXml.domainModelQueryIndexes = function (res, domain) { - var indexes = domain.indexes; +$generatorXml.domainModelQueryIndexes = function(res, domain) { + const indexes = domain.indexes; if (indexes && indexes.length > 0) { res.emptyLineIfNeeded(); @@ -1181,19 +1380,19 @@ $generatorXml.domainModelQueryIndexes = function (res, domain) { res.startBlock('<property name="indexes">'); res.startBlock('<list>'); - _.forEach(indexes, function (index) { + _.forEach(indexes, function(index) { res.startBlock('<bean class="org.apache.ignite.cache.QueryIndex">'); $generatorXml.property(res, index, 'name'); $generatorXml.property(res, index, 'indexType'); - var fields = index.fields; + const fields = index.fields; if (fields && fields.length > 0) { res.startBlock('<property name="fields">'); res.startBlock('<map>'); - _.forEach(fields, function (field) { + _.forEach(fields, function(field) { $generatorXml.element(res, 'entry', 'key', field.name, 'value', field.direction); }); @@ -1212,8 +1411,8 @@ $generatorXml.domainModelQueryIndexes = function (res, domain) { }; // Generate domain model db fields. -$generatorXml.domainModelDatabaseFields = function (res, domain, fieldProp) { - var fields = domain[fieldProp]; +$generatorXml.domainModelDatabaseFields = function(res, domain, fieldProp) { + const fields = domain[fieldProp]; if (fields && fields.length > 0) { res.emptyLineIfNeeded(); @@ -1222,7 +1421,7 @@ $generatorXml.domainModelDatabaseFields = function (res, domain, fieldProp) { res.startBlock('<list>'); - _.forEach(fields, function (field) { + _.forEach(fields, function(field) { res.startBlock('<bean class="org.apache.ignite.cache.store.jdbc.JdbcTypeField">'); $generatorXml.property(res, field, 'databaseFieldName'); @@ -1277,6 +1476,8 @@ $generatorXml.domainModelGeneral = function(domain, res) { $generatorXml.property(res, domain, 'valueType'); break; + + default: } res.needEmptyLine = true; @@ -1341,7 +1542,7 @@ $generatorXml.cacheDomains = function(domains, res) { if (!res) res = $generatorCommon.builder(); - var domainConfigs = _.filter(domains, function (domain) { + const domainConfigs = _.filter(domains, function(domain) { return $generatorCommon.domainQueryMetadata(domain) === 'Configuration' && $generatorCommon.isDefinedAndNotEmpty(domain.fields); }); @@ -1352,7 +1553,7 @@ $generatorXml.cacheDomains = function(domains, res) { res.startBlock('<property name="queryEntities">'); res.startBlock('<list>'); - _.forEach(domainConfigs, function (domain) { + _.forEach(domainConfigs, function(domain) { $generatorXml.cacheQueryMetadata(domain, res); }); @@ -1412,8 +1613,8 @@ $generatorXml.clusterCaches = function(caches, igfss, isSrvCfg, res) { res.needEmptyLine = true; }); - if (isSrvCfg) - _.forEach(igfss, function(igfs) { + if (isSrvCfg) { + _.forEach(igfss, (igfs) => { $generatorXml.cache($generatorCommon.igfsDataCache(igfs), res); res.needEmptyLine = true; @@ -1422,6 +1623,7 @@ $generatorXml.clusterCaches = function(caches, igfss, isSrvCfg, res) { res.needEmptyLine = true; }); + } res.endBlock('</list>'); res.endBlock('</property>'); @@ -1524,21 +1726,21 @@ $generatorXml.igfsSecondFS = function(igfs, res) { res = $generatorCommon.builder(); if (igfs.secondaryFileSystemEnabled) { - var secondFs = igfs.secondaryFileSystem || {}; + const secondFs = igfs.secondaryFileSystem || {}; res.startBlock('<property name="secondaryFileSystem">'); res.startBlock('<bean class="org.apache.ignite.hadoop.fs.IgniteHadoopIgfsSecondaryFileSystem">'); - var nameDefined = $generatorCommon.isDefinedAndNotEmpty(secondFs.userName); - var cfgDefined = $generatorCommon.isDefinedAndNotEmpty(secondFs.cfgPath); + const nameDefined = $generatorCommon.isDefinedAndNotEmpty(secondFs.userName); + const cfgDefined = $generatorCommon.isDefinedAndNotEmpty(secondFs.cfgPath); $generatorXml.constructorArg(res, 0, secondFs, 'uri'); if (cfgDefined || nameDefined) $generatorXml.constructorArg(res, 1, secondFs, 'cfgPath'); - $generatorXml.constructorArg(res, 2, secondFs, 'userName', undefined, true); + $generatorXml.constructorArg(res, 2, secondFs, 'userName', null, true); res.endBlock('</bean>'); res.endBlock('</property>'); @@ -1561,7 +1763,7 @@ $generatorXml.igfsGeneral = function(igfs, res) { $generatorXml.property(res, igfs, 'name'); $generatorXml.property(res, igfs, 'dataCacheName'); $generatorXml.property(res, igfs, 'metaCacheName'); - $generatorXml.property(res, igfs, 'defaultMode', null, "DUAL_ASYNC"); + $generatorXml.property(res, igfs, 'defaultMode', null, 'DUAL_ASYNC'); res.needEmptyLine = true; } @@ -1605,15 +1807,15 @@ $generatorXml.igfsMisc = function(igfs, res) { }; // Generate DataSource beans. -$generatorXml.generateDataSources = function (datasources, res) { +$generatorXml.generateDataSources = function(datasources, res) { if (!res) res = $generatorCommon.builder(); if (datasources.length > 0) { res.line('<!-- Data source beans will be initialized from external properties file. -->'); - _.forEach(datasources, function (item) { - var beanId = item.dataSourceBean; + _.forEach(datasources, function(item) { + const beanId = item.dataSourceBean; res.startBlock('<bean id="' + beanId + '" class="' + item.className + '">'); @@ -1658,8 +1860,8 @@ $generatorXml.generateDataSources = function (datasources, res) { return res; }; -$generatorXml.clusterConfiguration = function (cluster, clientNearCfg, res) { - var isSrvCfg = _.isNil(clientNearCfg); +$generatorXml.clusterConfiguration = function(cluster, clientNearCfg, res) { + const isSrvCfg = _.isNil(clientNearCfg); if (!isSrvCfg) { res.line('<property name="clientMode" value="true"/>'); @@ -1673,6 +1875,8 @@ $generatorXml.clusterConfiguration = function (cluster, clientNearCfg, res) { $generatorXml.clusterBinary(cluster.binaryConfiguration, res); + $generatorXml.clusterCollision(cluster.collision, res); + $generatorXml.clusterCommunication(cluster, res); $generatorXml.clusterConnector(cluster.connector, res); @@ -1681,6 +1885,10 @@ $generatorXml.clusterConfiguration = function (cluster, clientNearCfg, res) { $generatorXml.clusterEvents(cluster, res); + $generatorXml.clusterFailover(cluster, res); + + $generatorXml.clusterLogger(cluster.logger, res); + $generatorXml.clusterMarshaller(cluster, res); $generatorXml.clusterMetrics(cluster, res); @@ -1700,12 +1908,14 @@ $generatorXml.clusterConfiguration = function (cluster, clientNearCfg, res) { if (isSrvCfg) $generatorXml.igfss(cluster.igfss, res); + $generatorXml.clusterUserAttributes(cluster, res); + return res; }; -$generatorXml.cluster = function (cluster, clientNearCfg) { +$generatorXml.cluster = function(cluster, clientNearCfg) { if (cluster) { - var res = $generatorCommon.builder(1); + const res = $generatorCommon.builder(1); if (clientNearCfg) { res.startBlock('<bean id="nearCacheBean" class="org.apache.ignite.configuration.NearCacheConfiguration">'); @@ -1732,7 +1942,7 @@ $generatorXml.cluster = function (cluster, clientNearCfg) { // Build final XML: // 1. Add header. - var xml = '<?xml version="1.0" encoding="UTF-8"?>\n\n'; + let xml = '<?xml version="1.0" encoding="UTF-8"?>\n\n'; xml += '<!-- ' + $generatorCommon.mainComment() + ' -->\n\n'; xml += '<beans xmlns="http://www.springframework.org/schema/beans"\n'; http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/gulpfile.babel.js/tasks/eslint.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/gulpfile.babel.js/tasks/eslint.js b/modules/web-console/src/main/js/gulpfile.babel.js/tasks/eslint.js index cb49c64..2d60037 100644 --- a/modules/web-console/src/main/js/gulpfile.babel.js/tasks/eslint.js +++ b/modules/web-console/src/main/js/gulpfile.babel.js/tasks/eslint.js @@ -22,6 +22,9 @@ import sequence from 'gulp-sequence'; const paths = [ './app/**/*.js', + './controllers/**/*.js', + './generator/**/*.js', + './ignite_modules_temp/**/*.js', './gulpfile.babel.js/**/*.js', './gulpfile.babel.js/*.js' ]; http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/public/images/cluster.png ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/public/images/cluster.png b/modules/web-console/src/main/js/public/images/cluster.png index 1add34d..2d8b860 100644 Binary files a/modules/web-console/src/main/js/public/images/cluster.png and b/modules/web-console/src/main/js/public/images/cluster.png differ http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/public/images/query-table.png ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/public/images/query-table.png b/modules/web-console/src/main/js/public/images/query-table.png index d055125..53becda 100644 Binary files a/modules/web-console/src/main/js/public/images/query-table.png and b/modules/web-console/src/main/js/public/images/query-table.png differ http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/public/stylesheets/style.scss ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/public/stylesheets/style.scss b/modules/web-console/src/main/js/public/stylesheets/style.scss index 589028c..2c047ac 100644 --- a/modules/web-console/src/main/js/public/stylesheets/style.scss +++ b/modules/web-console/src/main/js/public/stylesheets/style.scss @@ -1036,6 +1036,11 @@ button.form-control { border: thin dotted $ignite-border-color; } +.panel-details-noborder { + margin-top: 5px; + padding: 10px 5px; +} + .group { border-radius: 5px; border: thin dotted $ignite-border-color; @@ -1346,6 +1351,7 @@ label.required:after { position: fixed; z-index: 1050; margin: 20px; + max-width: 700px; &.top-right { top: 60px; @@ -2126,3 +2132,25 @@ html,body,.splash-screen { .nvd3 .nv-axis .nv-axisMaxMin text { font-weight: normal; /* Here the text can be modified*/ } + +[ng-hide].ng-hide-add.ng-hide-animate { + display: none; +} + +[ng-show].ng-hide-add.ng-hide-animate { + display: none; +} + +@media only screen and (max-width: 767px) { + .container{ + padding: 0 $padding-small-horizontal; + } +} + +.domains-import-dialog { + .modal-body { + height: 325px; + margin: 0; + padding: 0; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/serve/agent.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/serve/agent.js b/modules/web-console/src/main/js/serve/agent.js index 78dd66f..77da925 100644 --- a/modules/web-console/src/main/js/serve/agent.js +++ b/modules/web-console/src/main/js/serve/agent.js @@ -152,7 +152,7 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, settings, mo const code = res.code; if (code === 401) - return reject(new Error('Agent is failed to authenticate in grid. Please check agent\'s login and password or node port.')); + return reject(new Error('Agent failed to authenticate in grid. Please check agent\'s login and password or node port.')); if (code !== 200) return reject(new Error(error || 'Failed connect to node and execute REST command.')); @@ -164,7 +164,7 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, settings, mo return resolve(msg.response); if (msg.successStatus === 2) - return reject(new Error('Agent is failed to authenticate in grid. Please check agent\'s login and password or node port.')); + return reject(new Error('Agent failed to authenticate in grid. Please check agent\'s login and password or node port.')); reject(new Error(msg.error)); } @@ -331,6 +331,27 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, settings, mo /** * @param {Boolean} demo Is need run command on demo node. + * @param {Array.<String>} nids Node ids. + * @param {Boolean} near true if near cache should be started. + * @param {String} cacheName Name for near cache. + * @param {String} cfg Cache XML configuration. + * @returns {Promise} + */ + cacheStart(demo, nids, near, cacheName, cfg) { + const cmd = new Command(demo, 'exe') + .addParam('name', 'org.apache.ignite.internal.visor.compute.VisorGatewayTask') + .addParam('p1', nids) + .addParam('p2', 'org.apache.ignite.internal.visor.cache.VisorCacheStartTask') + .addParam('p3', 'org.apache.ignite.internal.visor.cache.VisorCacheStartTask$VisorCacheStartArg') + .addParam('p4', near) + .addParam('p5', cacheName) + .addParam('p6', cfg); + + return this.executeRest(cmd); + } + + /** + * @param {Boolean} demo Is need run command on demo node. * @param {String} nid Node id. * @param {String} cacheName Cache name. * @returns {Promise} @@ -349,18 +370,84 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, settings, mo /** * @param {Boolean} demo Is need run command on demo node. * @param {String} nid Node id. + * @param {String} cacheName Cache name. + * @returns {Promise} + */ + cacheResetMetrics(demo, nid, cacheName) { + const cmd = new Command(demo, 'exe') + .addParam('name', 'org.apache.ignite.internal.visor.compute.VisorGatewayTask') + .addParam('p1', nid) + .addParam('p2', 'org.apache.ignite.internal.visor.cache.VisorCacheResetMetricsTask') + .addParam('p3', 'java.lang.String') + .addParam('p4', cacheName); + + return this.executeRest(cmd); + } + + /** + * @param {Boolean} demo Is need run command on demo node. + * @param {String} nid Node id. + * @param {String} cacheNames Cache names separated by comma. * @returns {Promise} */ - ping(demo, nid) { + cacheSwapBackups(demo, nid, cacheNames) { const cmd = new Command(demo, 'exe') .addParam('name', 'org.apache.ignite.internal.visor.compute.VisorGatewayTask') - .addParam('p1', 'null') + .addParam('p1', nid) + .addParam('p2', 'org.apache.ignite.internal.visor.cache.VisorCacheSwapBackupsTask') + .addParam('p3', 'java.util.Set') + .addParam('p4', 'java.lang.String') + .addParam('p5', cacheNames); + + return this.executeRest(cmd); + } + + /** + * @param {Boolean} demo Is need run command on demo node. + * @param {String} nids Node ids. + * @returns {Promise} + */ + gc(demo, nids) { + const cmd = new Command(demo, 'exe') + .addParam('name', 'org.apache.ignite.internal.visor.compute.VisorGatewayTask') + .addParam('p1', nids) + .addParam('p2', 'org.apache.ignite.internal.visor.node.VisorNodeGcTask') + .addParam('p3', 'java.lang.Void'); + + return this.executeRest(cmd); + } + + /** + * @param {Boolean} demo Is need run command on demo node. + * @param {String} taskNid node that is not node we want to ping. + * @param {String} nid Id of the node to ping. + * @returns {Promise} + */ + ping(demo, taskNid, nid) { + const cmd = new Command(demo, 'exe') + .addParam('name', 'org.apache.ignite.internal.visor.compute.VisorGatewayTask') + .addParam('p1', taskNid) .addParam('p2', 'org.apache.ignite.internal.visor.node.VisorNodePingTask') .addParam('p3', 'java.util.UUID') .addParam('p4', nid); return this.executeRest(cmd); } + + /** + * @param {Boolean} demo Is need run command on demo node. + * @param {String} nid Id of the node to get thread dump. + * @returns {Promise} + */ + threadDump(demo, nid) { + const cmd = new Command(demo, 'exe') + .addParam('name', 'org.apache.ignite.internal.visor.compute.VisorGatewayTask') + .addParam('p1', nid) + .addParam('p2', 'org.apache.ignite.internal.visor.debug.VisorThreadDumpTask') + .addParam('p3', 'java.lang.Void'); + + return this.executeRest(cmd); + } } /** @@ -482,66 +569,74 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, settings, mo return cb('You are using an older version of the agent. Please reload agent archive'); } - mongo.Account.findOne({token: data.token}, (err, account) => { - // TODO IGNITE-1379 send error to web master. - if (err) - cb('Failed to authorize user'); - else if (!account) - cb('Invalid token, user not found'); - else { + const tokens = data.tokens; + + mongo.Account.find({token: {$in: tokens}}, '_id token').lean().exec() + .then((accounts) => { + if (!accounts.length) + return cb('Agent is failed to authenticate. Please check agent\'s token(s)'); + const agent = new Agent(socket); - socket.on('disconnect', () => { - this._removeAgent(account._id, agent); - }); + const accountIds = _.map(accounts, (account) => account._id); + + socket.on('disconnect', () => this._agentDisconnected(accountIds, agent)); + + this._agentConnected(accountIds, agent); - this._addAgent(account._id, agent); + const missedTokens = _.difference(tokens, _.map(accounts, (account) => account.token)); + + if (missedTokens.length) { + agent._emit('agent:warning', + `Failed to authenticate with token(s): ${missedTokens.join(', ')}.`); + } cb(); - } - }); + }) + // TODO IGNITE-1379 send error to web master. + .catch((err) => cb('Agent is failed to authenticate. Please check agent\'s tokens')); }); }); } /** - * @param {ObjectId} userId - * @param {Socket} user - * @returns {int} connected agent count. + * @param {ObjectId} accountId + * @param {Socket} socket + * @returns {int} Connected agent count. */ - addAgentListener(userId, user) { - let users = this._browsers[userId]; + addAgentListener(accountId, socket) { + let sockets = this._browsers[accountId]; - if (!users) - this._browsers[userId] = users = []; + if (!sockets) + this._browsers[accountId] = sockets = []; - users.push(user); + sockets.push(socket); - const agents = this._agents[userId]; + const agents = this._agents[accountId]; return agents ? agents.length : 0; } /** - * @param {ObjectId} userId - * @param {Socket} user + * @param {ObjectId} accountId. + * @param {Socket} socket. * @returns {int} connected agent count. */ - removeAgentListener(userId, user) { - const users = this._browsers[userId]; + removeAgentListener(accountId, socket) { + const sockets = this._browsers[accountId]; - _.remove(users, (_user) => _user === user); + _.pull(sockets, socket); } /** - * @param {ObjectId} userId + * @param {ObjectId} accountId * @returns {Promise.<Agent>} */ - findAgent(userId) { + findAgent(accountId) { if (!this._server) return Promise.reject(new Error('Agent server not started yet!')); - const agents = this._agents[userId]; + const agents = this._agents[accountId]; if (!agents || agents.length === 0) return Promise.reject(new Error('Failed to connect to agent')); @@ -551,49 +646,66 @@ module.exports.factory = function(_, ws, fs, path, JSZip, socketio, settings, mo /** * Close connections for all user agents. - * @param {ObjectId} userId + * @param {ObjectId} accountId + * @param {String} oldToken */ - close(userId) { + close(accountId, oldToken) { if (!this._server) return; - const agents = this._agents[userId]; + const agentsForClose = this._agents[accountId]; + + const agentsForWarning = _.clone(agentsForClose); - this._agents[userId] = []; + this._agents[accountId] = []; - for (const agent of agents) - agent._emit('agent:close', 'Security token was changed for user'); + _.forEach(this._agents, (sockets) => _.pullAll(agentsForClose, sockets)); + + _.pullAll(agentsForWarning, agentsForClose); + + const msg = `Security token has been reset: ${oldToken}`; + + _.forEach(agentsForWarning, (socket) => socket._emit('agent:warning', msg)); + + _.forEach(agentsForClose, (socket) => socket._emit('agent:close', msg)); + + _.forEach(this._browsers[accountId], (socket) => socket.emit('agent:count', {count: 0})); } /** - * @param userId + * @param {ObjectId} accountIds * @param {Agent} agent */ - _removeAgent(userId, agent) { - const agents = this._agents[userId]; + _agentConnected(accountIds, agent) { + _.forEach(accountIds, (accountId) => { + let agents = this._agents[accountId]; - _.remove(agents, (_agent) => _agent === agent); + if (!agents) + this._agents[accountId] = agents = []; - const users = this._browsers[userId]; + agents.push(agent); - _.forEach(users, (user) => user.emit('agent:count', {count: agents.length})); + const sockets = this._browsers[accountId]; + + _.forEach(sockets, (socket) => socket.emit('agent:count', {count: agents.length})); + }); } /** - * @param {ObjectId} userId + * @param {ObjectId} accountIds * @param {Agent} agent */ - _addAgent(userId, agent) { - let agents = this._agents[userId]; + _agentDisconnected(accountIds, agent) { + _.forEach(accountIds, (accountId) => { + const agents = this._agents[accountId]; - if (!agents) - this._agents[userId] = agents = []; + if (agents && agents.length) + _.pull(agents, agent); - agents.push(agent); + const sockets = this._browsers[accountId]; - const users = this._browsers[userId]; - - _.forEach(users, (user) => user.emit('agent:count', {count: agents.length})); + _.forEach(sockets, (socket) => socket.emit('agent:count', {count: agents.length})); + }); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/serve/browser.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/serve/browser.js b/modules/web-console/src/main/js/serve/browser.js index 837450d..8a6d33e 100644 --- a/modules/web-console/src/main/js/serve/browser.js +++ b/modules/web-console/src/main/js/serve/browser.js @@ -42,13 +42,15 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { configure.socketio(io); io.sockets.on('connection', (socket) => { - const user = socket.client.request.user; + const user = socket.request.user; - const demo = socket.client.request._query.IgniteDemoMode === 'true'; + const demo = socket.request._query.IgniteDemoMode === 'true'; + + const accountId = () => user._id; // Return available drivers to browser. socket.on('schemaImport:drivers', (cb) => { - agentMgr.findAgent(user._id) + agentMgr.findAgent(accountId()) .then((agent) => agent.availableDrivers()) .then((drivers) => cb(null, drivers)) .catch((err) => cb(_errorToJson(err))); @@ -56,7 +58,7 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { // Return schemas from database to browser. socket.on('schemaImport:schemas', (preset, cb) => { - agentMgr.findAgent(user._id) + agentMgr.findAgent(accountId()) .then((agent) => { const jdbcInfo = {user: preset.user, password: preset.password}; @@ -68,7 +70,7 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { // Return tables from database to browser. socket.on('schemaImport:tables', (preset, cb) => { - agentMgr.findAgent(user._id) + agentMgr.findAgent(accountId()) .then((agent) => { const jdbcInfo = {user: preset.user, password: preset.password}; @@ -81,7 +83,7 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { // Return topology command result from grid to browser. socket.on('node:topology', (attr, mtr, cb) => { - agentMgr.findAgent(user._id) + agentMgr.findAgent(accountId()) .then((agent) => agent.topology(demo, attr, mtr)) .then((clusters) => cb(null, clusters)) .catch((err) => cb(_errorToJson(err))); @@ -89,7 +91,7 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { // Close query on node. socket.on('node:query:close', (queryId, cb) => { - agentMgr.findAgent(user._id) + agentMgr.findAgent(accountId()) .then((agent) => agent.queryClose(demo, queryId)) .then(() => cb()) .catch((err) => cb(_errorToJson(err))); @@ -97,7 +99,7 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { // Execute query on node and return first page to browser. socket.on('node:query', (cacheName, pageSize, query, cb) => { - agentMgr.findAgent(user._id) + agentMgr.findAgent(accountId()) .then((agent) => { if (query === null) return agent.scan(demo, cacheName, pageSize); @@ -110,7 +112,7 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { // Fetch next page for query and return result to browser. socket.on('node:query:fetch', (queryId, pageSize, cb) => { - agentMgr.findAgent(user._id) + agentMgr.findAgent(accountId()) .then((agent) => agent.queryFetch(demo, queryId, pageSize)) .then((res) => cb(null, res)) .catch((err) => cb(_errorToJson(err))); @@ -121,7 +123,7 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { // Set page size for query. const pageSize = 1024; - agentMgr.findAgent(user._id) + agentMgr.findAgent(accountId()) .then((agent) => { const firstPage = query === null ? agent.scan(demo, cacheName, pageSize) : agent.fieldsQuery(demo, cacheName, query, pageSize); @@ -132,7 +134,7 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { return agent.queryFetch(demo, acc.queryId, pageSize) .then((res) => { - acc.rows = acc.rows.concat(res.rows); + acc.items = acc.items.concat(res.items); acc.last = res.last; @@ -149,7 +151,7 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { // Return cache metadata from all nodes in grid. socket.on('node:cache:metadata', (cacheName, cb) => { - agentMgr.findAgent(user._id) + agentMgr.findAgent(accountId()) .then((agent) => agent.metadata(demo, cacheName)) .then((caches) => { let types = []; @@ -159,6 +161,8 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { }; const _typeMapper = (meta, typeName) => { + const maskedName = _.isEmpty(meta.cacheName) ? '<default>' : meta.cacheName; + let fields = meta.fields[typeName]; let columns = []; @@ -173,7 +177,8 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { clazz: fieldClass, system: fieldName === '_KEY' || fieldName === '_VAL', cacheName: meta.cacheName, - typeName + typeName, + maskedName }); } } @@ -190,7 +195,8 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { order: index.descendings.indexOf(field) < 0, unique: index.unique, cacheName: meta.cacheName, - typeName + typeName, + maskedName }); } @@ -200,7 +206,8 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { name: index.name, children: fields, cacheName: meta.cacheName, - typeName + typeName, + maskedName }); } } @@ -213,6 +220,7 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { name: 'Indexes', cacheName: meta.cacheName, typeName, + maskedName, children: indexes }); } @@ -221,6 +229,7 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { type: 'type', cacheName: meta.cacheName || '', typeName, + maskedName, children: columns }; }; @@ -239,7 +248,7 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { // Fetch next page for query and return result to browser. socket.on('node:visor:collect', (evtOrderKey, evtThrottleCntrKey, cb) => { - agentMgr.findAgent(user._id) + agentMgr.findAgent(accountId()) .then((agent) => agent.collect(demo, evtOrderKey, evtThrottleCntrKey)) .then((data) => { if (data.finished) @@ -250,9 +259,35 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { .catch((err) => cb(_errorToJson(err))); }); + // Swap backups specified caches on specified node and return result to browser. + socket.on('node:cache:swap:backups', (nid, cacheNames, cb) => { + agentMgr.findAgent(accountId()) + .then((agent) => agent.cacheSwapBackups(demo, nid, cacheNames)) + .then((data) => { + if (data.finished) + return cb(null, data.result); + + cb(_errorToJson(data.error)); + }) + .catch((err) => cb(_errorToJson(err))); + }); + + // Reset metrics specified cache on specified node and return result to browser. + socket.on('node:cache:reset:metrics', (nid, cacheName, cb) => { + agentMgr.findAgent(accountId()) + .then((agent) => agent.cacheResetMetrics(demo, nid, cacheName)) + .then((data) => { + if (data.finished) + return cb(null, data.result); + + cb(_errorToJson(data.error)); + }) + .catch((err) => cb(_errorToJson(err))); + }); + // Clear specified cache on specified node and return result to browser. socket.on('node:cache:clear', (nid, cacheName, cb) => { - agentMgr.findAgent(user._id) + agentMgr.findAgent(accountId()) .then((agent) => agent.cacheClear(demo, nid, cacheName)) .then((data) => { if (data.finished) @@ -263,10 +298,23 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { .catch((err) => cb(_errorToJson(err))); }); + // Start specified cache and return result to browser. + socket.on('node:cache:start', (nids, near, cacheName, cfg, cb) => { + agentMgr.findAgent(accountId()) + .then((agent) => agent.cacheStart(demo, nids, near, cacheName, cfg)) + .then((data) => { + if (data.finished) + return cb(null, data.result); + + cb(_errorToJson(data.error)); + }) + .catch((err) => cb(_errorToJson(err))); + }); + // Stop specified cache on specified node and return result to browser. - socket.on('node:cache:stop', (nids, cacheName, cb) => { - agentMgr.findAgent(user._id) - .then((agent) => agent.cacheStop(demo, nids, cacheName)) + socket.on('node:cache:stop', (nid, cacheName, cb) => { + agentMgr.findAgent(accountId()) + .then((agent) => agent.cacheStop(demo, nid, cacheName)) .then((data) => { if (data.finished) return cb(null, data.result); @@ -278,9 +326,35 @@ module.exports.factory = (_, socketio, agentMgr, configure) => { // Ping node and return result to browser. - socket.on('node:ping', (nid, cb) => { - agentMgr.findAgent(user._id) - .then((agent) => agent.ping(demo, nid)) + socket.on('node:ping', (taskNid, nid, cb) => { + agentMgr.findAgent(accountId()) + .then((agent) => agent.ping(demo, taskNid, nid)) + .then((data) => { + if (data.finished) + return cb(null, data.result); + + cb(_errorToJson(data.error)); + }) + .catch((err) => cb(_errorToJson(err))); + }); + + // GC node and return result to browser. + socket.on('node:gc', (nids, cb) => { + agentMgr.findAgent(accountId()) + .then((agent) => agent.gc(demo, nids)) + .then((data) => { + if (data.finished) + return cb(null, data.result); + + cb(_errorToJson(data.error)); + }) + .catch((err) => cb(_errorToJson(err))); + }); + + // GC node and return result to browser. + socket.on('node:thread:dump', (nid, cb) => { + agentMgr.findAgent(accountId()) + .then((agent) => agent.threadDump(demo, nid)) .then((data) => { if (data.finished) return cb(null, data.result); http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/serve/configure.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/serve/configure.js b/modules/web-console/src/main/js/serve/configure.js index 71f7c8a..9671d66 100644 --- a/modules/web-console/src/main/js/serve/configure.js +++ b/modules/web-console/src/main/js/serve/configure.js @@ -46,6 +46,7 @@ module.exports.factory = function(logger, cookieParser, bodyParser, session, con secret: settings.sessionSecret, resave: false, saveUninitialized: true, + unset: 'destroy', cookie: { expires: new Date(Date.now() + settings.cookieTTL), maxAge: settings.cookieTTL http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/serve/mongo.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/serve/mongo.js b/modules/web-console/src/main/js/serve/mongo.js index 81b4188..8fb0a20 100644 --- a/modules/web-console/src/main/js/serve/mongo.js +++ b/modules/web-console/src/main/js/serve/mongo.js @@ -540,7 +540,63 @@ module.exports.factory = function(deepPopulatePlugin, passportMongo, settings, p trustStoreType: String, trustManagers: [String] }, - rebalanceThreadPoolSize: Number + rebalanceThreadPoolSize: Number, + attributes: [{name: String, value: String}], + collision: { + kind: {type: String, enum: ['Noop', 'PriorityQueue', 'FifoQueue', 'JobStealing', 'Custom']}, + PriorityQueue: { + parallelJobsNumber: Number, + waitingJobsNumber: Number, + priorityAttributeKey: String, + jobPriorityAttributeKey: String, + defaultPriority: Number, + starvationIncrement: Number, + starvationPreventionEnabled: Boolean + }, + FifoQueue: { + parallelJobsNumber: Number, + waitingJobsNumber: Number + }, + JobStealing: { + activeJobsThreshold: Number, + waitJobsThreshold: Number, + messageExpireTime: Number, + maximumStealingAttempts: Number, + stealingEnabled: Boolean, + stealingAttributes: [{name: String, value: String}], + externalCollisionListener: String + }, + Custom: { + class: String + } + }, + failoverSpi: [{ + kind: {type: String, enum: ['JobStealing', 'Never', 'Always', 'Custom']}, + JobStealing: { + maximumFailoverAttempts: Number + }, + Always: { + maximumFailoverAttempts: Number + }, + Custom: { + class: String + } + }], + logger: { + kind: {type: 'String', enum: ['Log4j2', 'Null', 'Java', 'JCL', 'SLF4J', 'Log4j', 'Custom']}, + Log4j2: { + level: {type: String, enum: ['OFF', 'FATAL', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE', 'ALL']}, + path: String + }, + Log4j: { + mode: {type: String, enum: ['Default', 'Path']}, + level: {type: String, enum: ['OFF', 'FATAL', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE', 'ALL']}, + path: String + }, + Custom: { + class: String + } + } }); // Install deep populate plugin. http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/serve/routes/agent.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/serve/routes/agent.js b/modules/web-console/src/main/js/serve/routes/agent.js index 8fd8b75..020b692 100644 --- a/modules/web-console/src/main/js/serve/routes/agent.js +++ b/modules/web-console/src/main/js/serve/routes/agent.js @@ -59,7 +59,7 @@ module.exports.factory = function(_, express, fs, JSZip, settings, agentMgr) { const host = req.hostname.match(/:/g) ? req.hostname.slice(0, req.hostname.indexOf(':')) : req.hostname; - prop.push('token=' + req.user.token); + prop.push('tokens=' + req.user.token); prop.push('server-uri=' + (settings.agent.SSLOptions ? 'https' : 'http') + '://' + host + ':' + settings.agent.port); prop.push('#Uncomment following options if needed:'); prop.push('#node-uri=http://localhost:8080'); @@ -79,4 +79,3 @@ module.exports.factory = function(_, express, fs, JSZip, settings, agentMgr) { resolveFactory(router); }); }; - http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/serve/routes/caches.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/serve/routes/caches.js b/modules/web-console/src/main/js/serve/routes/caches.js index 61a0cfb..ed1f257 100644 --- a/modules/web-console/src/main/js/serve/routes/caches.js +++ b/modules/web-console/src/main/js/serve/routes/caches.js @@ -90,8 +90,8 @@ module.exports.factory = function(_, express, mongo) { return (new mongo.Cache(params)).save() .then((cache) => - mongo.Cluster.update({_id: {$in: clusters}}, {$addToSet: {caches: cacheId}}, {multi: true}).exec() - .then(() => mongo.DomainModel.update({_id: {$in: domains}}, {$addToSet: {caches: cacheId}}, {multi: true}).exec()) + mongo.Cluster.update({_id: {$in: clusters}}, {$addToSet: {caches: cache._id}}, {multi: true}).exec() + .then(() => mongo.DomainModel.update({_id: {$in: domains}}, {$addToSet: {caches: cache._id}}, {multi: true}).exec()) .then(() => res.send(cache._id)) ); }) http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/serve/routes/clusters.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/serve/routes/clusters.js b/modules/web-console/src/main/js/serve/routes/clusters.js index bfe89d3..9d13990 100644 --- a/modules/web-console/src/main/js/serve/routes/clusters.js +++ b/modules/web-console/src/main/js/serve/routes/clusters.js @@ -103,10 +103,10 @@ module.exports.factory = function(_, express, mongo) { return (new mongo.Cluster(params)).save() .then((cluster) => - mongo.Cache.update({_id: {$in: caches}}, {$addToSet: {clusters: clusterId}}, {multi: true}).exec() - .then(() => mongo.Cache.update({_id: {$nin: caches}}, {$pull: {clusters: clusterId}}, {multi: true}).exec()) - .then(() => mongo.Igfs.update({_id: {$in: igfss}}, {$addToSet: {clusters: clusterId}}, {multi: true}).exec()) - .then(() => mongo.Igfs.update({_id: {$nin: igfss}}, {$pull: {clusters: clusterId}}, {multi: true}).exec()) + mongo.Cache.update({_id: {$in: caches}}, {$addToSet: {clusters: cluster._id}}, {multi: true}).exec() + .then(() => mongo.Cache.update({_id: {$nin: caches}}, {$pull: {clusters: cluster._id}}, {multi: true}).exec()) + .then(() => mongo.Igfs.update({_id: {$in: igfss}}, {$addToSet: {clusters: cluster._id}}, {multi: true}).exec()) + .then(() => mongo.Igfs.update({_id: {$nin: igfss}}, {$pull: {clusters: cluster._id}}, {multi: true}).exec()) .then(() => res.send(cluster._id)) ); }) http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/serve/routes/igfs.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/serve/routes/igfs.js b/modules/web-console/src/main/js/serve/routes/igfs.js index 6e5e60c..f590273 100644 --- a/modules/web-console/src/main/js/serve/routes/igfs.js +++ b/modules/web-console/src/main/js/serve/routes/igfs.js @@ -82,7 +82,7 @@ module.exports.factory = function(_, express, mongo) { return (new mongo.Igfs(params)).save() .then((igfs) => - mongo.Cluster.update({_id: {$in: clusters}}, {$addToSet: {igfss: igfsId}}, {multi: true}).exec() + mongo.Cluster.update({_id: {$in: clusters}}, {$addToSet: {igfss: igfs._id}}, {multi: true}).exec() .then(() => res.send(igfs._id)) ); }) http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/serve/routes/profile.js ---------------------------------------------------------------------- diff --git a/modules/web-console/src/main/js/serve/routes/profile.js b/modules/web-console/src/main/js/serve/routes/profile.js index 5e4278f..5563a2b 100644 --- a/modules/web-console/src/main/js/serve/routes/profile.js +++ b/modules/web-console/src/main/js/serve/routes/profile.js @@ -80,13 +80,20 @@ module.exports.factory = function(_, express, mongo, agentMgr) { }) .then((user) => { if (params.token && user.token !== params.token) - agentMgr.close(user._id); + agentMgr.close(user._id, user.token); _.extend(user, params); return user.save(); }) - .then(() => res.sendStatus(200)) + .then((user) => { + const becomeUsed = req.session.viewedUser && req.user.admin; + + if (becomeUsed) + req.session.viewedUser = user; + + res.sendStatus(200); + }) .catch((err) => mongo.handleError(res, err)); });
