You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2016/06/28 13:06:48 UTC

[01/50] [abbrv] ignite git commit: fixed failing test

Repository: ignite
Updated Branches:
  refs/heads/ignite-1232 1c19f7293 -> 4bc9969f8


fixed failing test


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/54bd9237
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/54bd9237
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/54bd9237

Branch: refs/heads/ignite-1232
Commit: 54bd9237021e25390b1039b914d41c17ed6f7a3b
Parents: 351dfae
Author: Sergi Vladykin <se...@gmail.com>
Authored: Sun Jun 19 22:10:02 2016 +0300
Committer: Sergi Vladykin <se...@gmail.com>
Committed: Sun Jun 19 22:10:02 2016 +0300

----------------------------------------------------------------------
 .../processors/query/h2/sql/GridQueryParsingTest.java    | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/54bd9237/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
index ce1f241..9fb5765 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
@@ -292,7 +292,10 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
      * @param sql2 Sql 2.
      */
     private void assertSqlEquals(String sql1, String sql2) {
-        assertEquals(normalizeSql(sql1), normalizeSql(sql2));
+        String nsql1 = normalizeSql(sql1);
+        String nsql2 = normalizeSql(sql2);
+
+        assertEquals(nsql1, nsql2);
     }
 
     /**
@@ -301,7 +304,7 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
     private static String normalizeSql(String sql) {
         return sql.toLowerCase()
             .replaceAll("/\\*(?:.|\r|\n)*?\\*/", " ")
-            .replaceAll("\\s*on\\s+1\\s*=\\s*1\\s*", " ")
+            .replaceAll("\\s*on\\s+1\\s*=\\s*1\\s*", " on true ")
             .replaceAll("\\s+", " ")
             .replaceAll("\\( +", "(")
             .replaceAll(" +\\)", ")")
@@ -314,9 +317,9 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
     private void checkQuery(String qry) throws Exception {
         Prepared prepared = parse(qry);
 
-        GridSqlQueryParser ses = new GridSqlQueryParser();
+        GridSqlQuery gQry = new GridSqlQueryParser().parse(prepared);
 
-        String res = ses.parse(prepared).getSQL();
+        String res = gQry.getSQL();
 
         System.out.println(normalizeSql(res));
 


[36/50] [abbrv] ignite git commit: Ignite Web Console beta2.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/generator/generator-common.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/generator/generator-common.js b/modules/web-console/src/main/js/generator/generator-common.js
index 812fa6a..10bd299 100644
--- a/modules/web-console/src/main/js/generator/generator-common.js
+++ b/modules/web-console/src/main/js/generator/generator-common.js
@@ -19,23 +19,22 @@
 const $generatorCommon = {};
 
 // Add leading zero.
-$generatorCommon.addLeadingZero = function (numberStr, minSize) {
+$generatorCommon.addLeadingZero = function(numberStr, minSize) {
     if (typeof (numberStr) !== 'string')
-        numberStr = '' + numberStr;
+        numberStr = String(numberStr);
 
-    while (numberStr.length < minSize) {
+    while (numberStr.length < minSize)
         numberStr = '0' + numberStr;
-    }
 
     return numberStr;
 };
 
 // Format date to string.
-$generatorCommon.formatDate = function (date) {
-    var dd = $generatorCommon.addLeadingZero(date.getDate(), 2);
-    var mm = $generatorCommon.addLeadingZero(date.getMonth() + 1, 2);
+$generatorCommon.formatDate = function(date) {
+    const dd = $generatorCommon.addLeadingZero(date.getDate(), 2);
+    const mm = $generatorCommon.addLeadingZero(date.getMonth() + 1, 2);
 
-    var yyyy = date.getFullYear();
+    const yyyy = date.getFullYear();
 
     return mm + '/' + dd + '/' + yyyy + ' ' + $generatorCommon.addLeadingZero(date.getHours(), 2) + ':' + $generatorCommon.addLeadingZero(date.getMinutes(), 2);
 };
@@ -46,11 +45,11 @@ $generatorCommon.mainComment = function mainComment() {
 };
 
 // Create result holder with service functions and properties for XML and java code generation.
-$generatorCommon.builder = function (deep) {
+$generatorCommon.builder = function(deep) {
     if (_.isNil($generatorCommon.JavaTypes))
         $generatorCommon.JavaTypes = angular.element(document.getElementById('app')).injector().get('JavaTypes');
 
-    var res = [];
+    const res = [];
 
     res.deep = deep || 0;
     res.needEmptyLine = false;
@@ -66,7 +65,7 @@ $generatorCommon.builder = function (deep) {
     res.safeDatasources = [];
     res.safePoint = -1;
 
-    res.mergeProps = function (fromRes) {
+    res.mergeProps = function(fromRes) {
         if ($generatorCommon.isDefinedAndNotEmpty(fromRes)) {
             res.datasources = fromRes.datasources;
 
@@ -76,18 +75,18 @@ $generatorCommon.builder = function (deep) {
         }
     };
 
-    res.mergeLines = function (fromRes) {
+    res.mergeLines = function(fromRes) {
         if ($generatorCommon.isDefinedAndNotEmpty(fromRes)) {
             if (res.needEmptyLine)
                 res.push('');
 
-            _.forEach(fromRes, function (line) {
+            _.forEach(fromRes, function(line) {
                 res.append(line);
             });
         }
     };
 
-    res.startSafeBlock = function () {
+    res.startSafeBlock = function() {
         res.safeDeep = this.deep;
         this.safeNeedEmptyLine = this.needEmptyLine;
         this.safeImports = _.cloneDeep(this.imports);
@@ -96,7 +95,7 @@ $generatorCommon.builder = function (deep) {
         this.safePoint = this.length;
     };
 
-    res.rollbackSafeBlock = function () {
+    res.rollbackSafeBlock = function() {
         if (this.safePoint >= 0) {
             this.splice(this.safePoint, this.length - this.safePoint);
 
@@ -110,16 +109,16 @@ $generatorCommon.builder = function (deep) {
     };
 
     res.asString = function() {
-      return this.join('\n');
+        return this.join('\n');
     };
 
-    res.append = function (s) {
+    res.append = function(s) {
         this.push((this.lineStart ? _.repeat('    ', this.deep) : '') + s);
 
         return this;
     };
 
-    res.line = function (s) {
+    res.line = function(s) {
         if (s) {
             if (res.needEmptyLine)
                 res.push('');
@@ -134,7 +133,7 @@ $generatorCommon.builder = function (deep) {
         return res;
     };
 
-    res.startBlock = function (s) {
+    res.startBlock = function(s) {
         if (s) {
             if (this.needEmptyLine)
                 this.push('');
@@ -151,7 +150,7 @@ $generatorCommon.builder = function (deep) {
         return this;
     };
 
-    res.endBlock = function (s) {
+    res.endBlock = function(s) {
         this.deep--;
 
         if (s)
@@ -162,11 +161,11 @@ $generatorCommon.builder = function (deep) {
         return this;
     };
 
-    res.softEmptyLine = function () {
+    res.softEmptyLine = function() {
         this.needEmptyLine = this.length > 0;
     };
 
-    res.emptyLineIfNeeded = function () {
+    res.emptyLineIfNeeded = function() {
         if (this.needEmptyLine) {
             this.push('');
             this.lineStart = true;
@@ -181,15 +180,15 @@ $generatorCommon.builder = function (deep) {
      * @param clsName Full class name.
      * @returns {String} Short class name or full class name in case of names conflict.
      */
-    res.importClass = function (clsName) {
+    res.importClass = function(clsName) {
         if ($generatorCommon.JavaTypes.isJavaPrimitive(clsName))
             return clsName;
 
-        var fullClassName = $generatorCommon.JavaTypes.fullClassName(clsName);
+        const fullClassName = $generatorCommon.JavaTypes.fullClassName(clsName);
 
-        var dotIdx = fullClassName.lastIndexOf('.');
+        const dotIdx = fullClassName.lastIndexOf('.');
 
-        var shortName = dotIdx > 0 ? fullClassName.substr(dotIdx + 1) : fullClassName;
+        const shortName = dotIdx > 0 ? fullClassName.substr(dotIdx + 1) : fullClassName;
 
         if (this.imports[shortName]) {
             if (this.imports[shortName] !== fullClassName)
@@ -207,10 +206,10 @@ $generatorCommon.builder = function (deep) {
      * @param member Static member.
      * @returns {String} Short class name or full class name in case of names conflict.
      */
-    res.importStatic = function (member) {
-        var dotIdx = member.lastIndexOf('.');
+    res.importStatic = function(member) {
+        const dotIdx = member.lastIndexOf('.');
 
-        var shortName = dotIdx > 0 ? member.substr(dotIdx + 1) : member;
+        const shortName = dotIdx > 0 ? member.substr(dotIdx + 1) : member;
 
         if (this.staticImports[shortName]) {
             if (this.staticImports[shortName] !== member)
@@ -225,33 +224,33 @@ $generatorCommon.builder = function (deep) {
     /**
      * @returns String with "java imports" section.
      */
-    res.generateImports = function () {
-        var res = [];
+    res.generateImports = function() {
+        const genImports = [];
 
-        for (var clsName in this.imports) {
+        for (const clsName in this.imports) {
             if (this.imports.hasOwnProperty(clsName) && this.imports[clsName].lastIndexOf('java.lang.', 0) !== 0)
-                res.push('import ' + this.imports[clsName] + ';');
+                genImports.push('import ' + this.imports[clsName] + ';');
         }
 
-        res.sort();
+        genImports.sort();
 
-        return res.join('\n');
+        return genImports.join('\n');
     };
 
     /**
      * @returns String with "java imports" section.
      */
-    res.generateStaticImports = function () {
-        var res = [];
+    res.generateStaticImports = function() {
+        const statImports = [];
 
-        for (var clsName in this.staticImports) {
+        for (const clsName in this.staticImports) {
             if (this.staticImports.hasOwnProperty(clsName) && this.staticImports[clsName].lastIndexOf('java.lang.', 0) !== 0)
-                res.push('import static ' + this.staticImports[clsName] + ';');
+                statImports.push('import static ' + this.staticImports[clsName] + ';');
         }
 
-        res.sort();
+        statImports.sort();
 
-        return res.join('\n');
+        return statImports.join('\n');
     };
 
     return res;
@@ -298,7 +297,7 @@ $generatorCommon.JDBC_DIALECTS = {
 
 // Return JDBC dialect full class name for specified database.
 $generatorCommon.jdbcDialectClassName = function(db) {
-    var dialectClsName = $generatorCommon.JDBC_DIALECTS[db];
+    const dialectClsName = $generatorCommon.JDBC_DIALECTS[db];
 
     return dialectClsName ? dialectClsName : 'Unknown database: ' + db;
 };
@@ -338,7 +337,7 @@ $generatorCommon.DATA_SOURCES = {
 
 // Return data source full class name for specified database.
 $generatorCommon.dataSourceClassName = function(db) {
-    var dsClsName = $generatorCommon.DATA_SOURCES[db];
+    const dsClsName = $generatorCommon.DATA_SOURCES[db];
 
     return dsClsName ? dsClsName : 'Unknown database: ' + db;
 };
@@ -490,22 +489,22 @@ $generatorCommon.IGFS_IPC_CONFIGURATION = {
 };
 
 // Check that cache has datasource.
-$generatorCommon.cacheHasDatasource = function (cache) {
+$generatorCommon.cacheHasDatasource = function(cache) {
     if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) {
-        var storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind];
+        const storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind];
 
-        return !!(storeFactory && (storeFactory.connectVia ? (storeFactory.connectVia === 'DataSource' ? storeFactory.dialect : false) : storeFactory.dialect));
+        return !!(storeFactory && (storeFactory.connectVia ? (storeFactory.connectVia === 'DataSource' ? storeFactory.dialect : false) : storeFactory.dialect)); // eslint-disable-line no-nested-ternary
     }
 
     return false;
 };
 
-$generatorCommon.secretPropertiesNeeded = function (cluster) {
+$generatorCommon.secretPropertiesNeeded = function(cluster) {
     return !_.isNil(_.find(cluster.caches, $generatorCommon.cacheHasDatasource)) || cluster.sslEnabled;
 };
 
 // Check that binary is configured.
-$generatorCommon.binaryIsDefined = function (binary) {
+$generatorCommon.binaryIsDefined = function(binary) {
     return binary && ($generatorCommon.isDefinedAndNotEmpty(binary.idMapper) || $generatorCommon.isDefinedAndNotEmpty(binary.nameMapper) ||
         $generatorCommon.isDefinedAndNotEmpty(binary.serializer) || $generatorCommon.isDefinedAndNotEmpty(binary.typeConfigurations) ||
         (!_.isNil(binary.compactFooter) && !binary.compactFooter));
@@ -521,7 +520,7 @@ $generatorCommon.domainQueryMetadata = function(domain) {
  * @param {Array<String>} props Array of properties names.
  * @returns {boolean} 'true' if
  */
-$generatorCommon.hasAtLeastOneProperty = function (obj, props) {
+$generatorCommon.hasAtLeastOneProperty = function(obj, props) {
     return obj && props && _.findIndex(props, (prop) => !_.isNil(obj[prop])) >= 0;
 };
 
@@ -532,8 +531,8 @@ $generatorCommon.hasAtLeastOneProperty = function (obj, props) {
  * @param name to convert.
  * @returns {string} Valid java name.
  */
-$generatorCommon.toJavaName = function (prefix, name) {
-    var javaName = name ? name.replace(/[^A-Za-z_0-9]+/g, '_') : 'dflt';
+$generatorCommon.toJavaName = function(prefix, name) {
+    const javaName = name ? name.replace(/[^A-Za-z_0-9]+/g, '_') : 'dflt';
 
     return prefix + javaName.charAt(0).toLocaleUpperCase() + javaName.slice(1);
 };
@@ -542,8 +541,8 @@ $generatorCommon.toJavaName = function (prefix, name) {
  * @param v Value to check.
  * @returns {boolean} 'true' if value defined and not empty string.
  */
-$generatorCommon.isDefinedAndNotEmpty = function (v) {
-    var defined = !_.isNil(v);
+$generatorCommon.isDefinedAndNotEmpty = function(v) {
+    let defined = !_.isNil(v);
 
     if (defined && (_.isString(v) || _.isArray(v)))
         defined = v.length > 0;
@@ -556,8 +555,8 @@ $generatorCommon.isDefinedAndNotEmpty = function (v) {
  * @param {Array<String>} props Properties names.
  * @returns {boolean} 'true' if object contains at least one from specified properties.
  */
-$generatorCommon.hasProperty = function (obj, props) {
-    for (var propName in props) {
+$generatorCommon.hasProperty = function(obj, props) {
+    for (const propName in props) {
         if (props.hasOwnProperty(propName)) {
             if (obj[propName])
                 return true;
@@ -567,4 +566,46 @@ $generatorCommon.hasProperty = function (obj, props) {
     return false;
 };
 
+/**
+ * Get class for selected implementation of Failover SPI.
+ *
+ * @param spi Failover SPI configuration.
+ * @returns {*} Class for selected implementation of Failover SPI.
+ */
+$generatorCommon.failoverSpiClass = function(spi) {
+    switch (spi.kind) {
+        case 'JobStealing': return 'org.apache.ignite.spi.failover.jobstealing.JobStealingFailoverSpi';
+        case 'Never': return 'org.apache.ignite.spi.failover.never.NeverFailoverSpi';
+        case 'Always': return 'org.apache.ignite.spi.failover.always.AlwaysFailoverSpi';
+        case 'Custom': return _.get(spi, 'Custom.class');
+        default: return 'Unknown';
+    }
+};
+
+$generatorCommon.loggerConfigured = function(logger) {
+    if (logger && logger.kind) {
+        const log = logger[logger.kind];
+
+        switch (logger.kind) {
+            case 'Log4j2': return log && $generatorCommon.isDefinedAndNotEmpty(log.path);
+
+            case 'Log4j':
+                if (!log || !log.mode)
+                    return false;
+
+                if (log.mode === 'Path')
+                    return $generatorCommon.isDefinedAndNotEmpty(log.path);
+
+                return true;
+
+            case 'Custom': return log && $generatorCommon.isDefinedAndNotEmpty(log.class);
+
+            default:
+                return true;
+        }
+    }
+
+    return false;
+};
+
 export default $generatorCommon;


[50/50] [abbrv] ignite git commit: Merge remote-tracking branch 'remotes/origin/master' into ignite-1232

Posted by sb...@apache.org.
Merge remote-tracking branch 'remotes/origin/master' into ignite-1232

# Conflicts:
#	modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
#	modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoPolicy.java
#	modules/core/src/main/java/org/apache/ignite/internal/processors/closure/GridClosureProcessor.java
#	modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsIpcHandler.java
#	modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
#	modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2AbstractKeyValueRow.java
#	modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
#	modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
#	modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuerySplitter.java
#	modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4bc9969f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4bc9969f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4bc9969f

Branch: refs/heads/ignite-1232
Commit: 4bc9969f88d2a386bd1dfa43710d55354dfdf9ef
Parents: bc1902b
Author: sboikov <sb...@gridgain.com>
Authored: Tue Jun 28 16:06:18 2016 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Tue Jun 28 16:06:18 2016 +0300

----------------------------------------------------------------------
 .../communication/GridIoMessageFactory.java     |  2 +-
 .../closure/GridClosureProcessor.java           |  9 ----
 .../query/h2/opt/GridH2IndexBase.java           | 12 ++---
 .../h2/twostep/msg/GridH2IndexRangeRequest.java |  2 +-
 .../twostep/msg/GridH2IndexRangeResponse.java   |  2 +-
 .../h2/twostep/msg/GridH2QueryRequest.java      |  2 +-
 .../query/h2/twostep/msg/GridH2RowMessage.java  |  2 +-
 .../query/h2/twostep/msg/GridH2RowRange.java    |  2 +-
 .../h2/twostep/msg/GridH2RowRangeBounds.java    |  2 +-
 .../twostep/msg/GridH2ValueMessageFactory.java  | 12 ++---
 .../query/IgniteSqlSplitterSelfTest.java        |  8 +--
 .../IgniteCacheQuerySelfTestSuite.java          | 52 +-------------------
 .../IgniteCacheQuerySelfTestSuite2.java         | 10 ----
 13 files changed, 23 insertions(+), 94 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
index cd557f0..1eebfd4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
@@ -752,7 +752,7 @@ public class GridIoMessageFactory implements MessageFactory {
 
             // [-3..119] [124] - this
             // [120..123] - DR
-            // [-4..-28] - SQL
+            // [-4..-22, -30..-35] - SQL
             default:
                 if (ext != null) {
                     for (MessageFactory factory : ext) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/core/src/main/java/org/apache/ignite/internal/processors/closure/GridClosureProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/closure/GridClosureProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/closure/GridClosureProcessor.java
index a1213d6..a4559c8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/closure/GridClosureProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/closure/GridClosureProcessor.java
@@ -90,15 +90,6 @@ public class GridClosureProcessor extends GridProcessorAdapter {
     /** Ignite version in which binarylizable versions of closures were introduced. */
     public static final IgniteProductVersion BINARYLIZABLE_CLOSURES_SINCE = IgniteProductVersion.fromString("1.6.0");
 
-    /** */
-    private final Executor sysPool;
-
-    /** */
-    private final Executor pubPool;
-
-    /** */
-    private final Executor igfsPool;
-
     /** Lock to control execution after stop. */
     private final GridSpinReadWriteLock busyLock = new GridSpinReadWriteLock();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
index 962946a..109f238 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
@@ -199,11 +199,7 @@ public abstract class GridH2IndexBase extends BaseIndex {
      * @return Filtered iterator.
      */
     protected Iterator<GridH2Row> filter(Iterator<GridH2Row> iter, IndexingQueryFilter filter) {
-        IgniteBiPredicate<Object, Object> p = null;
-
-        IndexingQueryFilter f = filters.get();
-
-        return new FilteringIterator(iter, U.currentTimeMillis(), f);
+        return new FilteringIterator(iter, U.currentTimeMillis(), filter, getTable().spaceName());
     }
 
     /**
@@ -266,15 +262,17 @@ public abstract class GridH2IndexBase extends BaseIndex {
         /**
          * @param iter Iterator.
          * @param time Time for expired rows filtering.
+         * @param qryFilter Filter.
+         * @param spaceName Space name.
          */
         protected FilteringIterator(Iterator<GridH2Row> iter, long time,
-            IndexingQueryFilter qryFilter) {
+            IndexingQueryFilter qryFilter, String spaceName) {
             super(iter);
 
             this.time = time;
 
             if (qryFilter != null) {
-                this.fltr = qryFilter.forSpace(((GridH2Table)getTable()).spaceName());
+                this.fltr = qryFilter.forSpace(spaceName);
 
                 this.isValRequired = qryFilter.isValueRequired();
             } else {

http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2IndexRangeRequest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2IndexRangeRequest.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2IndexRangeRequest.java
index 075f50d28..e49c48f 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2IndexRangeRequest.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2IndexRangeRequest.java
@@ -188,7 +188,7 @@ public class GridH2IndexRangeRequest implements Message {
 
     /** {@inheritDoc} */
     @Override public byte directType() {
-        return -23;
+        return -30;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2IndexRangeResponse.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2IndexRangeResponse.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2IndexRangeResponse.java
index f557a35..c6414bd 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2IndexRangeResponse.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2IndexRangeResponse.java
@@ -259,7 +259,7 @@ public class GridH2IndexRangeResponse implements Message {
 
     /** {@inheritDoc} */
     @Override public byte directType() {
-        return -24;
+        return -31;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java
index e8d97b3..3b200c5 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2QueryRequest.java
@@ -381,7 +381,7 @@ public class GridH2QueryRequest implements Message, GridCacheQueryMarshallable {
 
     /** {@inheritDoc} */
     @Override public byte directType() {
-        return -26;
+        return -33;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowMessage.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowMessage.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowMessage.java
index 2100847..59c548d 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowMessage.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowMessage.java
@@ -96,7 +96,7 @@ public class GridH2RowMessage implements Message {
 
     /** {@inheritDoc} */
     @Override public byte directType() {
-        return -25;
+        return -32;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowRange.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowRange.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowRange.java
index b38a44d..374e4b8 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowRange.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowRange.java
@@ -158,7 +158,7 @@ public class GridH2RowRange implements Message {
 
     /** {@inheritDoc} */
     @Override public byte directType() {
-        return -27;
+        return -34;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowRangeBounds.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowRangeBounds.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowRangeBounds.java
index 2dd1e34..e32e449 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowRangeBounds.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2RowRangeBounds.java
@@ -168,7 +168,7 @@ public class GridH2RowRangeBounds implements Message {
 
     /** {@inheritDoc} */
     @Override public byte directType() {
-        return -28;
+        return -35;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2ValueMessageFactory.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2ValueMessageFactory.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2ValueMessageFactory.java
index ac9710b..aa84e4b 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2ValueMessageFactory.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/msg/GridH2ValueMessageFactory.java
@@ -91,22 +91,22 @@ public class GridH2ValueMessageFactory implements MessageFactory {
             case -22:
                 return new GridH2CacheObject();
 
-            case -23:
+            case -30:
                 return new GridH2IndexRangeRequest();
 
-            case -24:
+            case -31:
                 return new GridH2IndexRangeResponse();
 
-            case -25:
+            case -32:
                 return new GridH2RowMessage();
 
-            case -26:
+            case -33:
                 return new GridH2QueryRequest();
 
-            case -27:
+            case -34:
                 return new GridH2RowRange();
 
-            case -28:
+            case -35:
                 return new GridH2RowRangeBounds();
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlSplitterSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlSplitterSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlSplitterSelfTest.java
index f87cb6d..ce4d24b 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlSplitterSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlSplitterSelfTest.java
@@ -216,7 +216,7 @@ public class IgniteSqlSplitterSelfTest extends GridCommonAbstractTest {
      */
     public void testDistributedJoins() throws Exception {
         CacheConfiguration ccfg = cacheConfig("persOrg", true,
-            Integer.class, Person.class, Integer.class, Organization.class);
+            Integer.class, Person2.class, Integer.class, Organization.class);
 
         IgniteCache<Integer, Object> c = ignite(0).getOrCreateCache(ccfg);
 
@@ -309,7 +309,7 @@ public class IgniteSqlSplitterSelfTest extends GridCommonAbstractTest {
         Random rnd = new GridRandom();
 
         for (int i = 0; i < persons; i++) {
-            Person p = new Person();
+            Person2 p = new Person2();
 
             p.name = "Person" + i;
             p.orgId = rnd.nextInt(orgs);
@@ -317,7 +317,7 @@ public class IgniteSqlSplitterSelfTest extends GridCommonAbstractTest {
             c.put(key++, p);
         }
 
-        String select = "select count(*) from Organization o, Person p where p.orgId = o._key";
+        String select = "select count(*) from Organization o, Person2 p where p.orgId = o._key";
 
         String plan = (String)c.query(new SqlFieldsQuery("explain " + select)
             .setDistributedJoins(true).setEnforceJoinOrder(enforceJoinOrder).setPageSize(pageSize))
@@ -491,7 +491,7 @@ public class IgniteSqlSplitterSelfTest extends GridCommonAbstractTest {
         }
     }
 
-    private static class Person implements Serializable {
+    private static class Person2 implements Serializable {
         @QuerySqlField
         int orgId;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index 2c3cb01..c0a3b09 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -26,8 +26,6 @@ import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectFieldsQuery
 import org.apache.ignite.internal.processors.cache.IgniteBinaryWrappedObjectFieldsQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheCollocatedQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheDuplicateEntityConfigurationSelfTest;
-import org.apache.ignite.internal.processors.cache.IgniteCacheFieldsQueryNoDataSelfTest;
-import org.apache.ignite.internal.processors.cache.IgniteCacheJoinQueryTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheLargeResultSelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapEvictQueryTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapIndexScanTest;
@@ -42,10 +40,6 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheQueryMultiThreaded
 import org.apache.ignite.internal.processors.cache.IgniteCacheQueryOffheapEvictsMultiThreadedSelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheQueryOffheapMultiThreadedSelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheSqlQueryMultiThreadedSelfTest;
-import org.apache.ignite.internal.processors.cache.IgniteCrossCachesJoinsQueryTest;
-import org.apache.ignite.internal.processors.cache.SqlFieldsQuerySelfTest;
-import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheAtomicFieldsQuerySelfTest;
-import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheAtomicNearEnabledFieldsQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheAtomicNearEnabledQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheAtomicQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheClientQueryReplicatedNodeRestartSelfTest;
@@ -54,59 +48,15 @@ import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheP
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCachePartitionedSnapshotEnabledQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNoRebalanceSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeFailTest;
-import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeRestartDistributedJoinSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeRestartSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeRestartSelfTest2;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQueryP2PDisabledSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.local.IgniteCacheLocalAtomicQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.local.IgniteCacheLocalQuerySelfTest;
-import org.apache.ignite.internal.processors.cache.query.GridCacheSwapScanQuerySelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryCounterPartitionedAtomicTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryCounterPartitionedTxTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryCounterReplicatedAtomicTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryCounterReplicatedTxTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousBatchAckTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousBatchForceServerModeAckTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFactoryFilterTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverAtomicPrimaryWriteOrderOffheapTieredTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverAtomicPrimaryWriteOrderSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverAtomicReplicatedSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverTxOffheapTieredTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverTxReplicatedSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverTxSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryOperationP2PTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryRandomOperationsTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicNearEnabledSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicOffheapTieredTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicOffheapValuesTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicP2PDisabledSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryLocalAtomicSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryLocalSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryPartitionAtomicOneNodeTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryPartitionTxOneNodeTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryPartitionedOnlySelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryPartitionedP2PDisabledSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryPartitionedSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedAtomicOneNodeTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedAtomicSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedTxOneNodeTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedP2PDisabledSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryTxOffheapTieredTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryTxOffheapValuesTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryTxSelfTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.IgniteCacheContinuousQueryClientReconnectTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.IgniteCacheContinuousQueryClientTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.IgniteCacheContinuousQueryClientTxReconnectTest;
-import org.apache.ignite.internal.processors.cache.query.continuous.IgniteCacheContinuousQueryReconnectTest;
 import org.apache.ignite.internal.processors.query.IgniteSqlSchemaIndexingTest;
 import org.apache.ignite.internal.processors.query.IgniteSqlSplitterSelfTest;
 import org.apache.ignite.internal.processors.query.h2.sql.GridQueryParsingTest;
-import org.apache.ignite.internal.processors.query.h2.sql.H2CompareBigQueryDistributedJoinsTest;
-import org.apache.ignite.internal.processors.query.h2.sql.H2CompareBigQueryTest;
-import org.apache.ignite.spi.communication.tcp.GridOrderedMessageCancelSelfTest;
 
 /**
  * Test suite for cache queries.
@@ -128,13 +78,13 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
         // Queries tests.
         suite.addTestSuite(IgniteSqlSplitterSelfTest.class);
         suite.addTestSuite(IgniteSqlSchemaIndexingTest.class);
-        suite.addTestSuite(IgniteCachePartitionedQuerySelfTest.class);
         suite.addTestSuite(GridCacheQueryIndexDisabledSelfTest.class);
         suite.addTestSuite(IgniteCacheQueryLoadSelfTest.class);
         suite.addTestSuite(IgniteCacheLocalQuerySelfTest.class);
         suite.addTestSuite(IgniteCacheLocalAtomicQuerySelfTest.class);
         suite.addTestSuite(IgniteCacheReplicatedQuerySelfTest.class);
         suite.addTestSuite(IgniteCacheReplicatedQueryP2PDisabledSelfTest.class);
+        suite.addTestSuite(IgniteCachePartitionedQuerySelfTest.class);
         suite.addTestSuite(IgniteCachePartitionedSnapshotEnabledQuerySelfTest.class);
         suite.addTestSuite(IgniteCacheAtomicQuerySelfTest.class);
         suite.addTestSuite(IgniteCacheAtomicNearEnabledQuerySelfTest.class);

http://git-wip-us.apache.org/repos/asf/ignite/blob/4bc9969f/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite2.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite2.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite2.java
index e5f4027..7cb1adb 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite2.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite2.java
@@ -40,10 +40,6 @@ import org.apache.ignite.internal.processors.cache.distributed.replicated.Ignite
 import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedFieldsQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.local.IgniteCacheLocalFieldsQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.query.GridCacheSwapScanQuerySelfTest;
-import org.apache.ignite.internal.processors.cache.reducefields.GridCacheReduceFieldsQueryAtomicSelfTest;
-import org.apache.ignite.internal.processors.cache.reducefields.GridCacheReduceFieldsQueryLocalSelfTest;
-import org.apache.ignite.internal.processors.cache.reducefields.GridCacheReduceFieldsQueryPartitionedSelfTest;
-import org.apache.ignite.internal.processors.cache.reducefields.GridCacheReduceFieldsQueryReplicatedSelfTest;
 import org.apache.ignite.internal.processors.query.h2.sql.BaseH2CompareQueryTest;
 import org.apache.ignite.internal.processors.query.h2.sql.H2CompareBigQueryTest;
 import org.apache.ignite.spi.communication.tcp.GridOrderedMessageCancelSelfTest;
@@ -73,12 +69,6 @@ public class IgniteCacheQuerySelfTestSuite2 extends TestSuite {
         suite.addTestSuite(IgniteCachePartitionedFieldsQueryP2PEnabledSelfTest.class);
         suite.addTestSuite(IgniteCacheFieldsQueryNoDataSelfTest.class);
 
-        // Reduce fields queries.
-        suite.addTestSuite(GridCacheReduceFieldsQueryLocalSelfTest.class);
-        suite.addTestSuite(GridCacheReduceFieldsQueryPartitionedSelfTest.class);
-        suite.addTestSuite(GridCacheReduceFieldsQueryAtomicSelfTest.class);
-        suite.addTestSuite(GridCacheReduceFieldsQueryReplicatedSelfTest.class);
-
         suite.addTestSuite(GridCacheQueryIndexingDisabledSelfTest.class);
 
         suite.addTestSuite(GridCacheSwapScanQuerySelfTest.class);


[18/50] [abbrv] ignite git commit: IGNITE-3339 - Fixed entries eviction.

Posted by sb...@apache.org.
IGNITE-3339 - Fixed entries eviction.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/bb7a6728
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/bb7a6728
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/bb7a6728

Branch: refs/heads/ignite-1232
Commit: bb7a6728bbd886677a4e7f0c7ad92161dd51122b
Parents: 8ce29a9
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Wed Jun 22 06:34:57 2016 -0700
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Wed Jun 22 06:42:38 2016 -0700

----------------------------------------------------------------------
 .../distributed/near/GridNearGetFuture.java     |   8 +-
 .../transactions/IgniteTxLocalAdapter.java      |  12 +-
 .../cache/transactions/IgniteTxManager.java     |  16 +-
 .../IgniteCacheTxIteratorSelfTest.java          | 241 +++++++++++++++++++
 .../testsuites/IgniteCacheTestSuite5.java       |   2 +
 5 files changed, 266 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/bb7a6728/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
index 290c08e..b7fcbbd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
@@ -62,8 +62,6 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteUuid;
 import org.jetbrains.annotations.Nullable;
 
-import static org.apache.ignite.transactions.TransactionIsolation.READ_COMMITTED;
-
 /**
  *
  */
@@ -636,7 +634,7 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
             catch (GridCacheEntryRemovedException ignored) {
                 // Retry.
             }
-            catch (GridDhtInvalidPartitionException e) {
+            catch (GridDhtInvalidPartitionException ignored) {
                 return false;
             }
             catch (IgniteCheckedException e) {
@@ -645,7 +643,9 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
                 return false;
             }
             finally {
-                if (dhtEntry != null && (tx == null || (!tx.implicit() && tx.isolation() == READ_COMMITTED)))
+                if (dhtEntry != null)
+                    // Near cache is enabled, so near entry will be enlisted in the transaction.
+                    // Always touch DHT entry in this case.
                     dht.context().evicts().touch(dhtEntry, topVer);
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb7a6728/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
index d51d873..d9aca4a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
@@ -1395,11 +1395,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter implements Ig
                             log.debug("Got removed entry in transaction getAllAsync(..) (will retry): " + key);
                     }
                     finally {
-                        if (cacheCtx.isNear() && entry != null && readCommitted()) {
-                            if (cacheCtx.affinity().belongs(cacheCtx.localNode(), entry.partition(), topVer)) {
-                                if (entry.markObsolete(xidVer))
-                                    cacheCtx.cache().removeEntry(entry);
+                        if (entry != null && readCommitted()) {
+                            if (cacheCtx.isNear()) {
+                                if (cacheCtx.affinity().belongs(cacheCtx.localNode(), entry.partition(), topVer)) {
+                                    if (entry.markObsolete(xidVer))
+                                        cacheCtx.cache().removeEntry(entry);
+                                }
                             }
+                            else
+                                entry.context().evicts().touch(entry, topVer);
                         }
                     }
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb7a6728/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index 4ec280f..e8d20b6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -1236,7 +1236,7 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
      * @param tx Transaction to finish.
      * @param commit {@code True} if transaction is committed, {@code false} if rolled back.
      */
-    public void fastFinishTx(IgniteInternalTx tx, boolean commit) {
+    public void fastFinishTx(GridNearTxLocal tx, boolean commit) {
         assert tx != null;
         assert tx.writeMap().isEmpty();
         assert tx.optimistic() || tx.readMap().isEmpty();
@@ -1247,16 +1247,22 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
             // 1. Notify evictions.
             notifyEvitions(tx);
 
-            // 2. Remove obsolete entries.
+            // 2. Evict near entries.
+            if (!tx.readMap().isEmpty()) {
+                for (IgniteTxEntry entry : tx.readMap().values())
+                    tx.evictNearEntry(entry, false);
+            }
+
+            // 3. Remove obsolete entries.
             removeObsolete(tx);
 
-            // 3. Remove from per-thread storage.
+            // 4. Remove from per-thread storage.
             clearThreadMap(tx);
 
-            // 4. Clear context.
+            // 5. Clear context.
             resetContext();
 
-            // 5. Update metrics.
+            // 6. Update metrics.
             if (!tx.dht() && tx.local()) {
                 if (!tx.system()) {
                     if (commit)

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb7a6728/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheTxIteratorSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheTxIteratorSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheTxIteratorSelfTest.java
new file mode 100644
index 0000000..769a5f6
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheTxIteratorSelfTest.java
@@ -0,0 +1,241 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMemoryMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.eviction.fifo.FifoEvictionPolicy;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.configuration.TransactionConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
+
+import javax.cache.Cache;
+
+/**
+ *
+ */
+public class IgniteCacheTxIteratorSelfTest extends GridCommonAbstractTest {
+    /** */
+    public static final String CACHE_NAME = "testCache";
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        final IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        final TransactionConfiguration txCfg = new TransactionConfiguration();
+
+        txCfg.setDefaultTxIsolation(TransactionIsolation.READ_COMMITTED);
+
+        cfg.setTransactionConfiguration(txCfg);
+
+        return cfg;
+    }
+
+    /**
+     * @return Cache configuration.
+     */
+    private CacheConfiguration<String, TestClass> cacheConfiguration(
+        CacheMode mode,
+        CacheAtomicityMode atomMode,
+        CacheMemoryMode memMode,
+        boolean nearEnabled,
+        boolean useEvictPlc
+    ) {
+        final CacheConfiguration<String, TestClass> ccfg = new CacheConfiguration<>(CACHE_NAME);
+
+        ccfg.setAtomicityMode(atomMode);
+        ccfg.setCacheMode(mode);
+        ccfg.setMemoryMode(memMode);
+        ccfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+
+        if (nearEnabled)
+            ccfg.setNearConfiguration(new NearCacheConfiguration<String, TestClass>());
+
+        if (memMode == CacheMemoryMode.ONHEAP_TIERED && useEvictPlc) {
+            ccfg.setOffHeapMaxMemory(10 * 1024 * 1024);
+            ccfg.setEvictionPolicy(new FifoEvictionPolicy(50));
+        }
+
+        return ccfg;
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    public void testModesSingleNode() throws Exception {
+        checkModes(1);
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    public void testModesMultiNode() throws Exception {
+        checkModes(3);
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    public void checkModes(int gridCnt) throws Exception {
+        startGrids(gridCnt);
+
+        try {
+            for (CacheMode mode : CacheMode.values()) {
+                for (CacheAtomicityMode atomMode : CacheAtomicityMode.values()) {
+                    for (CacheMemoryMode memMode : CacheMemoryMode.values()) {
+                        if (mode == CacheMode.PARTITIONED) {
+                            // Near cache makes sense only for partitioned cache.
+                            checkTxCache(CacheMode.PARTITIONED, atomMode, memMode, true, false);
+                        }
+
+                        if (memMode == CacheMemoryMode.ONHEAP_TIERED)
+                            checkTxCache(mode, atomMode, CacheMemoryMode.ONHEAP_TIERED, false, true);
+
+                        checkTxCache(mode, atomMode, memMode, false, false);
+                    }
+                }
+            }
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void checkTxCache(
+        CacheMode mode,
+        CacheAtomicityMode atomMode,
+        CacheMemoryMode memMode,
+        boolean nearEnabled,
+        boolean useEvicPlc
+    ) throws Exception {
+        final Ignite ignite = grid(0);
+
+        final CacheConfiguration<String, TestClass> ccfg = cacheConfiguration(
+            mode,
+            atomMode,
+            memMode,
+            nearEnabled,
+            useEvicPlc);
+
+        final IgniteCache<String, TestClass> cache = ignite.createCache(ccfg);
+
+        info("Checking cache [mode=" + mode + ", atomMode=" + atomMode + ", memMode=" + memMode +
+            ", near=" + nearEnabled + ']');
+
+        try {
+            for (int i = 0; i < 30; i++) {
+                final TestClass val = new TestClass("data");
+                final String key = "key-" + i;
+
+                cache.put(key, val);
+
+                assertEquals(i + 1, cache.size());
+
+                for (TransactionIsolation iso : TransactionIsolation.values()) {
+                    for (TransactionConcurrency con : TransactionConcurrency.values()) {
+                        try (Transaction transaction = ignite.transactions().txStart(con, iso)) {
+                            assertEquals(val, cache.get(key));
+
+                            transaction.commit();
+                        }
+
+                        int cnt = iterateOverKeys(cache);
+
+                        assertEquals("Failed [con=" + con + ", iso=" + iso + ']', i + 1, cnt);
+
+                        assertEquals("Failed [con=" + con + ", iso=" + iso + ']', i + 1, cache.size());
+                    }
+                }
+            }
+        }
+        finally {
+            grid(0).destroyCache(CACHE_NAME);
+        }
+    }
+
+    /**
+     * @param cache Cache.
+     */
+    @SuppressWarnings("TypeMayBeWeakened")
+    private int iterateOverKeys(final IgniteCache<String, TestClass> cache) {
+        int cnt = 0;
+
+        for (final Cache.Entry<String, TestClass> ignore : cache)
+            cnt++;
+
+        return cnt;
+    }
+
+    /**
+     *
+     */
+    private static class TestClass {
+        /** */
+        private String data;
+
+        /**
+         * @param data Data.
+         */
+        private TestClass(String data) {
+            this.data = data;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean equals(final Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            final TestClass testCls = (TestClass)o;
+
+            return data != null ? data.equals(testCls.data) : testCls.data == null;
+
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int hashCode() {
+            return data != null ? data.hashCode() : 0;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public String toString() {
+            return S.toString(TestClass.class, this);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb7a6728/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
index 41e0ed1..7582f5c 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
@@ -29,6 +29,7 @@ import org.apache.ignite.internal.processors.cache.distributed.CacheLateAffinity
 import org.apache.ignite.internal.processors.cache.distributed.CacheLateAffinityAssignmentNodeJoinValidationTest;
 import org.apache.ignite.internal.processors.cache.distributed.CacheLateAffinityAssignmentTest;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheSyncRebalanceModeSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheTxIteratorSelfTest;
 import org.apache.ignite.internal.processors.cache.store.IgniteCacheWriteBehindNoUpdateSelfTest;
 
 /**
@@ -56,6 +57,7 @@ public class IgniteCacheTestSuite5 extends TestSuite {
         suite.addTestSuite(IgniteCacheSyncRebalanceModeSelfTest.class);
 
         suite.addTest(IgniteCacheReadThroughEvictionsVariationsSuite.suite());
+        suite.addTestSuite(IgniteCacheTxIteratorSelfTest.class);
 
         return suite;
     }


[38/50] [abbrv] ignite git commit: Ignite Web Console beta2.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/controllers/igfs-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/controllers/igfs-controller.js b/modules/web-console/src/main/js/controllers/igfs-controller.js
index 3a0e093..c37d08f 100644
--- a/modules/web-console/src/main/js/controllers/igfs-controller.js
+++ b/modules/web-console/src/main/js/controllers/igfs-controller.js
@@ -20,14 +20,14 @@ import consoleModule from 'controllers/common-module';
 
 consoleModule.controller('igfsController', [
     '$scope', '$http', '$state', '$filter', '$timeout', '$common', '$confirm', '$clone', '$loading', '$cleanup', '$unsavedChangesGuard', '$table',
-    function ($scope, $http, $state, $filter, $timeout, $common, $confirm, $clone, $loading, $cleanup, $unsavedChangesGuard, $table) {
+    function($scope, $http, $state, $filter, $timeout, $common, $confirm, $clone, $loading, $cleanup, $unsavedChangesGuard, $table) {
         $unsavedChangesGuard.install($scope);
 
-        var emptyIgfs = {empty: true};
+        const emptyIgfs = {empty: true};
 
-        var __original_value;
+        let __original_value;
 
-        var blank = {
+        const blank = {
             ipcEndpointConfiguration: {},
             secondaryFileSystem: {}
         };
@@ -43,60 +43,55 @@ consoleModule.controller('igfsController', [
         $scope.widthIsSufficient = $common.widthIsSufficient;
         $scope.saveBtnTipText = $common.saveBtnTipText;
 
-        // TODO LEGACY start
-        $scope.tableSave = function (field, index, stopEdit) {
-            switch (field.type) {
-                case 'pathModes':
-                    if ($table.tablePairSaveVisible(field, index))
-                        return $table.tablePairSave($scope.tablePairValid, $scope.backupItem, field, index, stopEdit);
+        const showPopoverMessage = $common.showPopoverMessage;
 
-                    break;
-            }
+        // TODO LEGACY start
+        $scope.tableSave = function(field, index, stopEdit) {
+            if (field.type === 'pathModes' && $table.tablePairSaveVisible(field, index))
+                return $table.tablePairSave($scope.tablePairValid, $scope.backupItem, field, index, stopEdit);
 
             return true;
         };
 
-        $scope.tableReset = function (save) {
-            var field = $table.tableField();
+        $scope.tableReset = (trySave) => {
+            const field = $table.tableField();
 
-            if (!save || !$common.isDefined(field) || $scope.tableSave(field, $table.tableEditedRowIndex(), true)) {
-                $table.tableReset();
+            if (trySave && $common.isDefined(field) && !$scope.tableSave(field, $table.tableEditedRowIndex(), true))
+                return false;
 
-                return true;
-            }
+            $table.tableReset();
 
-            return false;
+            return true;
         };
 
-        $scope.tableNewItem = function (field) {
+        $scope.tableNewItem = function(field) {
             if ($scope.tableReset(true))
                 $table.tableNewItem(field);
         };
 
         $scope.tableNewItemActive = $table.tableNewItemActive;
 
-        $scope.tableStartEdit = function (item, field, index) {
+        $scope.tableStartEdit = function(item, field, index) {
             if ($scope.tableReset(true))
                 $table.tableStartEdit(item, field, index, $scope.tableSave);
         };
 
         $scope.tableEditing = $table.tableEditing;
-
         $scope.tablePairSave = $table.tablePairSave;
         $scope.tablePairSaveVisible = $table.tablePairSaveVisible;
 
-        $scope.tableRemove = function (item, field, index) {
+        $scope.tableRemove = function(item, field, index) {
             if ($scope.tableReset(true))
                 $table.tableRemove(item, field, index);
         };
 
-        $scope.tablePairValid = function (item, field, index) {
-            var pairValue = $table.tablePairValue(field, index);
+        $scope.tablePairValid = function(item, field, index) {
+            const pairValue = $table.tablePairValue(field, index);
 
-            var model = item[field.model];
+            const model = item[field.model];
 
             if ($common.isDefined(model)) {
-                var idx = _.findIndex(model, function (pair) {
+                const idx = _.findIndex(model, function(pair) {
                     return pair.path === pairValue.key;
                 });
 
@@ -108,18 +103,26 @@ consoleModule.controller('igfsController', [
             return true;
         };
 
+        $scope.tblPathModes = {
+            type: 'pathModes',
+            model: 'pathModes',
+            focusId: 'PathMode',
+            ui: 'table-pair',
+            keyName: 'path',
+            valueName: 'mode',
+            save: $scope.tableSave
+        };
+
         $scope.igfsModes = $common.mkOptions(['PRIMARY', 'PROXY', 'DUAL_SYNC', 'DUAL_ASYNC']);
         // TODO LEGACY start - end
 
-        var showPopoverMessage = $common.showPopoverMessage;
-
-        $scope.contentVisible = function () {
-            var item = $scope.backupItem;
+        $scope.contentVisible = function() {
+            const item = $scope.backupItem;
 
             return !item.empty && (!item._id || _.find($scope.displayedRows, {_id: item._id}));
         };
 
-        $scope.toggleExpanded = function () {
+        $scope.toggleExpanded = function() {
             $scope.ui.expanded = !$scope.ui.expanded;
 
             $common.hidePopover();
@@ -137,34 +140,34 @@ consoleModule.controller('igfsController', [
 
         // When landing on the page, get IGFSs and show them.
         $http.post('/api/v1/configuration/igfs/list')
-            .success(function (data) {
+            .success(function(data) {
                 $scope.spaces = data.spaces;
 
                 $scope.igfss = data.igfss || [];
 
                 // For backward compatibility set colocateMetadata and relaxedConsistency default values.
-                _.forEach($scope.igfss, function (igfs) {
-                   if (_.isUndefined(igfs.colocateMetadata))
-                       igfs.colocateMetadata = true;
+                _.forEach($scope.igfss, (igfs) => {
+                    if (_.isUndefined(igfs.colocateMetadata))
+                        igfs.colocateMetadata = true;
 
-                   if (_.isUndefined(igfs.relaxedConsistency))
-                       igfs.relaxedConsistency = true;
+                    if (_.isUndefined(igfs.relaxedConsistency))
+                        igfs.relaxedConsistency = true;
                 });
 
-                $scope.clusters = _.map(data.clusters  || [], function (cluster) {
+                $scope.clusters = _.map(data.clusters || [], function(cluster) {
                     return {
                         value: cluster._id,
                         label: cluster.name
                     };
                 });
 
-                if ($state.params.id)
-                    $scope.createItem($state.params.id);
+                if ($state.params.linkId)
+                    $scope.createItem($state.params.linkId);
                 else {
-                    var lastSelectedIgfs = angular.fromJson(sessionStorage.lastSelectedIgfs);
+                    const lastSelectedIgfs = angular.fromJson(sessionStorage.lastSelectedIgfs);
 
                     if (lastSelectedIgfs) {
-                        var idx = _.findIndex($scope.igfss, function (igfs) {
+                        const idx = _.findIndex($scope.igfss, function(igfs) {
                             return igfs._id === lastSelectedIgfs;
                         });
 
@@ -181,30 +184,29 @@ consoleModule.controller('igfsController', [
                 }
 
                 $scope.$watch('ui.inputForm.$valid', function(valid) {
-                    if (valid && __original_value === JSON.stringify($cleanup($scope.backupItem))) {
+                    if (valid && _.isEqual(__original_value, $cleanup($scope.backupItem)))
                         $scope.ui.inputForm.$dirty = false;
-                    }
                 });
 
-                $scope.$watch('backupItem', function (val) {
-                    var form = $scope.ui.inputForm;
+                $scope.$watch('backupItem', function(val) {
+                    const form = $scope.ui.inputForm;
 
-                    if (form.$pristine || (form.$valid && __original_value === JSON.stringify($cleanup(val))))
+                    if (form.$pristine || (form.$valid && _.isEqual(__original_value, $cleanup(val))))
                         form.$setPristine();
                     else
                         form.$setDirty();
                 }, true);
             })
-            .catch(function (errMsg) {
+            .catch(function(errMsg) {
                 $common.showError(errMsg);
             })
-            .finally(function () {
+            .finally(function() {
                 $scope.ui.ready = true;
                 $scope.ui.inputForm.$setPristine();
                 $loading.finish('loadingIgfsScreen');
             });
 
-        $scope.selectItem = function (item, backup) {
+        $scope.selectItem = function(item, backup) {
             function selectItem() {
                 $table.tableReset(); // TODO LEGACY
 
@@ -229,7 +231,7 @@ consoleModule.controller('igfsController', [
 
                 $scope.backupItem = angular.merge({}, blank, $scope.backupItem);
 
-                __original_value = JSON.stringify($cleanup($scope.backupItem));
+                __original_value = $cleanup($scope.backupItem);
 
                 if ($common.getQueryVariable('new'))
                     $state.go('base.configuration.igfs');
@@ -238,26 +240,26 @@ consoleModule.controller('igfsController', [
             $common.confirmUnsavedChanges($scope.backupItem && $scope.ui.inputForm.$dirty, selectItem);
         };
 
-        function prepareNewItem(id) {
+        $scope.linkId = () => $scope.backupItem._id ? $scope.backupItem._id : 'create';
+
+        function prepareNewItem(linkId) {
             return {
                 space: $scope.spaces[0]._id,
                 ipcEndpointEnabled: true,
                 fragmentizerEnabled: true,
                 colocateMetadata: true,
                 relaxedConsistency: true,
-                clusters: id && _.find($scope.clusters, {value: id}) ? [id] :
-                    (!_.isEmpty($scope.clusters) ? [$scope.clusters[0].value] : [])
+                clusters: linkId && _.find($scope.clusters, {value: linkId}) ? [linkId] :
+                    (_.isEmpty($scope.clusters) ? [] : [$scope.clusters[0].value])
             };
         }
 
         // Add new IGFS.
-        $scope.createItem = function (id) {
+        $scope.createItem = function(linkId) {
             if ($scope.tableReset(true)) { // TODO LEGACY
-                $timeout(function () {
-                    $common.ensureActivePanel($scope.ui, 'general', 'igfsName');
-                });
+                $timeout(() => $common.ensureActivePanel($scope.ui, 'general', 'igfsName'));
 
-                $scope.selectItem(undefined, prepareNewItem(id));
+                $scope.selectItem(null, prepareNewItem(linkId));
             }
         };
 
@@ -268,46 +270,14 @@ consoleModule.controller('igfsController', [
             if ($common.isEmptyString(item.name))
                 return showPopoverMessage($scope.ui, 'general', 'igfsName', 'IGFS name should not be empty!');
 
-            var form = $scope.ui.inputForm;
-            var errors = form.$error;
-            var errKeys = Object.keys(errors);
-
-            if (errKeys && errKeys.length > 0) {
-                var firstErrorKey = errKeys[0];
-
-                var firstError = errors[firstErrorKey][0];
-                var actualError = firstError.$error[firstErrorKey][0];
-
-                var errNameFull = actualError.$name;
-                var errNameShort = errNameFull;
-
-                if (errNameShort.endsWith('TextInput'))
-                    errNameShort = errNameShort.substring(0, errNameShort.length - 9);
-
-                var extractErrorMessage = function (errName) {
-                    try {
-                        return errors[firstErrorKey][0].$errorMessages[errName][firstErrorKey];
-                    }
-                    catch(ignored) {
-                        try {
-                            msg = form[firstError.$name].$errorMessages[errName][firstErrorKey];
-                        }
-                        catch(ignited) {
-                            return false;
-                        }
-                    }
-                };
-
-                var msg = extractErrorMessage(errNameFull) || extractErrorMessage(errNameShort) || 'Invalid value!';
-
-                return showPopoverMessage($scope.ui, firstError.$name, errNameFull, msg);
-            }
+            if (!$common.checkFieldValidators($scope.ui))
+                return false;
 
             if (!item.secondaryFileSystemEnabled && (item.defaultMode === 'PROXY'))
                 return showPopoverMessage($scope.ui, 'secondaryFileSystem', 'secondaryFileSystem-title', 'Secondary file system should be configured for "PROXY" IGFS mode!');
 
             if (item.pathModes) {
-                for (var pathIx = 0; pathIx < item.pathModes.length; pathIx++) {
+                for (let pathIx = 0; pathIx < item.pathModes.length; pathIx++) {
                     if (!item.secondaryFileSystemEnabled && item.pathModes[pathIx].mode === 'PROXY')
                         return showPopoverMessage($scope.ui, 'secondaryFileSystem', 'secondaryFileSystem-title', 'Secondary file system should be configured for "PROXY" path mode!');
                 }
@@ -319,10 +289,10 @@ consoleModule.controller('igfsController', [
         // Save IGFS in database.
         function save(item) {
             $http.post('/api/v1/configuration/igfs/save', item)
-                .success(function (_id) {
+                .success(function(_id) {
                     $scope.ui.inputForm.$setPristine();
 
-                    var idx = _.findIndex($scope.igfss, function (igfs) {
+                    const idx = _.findIndex($scope.igfss, function(igfs) {
                         return igfs._id === _id;
                     });
 
@@ -337,15 +307,15 @@ consoleModule.controller('igfsController', [
 
                     $common.showInfo('IGFS "' + item.name + '" saved.');
                 })
-                .error(function (errMsg) {
+                .error(function(errMsg) {
                     $common.showError(errMsg);
                 });
         }
 
         // Save IGFS.
-        $scope.saveItem = function () {
+        $scope.saveItem = function() {
             if ($scope.tableReset(true)) { // TODO LEGACY
-                var item = $scope.backupItem;
+                const item = $scope.backupItem;
 
                 if (validate(item))
                     save(item);
@@ -353,16 +323,16 @@ consoleModule.controller('igfsController', [
         };
 
         function _igfsNames() {
-            return _.map($scope.igfss, function (igfs) {
+            return _.map($scope.igfss, function(igfs) {
                 return igfs.name;
             });
         }
 
         // Clone IGFS with new name.
-        $scope.cloneItem = function () {
+        $scope.cloneItem = function() {
             if ($scope.tableReset(true) && validate($scope.backupItem)) { // TODO LEGACY
-                $clone.confirm($scope.backupItem.name, _igfsNames()).then(function (newName) {
-                    var item = angular.copy($scope.backupItem);
+                $clone.confirm($scope.backupItem.name, _igfsNames()).then(function(newName) {
+                    const item = angular.copy($scope.backupItem);
 
                     delete item._id;
 
@@ -374,22 +344,22 @@ consoleModule.controller('igfsController', [
         };
 
         // Remove IGFS from db.
-        $scope.removeItem = function () {
+        $scope.removeItem = function() {
             $table.tableReset(); // TODO LEGACY
 
-            var selectedItem = $scope.selectedItem;
+            const selectedItem = $scope.selectedItem;
 
             $confirm.confirm('Are you sure you want to remove IGFS: "' + selectedItem.name + '"?')
-                .then(function () {
-                    var _id = selectedItem._id;
+                .then(function() {
+                    const _id = selectedItem._id;
 
-                    $http.post('/api/v1/configuration/igfs/remove', {_id: _id})
-                        .success(function () {
+                    $http.post('/api/v1/configuration/igfs/remove', {_id})
+                        .success(function() {
                             $common.showInfo('IGFS has been removed: ' + selectedItem.name);
 
-                            var igfss = $scope.igfss;
+                            const igfss = $scope.igfss;
 
-                            var idx = _.findIndex(igfss, function (igfs) {
+                            const idx = _.findIndex(igfss, function(igfs) {
                                 return igfs._id === _id;
                             });
 
@@ -398,41 +368,43 @@ consoleModule.controller('igfsController', [
 
                                 if (igfss.length > 0)
                                     $scope.selectItem(igfss[0]);
-                                else
+                                else {
                                     $scope.backupItem = emptyIgfs;
+                                    $scope.ui.inputForm.$setPristine();
+                                }
                             }
                         })
-                        .error(function (errMsg) {
+                        .error(function(errMsg) {
                             $common.showError(errMsg);
                         });
                 });
         };
 
         // Remove all IGFS from db.
-        $scope.removeAllItems = function () {
+        $scope.removeAllItems = function() {
             $table.tableReset(); // TODO LEGACY
 
             $confirm.confirm('Are you sure you want to remove all IGFS?')
-                .then(function () {
+                .then(function() {
                     $http.post('/api/v1/configuration/igfs/remove/all')
-                        .success(function () {
+                        .success(function() {
                             $common.showInfo('All IGFS have been removed');
 
                             $scope.igfss = [];
                             $scope.backupItem = emptyIgfs;
                             $scope.ui.inputForm.$setPristine();
                         })
-                        .error(function (errMsg) {
+                        .error(function(errMsg) {
                             $common.showError(errMsg);
                         });
                 });
         };
 
-        $scope.resetAll = function () {
+        $scope.resetAll = function() {
             $table.tableReset(); // TODO LEGACY
 
             $confirm.confirm('Are you sure you want to undo all changes for current IGFS?')
-                .then(function () {
+                .then(function() {
                     $scope.backupItem = $scope.selectedItem ? angular.copy($scope.selectedItem) : prepareNewItem();
                     $scope.ui.inputForm.$setPristine();
                 });

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/controllers/profile-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/controllers/profile-controller.js b/modules/web-console/src/main/js/controllers/profile-controller.js
index ffeffd4..39457af 100644
--- a/modules/web-console/src/main/js/controllers/profile-controller.js
+++ b/modules/web-console/src/main/js/controllers/profile-controller.js
@@ -19,66 +19,74 @@
 import consoleModule from 'controllers/common-module';
 
 consoleModule.controller('profileController', [
-    '$rootScope', '$scope', '$http', '$common', '$focus', '$confirm', 'IgniteCountries',
-    function ($root, $scope, $http, $common, $focus, $confirm, Countries) {
+    '$rootScope', '$scope', '$http', '$common', '$focus', '$confirm', 'IgniteCountries', 'User',
+    function($root, $scope, $http, $common, $focus, $confirm, Countries, User) {
         $scope.user = angular.copy($root.user);
 
         $scope.countries = Countries.getAll();
 
         $scope.generateToken = () => {
             $confirm.confirm('Are you sure you want to change security token?')
-                .then(() => $scope.user.token = $common.randomString(20))
+                .then(() => $scope.user.token = $common.randomString(20));
         };
 
-        const _cleanup = () => {
-            const _user = $scope.user;
-
-            if (!$scope.expandedToken)
-                _user.token = $root.user.token;
-
-            if (!$scope.expandedPassword) {
-                delete _user.password;
+        const _passwordValid = () => {
+            const cur = $scope.user;
 
-                delete _user.confirm;
-            }
+            return !$scope.expandedPassword || (cur.password && cur.confirm && cur.password === cur.confirm);
         };
 
         const _profileChanged = () => {
-            _cleanup();
-
             const old = $root.user;
             const cur = $scope.user;
 
             return !_.isEqual(old, cur);
         };
 
-        $scope.profileCouldBeSaved = () => _profileChanged() && $scope.profileForm && $scope.profileForm.$valid;
+        $scope.toggleToken = () => {
+            $scope.expandedToken = !$scope.expandedToken;
+
+            if (!$scope.expandedToken)
+                $scope.user.token = $root.user.token;
+        };
+
+        $scope.togglePassword = () => {
+            $scope.expandedPassword = !$scope.expandedPassword;
+
+            if (!$scope.expandedPassword) {
+                delete $scope.user.password;
+
+                delete $scope.user.confirm;
+            }
+        };
+
+        $scope.profileCouldBeSaved = () => _profileChanged() && $scope.profileForm && $scope.profileForm.$valid && _passwordValid();
 
         $scope.saveBtnTipText = () => {
             if (!_profileChanged())
                 return 'Nothing to save';
 
+            if (!_passwordValid())
+                return 'Invalid password';
+
             return $scope.profileForm && $scope.profileForm.$valid ? 'Save profile' : 'Invalid profile settings';
         };
 
         $scope.saveUser = () => {
-            _cleanup();
-
             $http.post('/api/v1/profile/save', $scope.user)
-                .success(() => {
-                    $scope.expandedPassword = false;
-
-                    _cleanup();
-
-                    $scope.expandedToken = false;
+                .then(User.read)
+                .then(() => {
+                    if ($scope.expandedPassword)
+                        $scope.togglePassword();
 
-                    $root.user = angular.copy($scope.user);
+                    if ($scope.expandedToken)
+                        $scope.toggleToken();
 
                     $common.showInfo('Profile saved.');
 
                     $focus('profile-username');
                 })
-                .error((err) => $common.showError('Failed to save profile: ' + $common.errorMessage(err)));
+                .catch((err) => $common.showError('Failed to save profile: ' + $common.errorMessage(err)));
         };
     }]
 );


[02/50] [abbrv] ignite git commit: IGNITE-3277 Replaced outdated json-lib 2.4 to modern Jackson 2.7.5.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyObjectMapper.java
----------------------------------------------------------------------
diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyObjectMapper.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyObjectMapper.java
new file mode 100644
index 0000000..f09b583
--- /dev/null
+++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyObjectMapper.java
@@ -0,0 +1,259 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.rest.protocols.http.jetty;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationConfig;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
+import com.fasterxml.jackson.databind.ser.SerializerFactory;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import org.apache.ignite.internal.LessNamingBean;
+import org.apache.ignite.internal.visor.cache.VisorCache;
+import org.apache.ignite.internal.visor.util.VisorExceptionWrapper;
+import org.apache.ignite.lang.IgniteBiTuple;
+import org.apache.ignite.lang.IgniteUuid;
+
+/**
+ * Custom object mapper for HTTP REST API.
+ */
+public class GridJettyObjectMapper extends ObjectMapper {
+    /**
+     * Default constructor.
+     */
+    public GridJettyObjectMapper() {
+        super(null, new CustomSerializerProvider(), null);
+
+        setDateFormat(DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US));
+
+        SimpleModule module = new SimpleModule();
+
+        module.addSerializer(Throwable.class, THROWABLE_SERIALIZER);
+        module.addSerializer(IgniteBiTuple.class, IGNITE_TUPLE_SERIALIZER);
+        module.addSerializer(IgniteUuid.class, IGNITE_UUID_SERIALIZER);
+        module.addSerializer(LessNamingBean.class, LESS_NAMING_SERIALIZER);
+
+        registerModule(module);
+    }
+
+    /** Custom {@code null} value serializer. */
+    private static final JsonSerializer<Object> NULL_SERIALIZER = new JsonSerializer<Object>() {
+        /** {@inheritDoc} */
+        @Override public void serialize(Object val, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            gen.writeNull();
+        }
+    };
+
+    /** Custom {@code null} string serializer. */
+    private static final JsonSerializer<Object> NULL_STRING_SERIALIZER = new JsonSerializer<Object>() {
+        /** {@inheritDoc} */
+        @Override public void serialize(Object val, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            gen.writeString("");
+        }
+    };
+
+    /**
+     * Custom serializers provider that provide special serializers for {@code null} values.
+     */
+    private static class CustomSerializerProvider extends DefaultSerializerProvider {
+        /**
+         * Default constructor.
+         */
+        CustomSerializerProvider() {
+            super();
+        }
+
+        /**
+         * Full constructor.
+         *
+         * @param src Blueprint object used as the baseline for this instance.
+         * @param cfg Provider configuration.
+         * @param f Serializers factory.
+         */
+        CustomSerializerProvider(SerializerProvider src, SerializationConfig cfg, SerializerFactory f) {
+            super(src, cfg, f);
+        }
+
+        /** {@inheritDoc} */
+        public DefaultSerializerProvider createInstance(SerializationConfig cfg, SerializerFactory jsf) {
+            return new CustomSerializerProvider(this, cfg, jsf);
+        }
+
+        /** {@inheritDoc} */
+        @Override public JsonSerializer<Object> findNullValueSerializer(BeanProperty prop) throws JsonMappingException {
+            if (prop.getType().getRawClass() == String.class)
+                return NULL_STRING_SERIALIZER;
+
+            return NULL_SERIALIZER;
+        }
+    }
+
+    /** Custom serializer for {@link Throwable} */
+    private static final JsonSerializer<Throwable> THROWABLE_SERIALIZER = new JsonSerializer<Throwable>() {
+        /** {@inheritDoc} */
+        @Override public void serialize(Throwable e, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            gen.writeStartObject();
+
+            if (e instanceof VisorExceptionWrapper) {
+                VisorExceptionWrapper wrapper = (VisorExceptionWrapper)e;
+
+                gen.writeStringField("className", wrapper.getClassName());
+            }
+            else
+                gen.writeStringField("className", e.getClass().getName());
+
+            if (e.getMessage() != null)
+                gen.writeStringField("message", e.getMessage());
+
+            if (e.getCause() != null)
+                gen.writeObjectField("cause", e.getCause());
+
+            if (e instanceof SQLException) {
+                SQLException sqlE = (SQLException)e;
+
+                gen.writeNumberField("errorCode", sqlE.getErrorCode());
+                gen.writeStringField("SQLState", sqlE.getSQLState());
+            }
+
+            gen.writeEndObject();
+        }
+    };
+
+    /** Custom serializer for {@link IgniteUuid} */
+    private static final JsonSerializer<IgniteUuid> IGNITE_UUID_SERIALIZER = new JsonSerializer<IgniteUuid>() {
+        /** {@inheritDoc} */
+        @Override public void serialize(IgniteUuid uid, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            gen.writeString(uid.toString());
+        }
+    };
+
+    /** Custom serializer for {@link IgniteBiTuple} */
+    private static final JsonSerializer<IgniteBiTuple> IGNITE_TUPLE_SERIALIZER = new JsonSerializer<IgniteBiTuple>() {
+        /** {@inheritDoc} */
+        @Override public void serialize(IgniteBiTuple t, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            gen.writeStartObject();
+
+            gen.writeObjectField("key", t.getKey());
+            gen.writeObjectField("value", t.getValue());
+
+            gen.writeEndObject();
+        }
+    };
+
+    /**
+     * Custom serializer for Visor classes with non JavaBeans getters.
+     */
+    private static final JsonSerializer<Object> LESS_NAMING_SERIALIZER = new JsonSerializer<Object>() {
+        /** Methods to exclude. */
+        private final Collection<String> exclMtds = Arrays.asList("toString", "hashCode", "clone", "getClass");
+
+        /** */
+        private final Map<Class<?>, Collection<Method>> clsCache = new HashMap<>();
+
+        /** */
+        private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
+
+        /** {@inheritDoc} */
+        @Override public void serialize(Object bean, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            if (bean != null) {
+                gen.writeStartObject();
+
+                Class<?> cls = bean.getClass();
+
+                Collection<Method> methods;
+
+                // Get descriptor from cache.
+                rwLock.readLock().lock();
+
+                try {
+                    methods = clsCache.get(cls);
+                }
+                finally {
+                    rwLock.readLock().unlock();
+                }
+
+                // If missing in cache - build descriptor
+                if (methods == null) {
+                    Method[] publicMtds = cls.getMethods();
+
+                    methods = new ArrayList<>(publicMtds.length);
+
+                    for (Method mtd : publicMtds) {
+                        Class retType = mtd.getReturnType();
+
+                        String mtdName = mtd.getName();
+
+                        if (mtd.getParameterTypes().length != 0 ||
+                            retType == void.class || retType == cls ||
+                            exclMtds.contains(mtdName) ||
+                            (VisorCache.class.isAssignableFrom(retType) && "history".equals(mtdName)))
+                            continue;
+
+                        mtd.setAccessible(true);
+
+                        methods.add(mtd);
+                    }
+
+                    // Allow multiple puts for the same class - they will simply override.
+                    rwLock.writeLock().lock();
+
+                    try {
+                        clsCache.put(cls, methods);
+                    }
+                    finally {
+                        rwLock.writeLock().unlock();
+                    }
+                }
+
+                // Extract fields values using descriptor and build JSONObject.
+                for (Method mtd : methods) {
+                    try {
+                        Object prop = mtd.invoke(bean);
+
+                        if (prop != null)
+                            gen.writeObjectField(mtd.getName(), prop);
+                    }
+                    catch (IOException ioe) {
+                        throw ioe;
+                    }
+                    catch (Exception e) {
+                        throw new IOException(e);
+                    }
+                }
+
+                gen.writeEndObject();
+            }
+        }
+    };
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
----------------------------------------------------------------------
diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
index b6a386b..c2679df 100644
--- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
+++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
@@ -17,6 +17,8 @@
 
 package org.apache.ignite.internal.processors.rest.protocols.http.jetty;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -24,6 +26,7 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.LineNumberReader;
 import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -34,17 +37,11 @@ import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import net.sf.json.JSON;
-import net.sf.json.JSONException;
-import net.sf.json.JSONSerializer;
-import net.sf.json.JsonConfig;
-import net.sf.json.processors.JsonValueProcessor;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.internal.processors.rest.GridRestCommand;
 import org.apache.ignite.internal.processors.rest.GridRestProtocolHandler;
 import org.apache.ignite.internal.processors.rest.GridRestResponse;
-import org.apache.ignite.internal.processors.rest.client.message.GridClientTaskResultBean;
 import org.apache.ignite.internal.processors.rest.request.DataStructuresRequest;
 import org.apache.ignite.internal.processors.rest.request.GridRestCacheRequest;
 import org.apache.ignite.internal.processors.rest.request.GridRestLogRequest;
@@ -68,32 +65,30 @@ import static org.apache.ignite.internal.processors.rest.GridRestCommand.EXECUTE
 import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_FAILED;
 
 /**
- * Jetty REST handler. The following URL format is supported:
- * {@code /ignite?cmd=cmdName&param1=abc&param2=123}
+ * Jetty REST handler. The following URL format is supported: {@code /ignite?cmd=cmdName&param1=abc&param2=123}
  */
 public class GridJettyRestHandler extends AbstractHandler {
-    /** JSON value processor that does not transform input object. */
-    private static final JsonValueProcessor SKIP_STR_VAL_PROC = new JsonValueProcessor() {
-        @Override public Object processArrayValue(Object o, JsonConfig jsonConfig) {
-            return o;
-        }
-
-        @Override public Object processObjectValue(String s, Object o, JsonConfig jsonConfig) {
-            return o;
-        }
-    };
+    /** Used to sent request charset. */
+    private static final String CHARSET = StandardCharsets.UTF_8.name();
 
     /** Logger. */
     private final IgniteLogger log;
+
     /** Authentication checker. */
     private final IgniteClosure<String, Boolean> authChecker;
+
     /** Request handlers. */
     private GridRestProtocolHandler hnd;
+
     /** Default page. */
     private volatile String dfltPage;
+
     /** Favicon. */
     private volatile byte[] favicon;
 
+    /** Mapper from Java object to JSON. */
+    private final ObjectMapper jsonMapper;
+
     /**
      * Creates new HTTP requests handler.
      *
@@ -108,6 +103,7 @@ public class GridJettyRestHandler extends AbstractHandler {
         this.hnd = hnd;
         this.log = log;
         this.authChecker = authChecker;
+        this.jsonMapper = new GridJettyObjectMapper();
 
         // Init default page and favicon.
         try {
@@ -137,14 +133,14 @@ public class GridJettyRestHandler extends AbstractHandler {
      * @param key Key.
      * @param params Parameters map.
      * @param dfltVal Default value.
-     * @return Long value from parameters map or {@code dfltVal} if null
-     *     or not exists.
+     * @return Long value from parameters map or {@code dfltVal} if null or not exists.
      * @throws IgniteCheckedException If parsing failed.
      */
-    @Nullable private static Long longValue(String key, Map<String, Object> params, Long dfltVal) throws IgniteCheckedException {
+    @Nullable private static Long longValue(String key, Map<String, Object> params,
+        Long dfltVal) throws IgniteCheckedException {
         assert key != null;
 
-        String val = (String) params.get(key);
+        String val = (String)params.get(key);
 
         try {
             return val == null ? dfltVal : Long.valueOf(val);
@@ -160,17 +156,16 @@ public class GridJettyRestHandler extends AbstractHandler {
      * @param key Key.
      * @param params Parameters map.
      * @param dfltVal Default value.
-     * @return Integer value from parameters map or {@code dfltVal} if null
-     *     or not exists.
+     * @return Integer value from parameters map or {@code dfltVal} if null or not exists.
      * @throws IgniteCheckedException If parsing failed.
      */
-    @Nullable private static Integer intValue(String key, Map<String, Object> params, Integer dfltVal) throws IgniteCheckedException {
+    private static int intValue(String key, Map<String, Object> params, int dfltVal) throws IgniteCheckedException {
         assert key != null;
 
-        String val = (String) params.get(key);
+        String val = (String)params.get(key);
 
         try {
-            return val == null ? dfltVal : Integer.valueOf(val);
+            return val == null ? dfltVal : Integer.parseInt(val);
         }
         catch (NumberFormatException ignore) {
             throw new IgniteCheckedException("Failed to parse parameter of Integer type [" + key + "=" + val + "]");
@@ -182,14 +177,13 @@ public class GridJettyRestHandler extends AbstractHandler {
      *
      * @param key Key.
      * @param params Parameters map.
-     * @return UUID value from parameters map or {@code null} if null
-     *     or not exists.
+     * @return UUID value from parameters map or {@code null} if null or not exists.
      * @throws IgniteCheckedException If parsing failed.
      */
     @Nullable private static UUID uuidValue(String key, Map<String, Object> params) throws IgniteCheckedException {
         assert key != null;
 
-        String val = (String) params.get(key);
+        String val = (String)params.get(key);
 
         try {
             return val == null ? null : UUID.fromString(val);
@@ -208,7 +202,7 @@ public class GridJettyRestHandler extends AbstractHandler {
         InputStream in = getClass().getResourceAsStream("rest.html");
 
         if (in != null) {
-            LineNumberReader rdr = new LineNumberReader(new InputStreamReader(in));
+            LineNumberReader rdr = new LineNumberReader(new InputStreamReader(in, CHARSET));
 
             try {
                 StringBuilder buf = new StringBuilder(2048);
@@ -217,7 +211,7 @@ public class GridJettyRestHandler extends AbstractHandler {
                     buf.append(line);
 
                     if (!line.endsWith(" "))
-                        buf.append(" ");
+                        buf.append(' ');
                 }
 
                 dfltPage = buf.toString();
@@ -368,39 +362,35 @@ public class GridJettyRestHandler extends AbstractHandler {
                 throw (Error)e;
         }
 
-        JsonConfig cfg = new GridJettyJsonConfig(log);
-
-        // Workaround for not needed transformation of string into JSON object.
-        if (cmdRes.getResponse() instanceof String)
-            cfg.registerJsonValueProcessor(cmdRes.getClass(), "response", SKIP_STR_VAL_PROC);
-
-        // Workaround for not needed transformation of result field string into JSON object at GridClientTaskResultBean.
-        if (cmdRes.getResponse() instanceof GridClientTaskResultBean
-            && ((GridClientTaskResultBean)cmdRes.getResponse()).getResult() instanceof String)
-            cfg.registerJsonValueProcessor(cmdRes.getResponse().getClass(), "result", SKIP_STR_VAL_PROC);
-
-        JSON json;
+        String json;
 
         try {
-            json = JSONSerializer.toJSON(cmdRes, cfg);
+            json = jsonMapper.writeValueAsString(cmdRes);
         }
-        catch (JSONException e) {
-            U.error(log, "Failed to convert response to JSON: " + cmdRes, e);
+        catch (JsonProcessingException e1) {
+            U.error(log, "Failed to convert response to JSON: " + cmdRes, e1);
+
+            GridRestResponse resFailed = new GridRestResponse(STATUS_FAILED, e1.getMessage());
 
-            json = JSONSerializer.toJSON(new GridRestResponse(STATUS_FAILED, e.getMessage()), cfg);
+            try {
+                json = jsonMapper.writeValueAsString(resFailed);
+            }
+            catch (JsonProcessingException e2) {
+                json = "{\"successStatus\": \"1\", \"error:\" \"" + e2.getMessage() + "\"}}";
+            }
         }
 
         try {
             if (log.isDebugEnabled())
-                log.debug("Parsed command response into JSON object: " + json.toString(2));
+                log.debug("Parsed command response into JSON object: " + json);
 
-            res.getWriter().write(json.toString());
+            res.getWriter().write(json);
 
             if (log.isDebugEnabled())
                 log.debug("Processed HTTP request [action=" + act + ", jsonRes=" + cmdRes + ", req=" + req + ']');
         }
         catch (IOException e) {
-            U.error(log, "Failed to send HTTP response: " + json.toString(2), e);
+            U.error(log, "Failed to send HTTP response: " + json, e);
         }
     }
 
@@ -510,10 +500,10 @@ public class GridJettyRestHandler extends AbstractHandler {
             case NODE: {
                 GridRestTopologyRequest restReq0 = new GridRestTopologyRequest();
 
-                restReq0.includeMetrics(Boolean.parseBoolean((String) params.get("mtr")));
-                restReq0.includeAttributes(Boolean.parseBoolean((String) params.get("attr")));
+                restReq0.includeMetrics(Boolean.parseBoolean((String)params.get("mtr")));
+                restReq0.includeAttributes(Boolean.parseBoolean((String)params.get("attr")));
 
-                restReq0.nodeIp((String) params.get("ip"));
+                restReq0.nodeIp((String)params.get("ip"));
 
                 restReq0.nodeId(uuidValue("id", params));
 
@@ -527,12 +517,12 @@ public class GridJettyRestHandler extends AbstractHandler {
             case NOOP: {
                 GridRestTaskRequest restReq0 = new GridRestTaskRequest();
 
-                restReq0.taskId((String) params.get("id"));
-                restReq0.taskName((String) params.get("name"));
+                restReq0.taskId((String)params.get("id"));
+                restReq0.taskName((String)params.get("name"));
 
                 restReq0.params(values("p", params));
 
-                restReq0.async(Boolean.parseBoolean((String) params.get("async")));
+                restReq0.async(Boolean.parseBoolean((String)params.get("async")));
 
                 restReq0.timeout(longValue("timeout", params, 0L));
 
@@ -544,7 +534,7 @@ public class GridJettyRestHandler extends AbstractHandler {
             case LOG: {
                 GridRestLogRequest restReq0 = new GridRestLogRequest();
 
-                restReq0.path((String) params.get("path"));
+                restReq0.path((String)params.get("path"));
 
                 restReq0.from(intValue("from", params, -1));
                 restReq0.to(intValue("to", params, -1));
@@ -569,9 +559,9 @@ public class GridJettyRestHandler extends AbstractHandler {
 
                 restReq0.arguments(values("arg", params).toArray());
 
-                restReq0.typeName((String) params.get("type"));
+                restReq0.typeName((String)params.get("type"));
 
-                String pageSize = (String) params.get("pageSize");
+                String pageSize = (String)params.get("pageSize");
 
                 if (pageSize != null)
                     restReq0.pageSize(Integer.parseInt(pageSize));
@@ -612,7 +602,7 @@ public class GridJettyRestHandler extends AbstractHandler {
             case FETCH_SQL_QUERY: {
                 RestQueryRequest restReq0 = new RestQueryRequest();
 
-                String qryId = (String) params.get("qryId");
+                String qryId = (String)params.get("qryId");
 
                 if (qryId != null)
                     restReq0.queryId(Long.parseLong(qryId));
@@ -632,7 +622,7 @@ public class GridJettyRestHandler extends AbstractHandler {
             case CLOSE_SQL_QUERY: {
                 RestQueryRequest restReq0 = new RestQueryRequest();
 
-                String qryId = (String) params.get("qryId");
+                String qryId = (String)params.get("qryId");
 
                 if (qryId != null)
                     restReq0.queryId(Long.parseLong(qryId));
@@ -659,7 +649,7 @@ public class GridJettyRestHandler extends AbstractHandler {
             restReq.credentials(cred);
         }
 
-        String clientId = (String) params.get("clientId");
+        String clientId = (String)params.get("clientId");
 
         try {
             if (clientId != null)
@@ -669,7 +659,7 @@ public class GridJettyRestHandler extends AbstractHandler {
             // Ignore invalid client id. Rest handler will process this logic.
         }
 
-        String destId = (String) params.get("destId");
+        String destId = (String)params.get("destId");
 
         try {
             if (destId != null)
@@ -679,7 +669,7 @@ public class GridJettyRestHandler extends AbstractHandler {
             // Don't fail - try to execute locally.
         }
 
-        String sesTokStr = (String) params.get("sessionToken");
+        String sesTokStr = (String)params.get("sessionToken");
 
         try {
             if (sesTokStr != null)
@@ -699,7 +689,7 @@ public class GridJettyRestHandler extends AbstractHandler {
      * @param params Parameters map.
      * @return Values.
      */
-    @Nullable protected List<Object> values(String keyPrefix, Map<String, Object> params) {
+    protected List<Object> values(String keyPrefix, Map<String, Object> params) {
         assert keyPrefix != null;
 
         List<Object> vals = new LinkedList<>();
@@ -720,15 +710,14 @@ public class GridJettyRestHandler extends AbstractHandler {
      * @param req Request.
      * @return Command.
      */
-    @Nullable GridRestCommand command(ServletRequest req) {
+    @Nullable private GridRestCommand command(ServletRequest req) {
         String cmd = req.getParameter("cmd");
 
         return cmd == null ? null : GridRestCommand.fromKey(cmd.toLowerCase());
     }
 
     /**
-     * Parses HTTP parameters in an appropriate format and return back map of
-     * values to predefined list of names.
+     * Parses HTTP parameters in an appropriate format and return back map of values to predefined list of names.
      *
      * @param req Request.
      * @return Map of parsed parameters.

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index c493248..d78deac 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -74,6 +74,7 @@
         <httpclient.version>4.5.1</httpclient.version>
         <httpcore.version>4.4.3</httpcore.version>
         <jackson.version>1.9.13</jackson.version>
+        <jackson2.version>2.7.5</jackson2.version>
         <javax.cache.bundle.version>1.0.0_1</javax.cache.bundle.version>
         <javax.cache.version>1.0.0</javax.cache.version>
         <jetty.version>9.2.11.v20150529</jetty.version>


[04/50] [abbrv] ignite git commit: IGNITE-3277 Replaced outdated json-lib 2.4 to modern Jackson 2.7.5.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
index 9fd3044..ad667ed 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
@@ -17,24 +17,27 @@
 
 package org.apache.ignite.internal.processors.rest;
 
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.LineNumberReader;
 import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Pattern;
-import net.sf.json.JSONNull;
-import net.sf.json.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
@@ -52,10 +55,12 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheProxy;
 import org.apache.ignite.internal.processors.cache.query.GridCacheSqlIndexMetadata;
 import org.apache.ignite.internal.processors.cache.query.GridCacheSqlMetadata;
 import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandler;
+import org.apache.ignite.internal.processors.rest.protocols.http.jetty.GridJettyObjectMapper;
 import org.apache.ignite.internal.util.lang.GridTuple3;
 import org.apache.ignite.internal.util.typedef.C1;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.P1;
+import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.internal.visor.cache.VisorCacheClearTask;
@@ -103,6 +108,7 @@ import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.testframework.GridTestUtils;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_JETTY_PORT;
+import static org.apache.ignite.internal.IgniteVersionUtils.VER_STR;
 
 /**
  * Tests for Jetty REST protocol.
@@ -112,6 +118,15 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     /** Grid count. */
     private static final int GRID_CNT = 3;
 
+    /** Url address to send HTTP request. */
+    private final String TEST_URL = "http://" + LOC_HOST + ":" + restPort() + "/ignite?";
+
+    /** Used to sent request charset. */
+    private static final String CHARSET = StandardCharsets.UTF_8.name();
+
+    /** JSON to java mapper. */
+    private static final ObjectMapper JSON_MAPPER = new GridJettyObjectMapper();
+
     /** {@inheritDoc} */
     @Override protected void beforeTestsStarted() throws Exception {
         System.setProperty(IGNITE_JETTY_PORT, Integer.toString(restPort()));
@@ -157,12 +172,12 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
      * @throws Exception If failed.
      */
     protected String content(Map<String, String> params) throws Exception {
-        String addr = "http://" + LOC_HOST + ":" + restPort() + "/ignite?";
+        SB sb = new SB(TEST_URL);
 
         for (Map.Entry<String, String> e : params.entrySet())
-            addr += e.getKey() + '=' + e.getValue() + '&';
+            sb.a(e.getKey()).a('=').a(e.getValue()).a('&');
 
-        URL url = new URL(addr);
+        URL url = new URL(sb.toString());
 
         URLConnection conn = url.openConnection();
 
@@ -173,165 +188,255 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         InputStream in = conn.getInputStream();
 
-        LineNumberReader rdr = new LineNumberReader(new InputStreamReader(in));
-
         StringBuilder buf = new StringBuilder(256);
 
-        for (String line = rdr.readLine(); line != null; line = rdr.readLine())
-            buf.append(line);
+        try (LineNumberReader rdr = new LineNumberReader(new InputStreamReader(in, "UTF-8"))) {
+            for (String line = rdr.readLine(); line != null; line = rdr.readLine())
+                buf.append(line);
+        }
 
         return buf.toString();
     }
 
     /**
-     * @param json JSON response.
-     * @param ptrn Pattern to match.
+     * @param content Content to check.
      */
-    @SuppressWarnings("TypeMayBeWeakened")
-    protected void jsonEquals(String json, String ptrn) {
-        assertTrue("JSON mismatch [json=" + json + ", ptrn=" + ptrn + ']', Pattern.matches(ptrn, json));
+    private void assertResponseContainsError(String content) throws IOException {
+        assertNotNull(content);
+        assertFalse(content.isEmpty());
+
+        JsonNode node = JSON_MAPPER.readTree(content);
+
+        assertEquals(1, node.get("successStatus").asInt());
+        assertFalse(node.get("error").asText().isEmpty());
+        assertTrue(node.get("response").isNull());
+        assertTrue(node.get("sessionToken").asText().isEmpty());
     }
 
     /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
+     * @param content Content to check.
+     * @param err Error message.
      */
-    private String cachePattern(String res, boolean success) {
-        return "\\{\\\"affinityNodeId\\\":\\\"\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}\\\"\\," +
-            "\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":\\\"" + res + "\\\"\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    private void assertResponseContainsError(String content, String err) throws IOException {
+        assertNotNull(content);
+        assertFalse(content.isEmpty());
+
+        assertNotNull(err);
+
+        JsonNode node = JSON_MAPPER.readTree(content);
+
+        assertEquals(1, node.get("successStatus").asInt());
+
+        assertTrue(node.get("response").isNull());
+        assertEquals(err, node.get("error").asText());
     }
 
     /**
-     * @param err Error.
-     * @return Regex pattern for JSON.
+     * @param content Content to check.
      */
-    private String errorPattern(String err) {
-        return "\\{" +
-            "\\\"error\\\":\\\"" + err + "\\\"\\," +
-            "\\\"response\\\":null\\," +
-            "\\\"sessionToken\\\":\\\"\\\"," +
-            "\\\"successStatus\\\":" + 1 + "\\}";
+    private JsonNode jsonCacheOperationResponse(String content, boolean bulk) throws IOException {
+        assertNotNull(content);
+        assertFalse(content.isEmpty());
+
+        JsonNode node = JSON_MAPPER.readTree(content);
+
+        assertEquals(bulk, node.get("affinityNodeId").asText().isEmpty());
+        assertEquals(0, node.get("successStatus").asInt());
+        assertTrue(node.get("error").asText().isEmpty());
+
+        assertNotSame(securityEnabled(), node.get("sessionToken").asText().isEmpty());
+
+        return node.get("response");
     }
 
     /**
+     * @param content Content to check.
      * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
      */
-    private String integerPattern(int res, boolean success) {
-        return "\\{\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    private void assertCacheOperation(String content, Object res) throws IOException {
+        JsonNode ret = jsonCacheOperationResponse(content, false);
+
+        assertEquals(String.valueOf(res), ret.asText());
     }
 
     /**
+     * @param content Content to check.
      * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
      */
-    private String cacheBulkPattern(String res, boolean success) {
-        return "\\{\\\"affinityNodeId\\\":\\\"\\\"\\," +
-            "\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    private void assertCacheBulkOperation(String content, Object res) throws IOException {
+        JsonNode ret = jsonCacheOperationResponse(content, true);
+
+        assertEquals(String.valueOf(res), ret.asText());
     }
 
     /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
+     * @param content Content to check.
      */
-    private String cacheBulkPattern(int res, boolean success) {
-        return "\\{\\\"affinityNodeId\\\":\\\"\\\"\\," +
-            "\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    private void assertCacheMetrics(String content) throws IOException {
+        JsonNode ret = jsonCacheOperationResponse(content, true);
+
+        assertTrue(ret.isObject());
     }
 
     /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
+     * @param content Content to check.
+     * @return REST result.
      */
-    private String cachePattern(boolean res, boolean success) {
-        return "\\{\\\"affinityNodeId\\\":\\\"\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}\\\"\\," +
-            "\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    protected JsonNode jsonResponse(String content) throws IOException {
+        assertNotNull(content);
+        assertFalse(content.isEmpty());
+
+        JsonNode node = JSON_MAPPER.readTree(content);
+
+        assertEquals(0, node.get("successStatus").asInt());
+        assertTrue(node.get("error").asText().isEmpty());
+
+        assertNotSame(securityEnabled(), node.get("sessionToken").asText().isEmpty());
+
+        return node.get("response");
     }
 
     /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
+     * @param content Content to check.
+     * @return Task result.
      */
-    private String cacheBulkPattern(boolean res, boolean success) {
-        return "\\{\\\"affinityNodeId\\\":\\\"\\\"\\," +
-            "\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    protected JsonNode jsonTaskResult(String content) throws IOException {
+        assertNotNull(content);
+        assertFalse(content.isEmpty());
+
+        JsonNode node = JSON_MAPPER.readTree(content);
+
+        assertEquals(0, node.get("successStatus").asInt());
+        assertTrue(node.get("error").asText().isEmpty());
+        assertFalse(node.get("response").isNull());
+
+        assertEquals(securityEnabled(), !node.get("sessionToken").asText().isEmpty());
+
+        JsonNode res = node.get("response");
+
+        assertTrue(res.isObject());
+
+        assertFalse(res.get("id").asText().isEmpty());
+        assertTrue(res.get("finished").asBoolean());
+        assertTrue(res.get("error").asText().isEmpty());
+
+        return res.get("result");
     }
 
     /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
+     * @throws Exception If failed.
      */
-    private String cacheMetricsPattern(String res, boolean success) {
-        return "\\{\\\"affinityNodeId\\\":\\\"(\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12})?\\\"\\," +
-            "\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    public void testGet() throws Exception {
+        jcache().put("getKey", "getVal");
+
+        String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "key", "getKey"));
+
+        info("Get command result: " + ret);
+
+        assertCacheOperation(ret, "getVal");
     }
 
     /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
+     * @throws Exception If failed.
      */
-    protected String pattern(String res, boolean success) {
-        return "\\{\\\"error\\\":\\\"" + (!success ? ".+" : "") + "\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    public void testSimpleObject()  throws Exception {
+        SimplePerson p = new SimplePerson(1, "Test", java.sql.Date.valueOf("1977-01-26"), 1000.55, 39, "CIO", 25);
+
+        jcache().put("simplePersonKey", p);
+
+        String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "key", "simplePersonKey"));
+
+        info("Get command result: " + ret);
+
+        JsonNode res = jsonCacheOperationResponse(ret, false);
+
+        assertEquals(res.get("id").asInt(), p.id);
+        assertEquals(res.get("name").asText(), p.name);
+        assertEquals(res.get("birthday").asText(), p.birthday.toString());
+        assertEquals(res.get("salary").asDouble(), p.salary);
+        assertNull(res.get("age"));
+        assertNull(res.get("post"));
+        assertNull(res.get("bonus"));
     }
 
     /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
+     * @throws Exception If failed.
      */
-    private String stringPattern(String res, boolean success) {
-        return "\\{\\\"error\\\":\\\"" + (!success ? ".+" : "") + "\\\"\\," +
-            "\\\"response\\\":\\\"" + res + "\\\"\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    public void testDate() throws Exception {
+        java.util.Date utilDate = new java.util.Date();
+
+        DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US);
+
+        String date = formatter.format(utilDate);
+
+        jcache().put("utilDateKey", utilDate);
+
+        String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "key", "utilDateKey"));
+
+        info("Get command result: " + ret);
+
+        assertCacheOperation(ret, date);
+
+        java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
+
+        jcache().put("sqlDateKey", sqlDate);
+
+        ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "key", "sqlDateKey"));
+
+        info("Get SQL result: " + ret);
+
+        assertCacheOperation(ret, sqlDate.toString());
+
+        jcache().put("timestampKey", new java.sql.Timestamp(utilDate.getTime()));
+
+        ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "key", "timestampKey"));
+
+        info("Get timestamp: " + ret);
+
+        assertCacheOperation(ret, date);
     }
 
     /**
      * @throws Exception If failed.
      */
-    public void testGet() throws Exception {
-        jcache().put("getKey", "getVal");
+    public void testUUID() throws Exception {
+        UUID uuid = UUID.randomUUID();
 
-        String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "key", "getKey"));
+        jcache().put("uuidKey", uuid);
+
+        String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "key", "uuidKey"));
+
+        info("Get command result: " + ret);
+
+        assertCacheOperation(ret, uuid.toString());
+
+        IgniteUuid igniteUuid = IgniteUuid.fromUuid(uuid);
+
+        jcache().put("igniteUuidKey", igniteUuid);
+
+        ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "key", "igniteUuidKey"));
+
+        info("Get command result: " + ret);
+
+        assertCacheOperation(ret, igniteUuid.toString());
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTuple() throws Exception {
+        T2 t = new T2("key", "value");
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        jcache().put("tupleKey", t);
+
+        String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "key", "tupleKey"));
 
         info("Get command result: " + ret);
 
-        jsonEquals(ret, cachePattern("getVal", true));
+        JsonNode res = jsonCacheOperationResponse(ret, false);
+
+        assertEquals(t.getKey(), res.get("key").asText());
+        assertEquals(t.getValue(), res.get("value").asText());
     }
 
     /**
@@ -344,12 +449,9 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_SIZE.key()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Size command result: " + ret);
 
-        jsonEquals(ret, cacheBulkPattern(1, true));
+        assertCacheBulkOperation(ret, 1);
     }
 
     /**
@@ -358,12 +460,9 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testIgniteName() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.NAME.key()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Name command result: " + ret);
 
-        jsonEquals(ret, stringPattern(getTestGridName(0), true));
+        assertEquals(getTestGridName(0), jsonResponse(ret).asText());
     }
 
     /**
@@ -372,17 +471,13 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testGetOrCreateCache() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.GET_OR_CREATE_CACHE.key(), "cacheName", "testCache"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Name command result: " + ret);
 
         grid(0).cache("testCache").put("1", "1");
 
         ret = content(F.asMap("cmd", GridRestCommand.DESTROY_CACHE.key(), "cacheName", "testCache"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        assertTrue(jsonResponse(ret).isNull());
 
         assertNull(grid(0).cache("testCache"));
     }
@@ -391,20 +486,19 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
      * @throws Exception If failed.
      */
     public void testGetAll() throws Exception {
-        jcache().put("getKey1", "getVal1");
-        jcache().put("getKey2", "getVal2");
+        final Map<String, String> entries = F.asMap("getKey1", "getVal1", "getKey2", "getVal2");
 
-        String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET_ALL.key(), "k1", "getKey1", "k2", "getKey2"));
+        jcache().putAll(entries);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET_ALL.key(), "k1", "getKey1", "k2", "getKey2"));
 
         info("Get all command result: " + ret);
 
-        jsonEquals(ret,
-            // getKey[12] is used since the order is not determined.
-            cacheBulkPattern("\\{\\\"getKey[12]\\\":\\\"getVal[12]\\\"\\,\\\"getKey[12]\\\":\\\"getVal[12]\\\"\\}",
-                true));
+        JsonNode res = jsonCacheOperationResponse(ret, true);
+
+        assertTrue(res.isObject());
+
+        assertTrue(entries.equals(JSON_MAPPER.treeToValue(res, Map.class)));
     }
 
     /**
@@ -413,9 +507,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testIncorrectPut() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_PUT.key(), "key", "key0"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-        jsonEquals(ret, errorPattern("Failed to find mandatory parameter in request: val"));
+        assertResponseContainsError(ret, "Failed to find mandatory parameter in request: val");
     }
 
     /**
@@ -426,10 +518,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_CONTAINS_KEY.key(), "key", "key0"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -442,10 +531,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_CONTAINS_KEYS.key(),
             "k1", "key0", "k2", "key1"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cacheBulkPattern(true, true));
+        assertCacheBulkOperation(ret, true);
     }
 
     /**
@@ -456,10 +542,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET_AND_PUT.key(), "key", "key0", "val", "val1"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern("val0", true));
+        assertCacheOperation(ret, "val0");
 
         assertEquals("val1", grid(0).cache(null).get("key0"));
     }
@@ -473,10 +556,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET_AND_PUT_IF_ABSENT.key(),
             "key", "key0", "val", "val1"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern("val0", true));
+        assertCacheOperation(ret, "val0");
 
         assertEquals("val0", grid(0).cache(null).get("key0"));
     }
@@ -488,10 +568,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_PUT_IF_ABSENT.key(),
             "key", "key0", "val", "val1"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("val1", grid(0).cache(null).get("key0"));
     }
@@ -505,20 +582,14 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_REMOVE_VALUE.key(),
             "key", "key0", "val", "val1"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(false, true));
+        assertCacheOperation(ret, false);
 
         assertEquals("val0", grid(0).cache(null).get("key0"));
 
         ret = content(F.asMap("cmd", GridRestCommand.CACHE_REMOVE_VALUE.key(),
             "key", "key0", "val", "val0"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertNull(grid(0).cache(null).get("key0"));
     }
@@ -532,10 +603,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET_AND_REMOVE.key(),
             "key", "key0"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern("val0", true));
+        assertCacheOperation(ret, "val0");
 
         assertNull(grid(0).cache(null).get("key0"));
     }
@@ -549,20 +617,14 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_REPLACE_VALUE.key(),
             "key", "key0", "val", "val1", "val2", "val2"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(false, true));
+        assertCacheOperation(ret, false);
 
         assertEquals("val0", grid(0).cache(null).get("key0"));
 
         ret = content(F.asMap("cmd", GridRestCommand.CACHE_REPLACE_VALUE.key(),
             "key", "key0", "val", "val1", "val2", "val0"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("val1", grid(0).cache(null).get("key0"));
     }
@@ -576,10 +638,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET_AND_REPLACE.key(),
             "key", "key0", "val", "val1"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern("val0", true));
+        assertCacheOperation(ret, "val0");
 
         assertEquals("val1", grid(0).cache(null).get("key0"));
     }
@@ -591,14 +650,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_PUT.key(),
             "key", "putKey", "val", "putVal"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Put command result: " + ret);
 
         assertEquals("putVal", jcache().localPeek("putKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -608,10 +664,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_PUT.key(),
             "key", "putKey", "val", "putVal", "exp", "2000"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("putVal", jcache().get("putKey"));
 
@@ -629,10 +682,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_ADD.key(),
             "key", "addKey2", "val", "addVal2"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("addVal1", jcache().localPeek("addKey1", CachePeekMode.ONHEAP));
         assertEquals("addVal2", jcache().localPeek("addKey2", CachePeekMode.ONHEAP));
@@ -645,10 +695,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_ADD.key(),
             "key", "addKey", "val", "addVal", "exp", "2000"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("addVal", jcache().get("addKey"));
 
@@ -665,15 +712,12 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
             "k1", "putKey1", "k2", "putKey2",
             "v1", "putVal1", "v2", "putVal2"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Put all command result: " + ret);
 
         assertEquals("putVal1", jcache().localPeek("putKey1", CachePeekMode.ONHEAP));
         assertEquals("putVal2", jcache().localPeek("putKey2", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cacheBulkPattern(true, true));
+        assertCacheBulkOperation(ret, true);
     }
 
     /**
@@ -687,14 +731,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_REMOVE.key(),
             "key", "rmvKey"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Remove command result: " + ret);
 
         assertNull(jcache().localPeek("rmvKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -714,9 +755,6 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_REMOVE_ALL.key(),
             "k1", "rmvKey1", "k2", "rmvKey2"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Remove all command result: " + ret);
 
         assertNull(jcache().localPeek("rmvKey1", CachePeekMode.ONHEAP));
@@ -724,13 +762,10 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         assertEquals("rmvVal3", jcache().localPeek("rmvKey3", CachePeekMode.ONHEAP));
         assertEquals("rmvVal4", jcache().localPeek("rmvKey4", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cacheBulkPattern(true, true));
+        assertCacheBulkOperation(ret, true);
 
         ret = content(F.asMap("cmd", GridRestCommand.CACHE_REMOVE_ALL.key()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Remove all command result: " + ret);
 
         assertNull(jcache().localPeek("rmvKey1", CachePeekMode.ONHEAP));
@@ -739,7 +774,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         assertNull(jcache().localPeek("rmvKey4", CachePeekMode.ONHEAP));
         assertTrue(jcache().localSize() == 0);
 
-        jsonEquals(ret, cacheBulkPattern(true, true));
+        assertCacheBulkOperation(ret, true);
     }
 
     /**
@@ -753,14 +788,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_CAS.key(),
             "key", "casKey", "val2", "casOldVal", "val1", "casNewVal"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("CAS command result: " + ret);
 
         assertEquals("casNewVal", jcache().localPeek("casKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         jcache().remove("casKey");
     }
@@ -776,14 +808,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_REPLACE.key(),
             "key", "repKey", "val", "repVal"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Replace command result: " + ret);
 
         assertEquals("repVal", jcache().localPeek("repKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -797,10 +826,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_REPLACE.key(),
             "key", "replaceKey", "val", "replaceValNew", "exp", "2000"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("replaceValNew", jcache().get("replaceKey"));
 
@@ -819,10 +845,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_APPEND.key(),
             "key", "appendKey", "val", "_suffix"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("appendVal_suffix", jcache().get("appendKey"));
     }
@@ -836,10 +859,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_PREPEND.key(),
             "key", "prependKey", "val", "prefix_"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("prefix_prependVal", jcache().get("prependKey"));
     }
@@ -851,20 +871,16 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.ATOMIC_INCREMENT.key(),
             "key", "incrKey", "init", "2", "delta", "3"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, integerPattern(5, true));
+        JsonNode res = jsonResponse(ret);
 
+        assertEquals(5, res.asInt());
         assertEquals(5, grid(0).atomicLong("incrKey", 0, true).get());
 
         ret = content(F.asMap("cmd", GridRestCommand.ATOMIC_INCREMENT.key(), "key", "incrKey", "delta", "10"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, integerPattern(15, true));
+        res = jsonResponse(ret);
 
+        assertEquals(15, res.asInt());
         assertEquals(15, grid(0).atomicLong("incrKey", 0, true).get());
     }
 
@@ -875,21 +891,17 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.ATOMIC_DECREMENT.key(),
             "key", "decrKey", "init", "15", "delta", "10"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, integerPattern(5, true));
+        JsonNode res = jsonResponse(ret);
 
+        assertEquals(5, res.asInt());
         assertEquals(5, grid(0).atomicLong("decrKey", 0, true).get());
 
         ret = content(F.asMap("cmd", GridRestCommand.ATOMIC_DECREMENT.key(),
             "key", "decrKey", "delta", "3"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, integerPattern(2, true));
+        res = jsonResponse(ret);
 
+        assertEquals(2, res.asInt());
         assertEquals(2, grid(0).atomicLong("decrKey", 0, true).get());
     }
 
@@ -904,14 +916,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_CAS.key(),
             "key", "casKey", "val2", "casOldVal"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("CAR command result: " + ret);
 
         assertNull(jcache().localPeek("casKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -923,14 +932,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_CAS.key(),
             "key", "casKey", "val1", "casNewVal"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("PutIfAbsent command result: " + ret);
 
         assertEquals("casNewVal", jcache().localPeek("casKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -943,14 +949,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_CAS.key(), "key", "casKey"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("CAS Remove command result: " + ret);
 
         assertNull(jcache().localPeek("casKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -959,12 +962,9 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testMetrics() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_METRICS.key()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Cache metrics command result: " + ret);
 
-        jsonEquals(ret, cacheMetricsPattern("\\{.+\\}", true));
+        assertCacheMetrics(ret);
     }
 
     /**
@@ -981,20 +981,16 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Cache metadata result: " + ret);
 
-        jsonEquals(ret, pattern("\\[.+\\]", true));
-
-        Collection<Map> results = (Collection)JSONObject.fromObject(ret).get("response");
+        JsonNode arr = jsonResponse(ret);
 
-        assertEquals(metas.size(), results.size());
-        assertEquals(cacheNameArg, F.first(results).get("cacheName"));
+        assertTrue(arr.isArray());
+        assertEquals(metas.size(), arr.size());
 
-        for (Map res : results) {
-            final Object cacheName = res.get("cacheName");
+        for (JsonNode item : arr) {
+            JsonNode cacheNameNode = item.get("cacheName");
+            final String cacheName = cacheNameNode != null ? cacheNameNode.asText() : null;
 
             GridCacheSqlMetadata meta = F.find(metas, null, new P1<GridCacheSqlMetadata>() {
                 @Override public boolean apply(GridCacheSqlMetadata meta) {
@@ -1004,49 +1000,60 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
             assertNotNull("REST return metadata for unexpected cache: " + cacheName, meta);
 
-            Collection types = (Collection)res.get("types");
+            JsonNode types = item.get("types");
 
             assertNotNull(types);
-            assertEqualsCollections(meta.types(), types);
+            assertFalse(types.isNull());
 
-            Map keyClasses = (Map)res.get("keyClasses");
+            assertEqualsCollections(meta.types(), JSON_MAPPER.treeToValue(types, Collection.class));
+
+            JsonNode keyClasses = item.get("keyClasses");
 
             assertNotNull(keyClasses);
-            assertTrue(meta.keyClasses().equals(keyClasses));
+            assertFalse(keyClasses.isNull());
+
+            assertTrue(meta.keyClasses().equals(JSON_MAPPER.treeToValue(keyClasses, Map.class)));
 
-            Map valClasses = (Map)res.get("valClasses");
+            JsonNode valClasses = item.get("valClasses");
 
             assertNotNull(valClasses);
-            assertTrue(meta.valClasses().equals(valClasses));
+            assertFalse(valClasses.isNull());
+
+            assertTrue(meta.valClasses().equals(JSON_MAPPER.treeToValue(valClasses, Map.class)));
 
-            Map fields = (Map)res.get("fields");
+            JsonNode fields = item.get("fields");
 
             assertNotNull(fields);
-            assertTrue(meta.fields().equals(fields));
+            assertFalse(fields.isNull());
+            assertTrue(meta.fields().equals(JSON_MAPPER.treeToValue(fields, Map.class)));
 
-            Map indexesByType = (Map)res.get("indexes");
+            JsonNode indexesByType = item.get("indexes");
 
             assertNotNull(indexesByType);
+            assertFalse(indexesByType.isNull());
             assertEquals(meta.indexes().size(), indexesByType.size());
 
             for (Map.Entry<String, Collection<GridCacheSqlIndexMetadata>> metaIndexes : meta.indexes().entrySet()) {
-                Collection<Map> indexes = (Collection<Map>)indexesByType.get(metaIndexes.getKey());
+                JsonNode indexes = indexesByType.get(metaIndexes.getKey());
 
                 assertNotNull(indexes);
+                assertFalse(indexes.isNull());
                 assertEquals(metaIndexes.getValue().size(), indexes.size());
 
                 for (final GridCacheSqlIndexMetadata metaIdx : metaIndexes.getValue()) {
-                    Map idx = F.find(indexes, null, new P1<Map>() {
-                        @Override public boolean apply(Map map) {
-                            return metaIdx.name().equals(map.get("name"));
+                    JsonNode idx = F.find(indexes, null, new P1<JsonNode>() {
+                        @Override public boolean apply(JsonNode idx) {
+                            return metaIdx.name().equals(idx.get("name").asText());
                         }
                     });
 
                     assertNotNull(idx);
 
-                    assertEqualsCollections(metaIdx.fields(), (Collection)idx.get("fields"));
-                    assertEqualsCollections(metaIdx.descendings(), (Collection)idx.get("descendings"));
-                    assertEquals(metaIdx.unique(), idx.get("unique"));
+                    assertEqualsCollections(metaIdx.fields(),
+                        JSON_MAPPER.treeToValue(idx.get("fields"), Collection.class));
+                    assertEqualsCollections(metaIdx.descendings(),
+                        JSON_MAPPER.treeToValue(idx.get("descendings"), Collection.class));
+                    assertEquals(metaIdx.unique(), idx.get("unique").asBoolean());
                 }
             }
         }
@@ -1087,32 +1094,28 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testTopology() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.TOPOLOGY.key(), "attr", "false", "mtr", "false"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Topology command result: " + ret);
 
-        jsonEquals(ret, pattern("\\[\\{.+\\}\\]", true));
-
-        JSONObject json = JSONObject.fromObject(ret);
+        JsonNode res = jsonResponse(ret);
 
-        Collection<Map> nodes = (Collection)json.get("response");
+        assertEquals(GRID_CNT, res.size());
 
-        assertEquals(GRID_CNT, nodes.size());
+        for (JsonNode node : res) {
+            assertTrue(node.get("attributes").isNull());
+            assertTrue(node.get("metrics").isNull());
 
-        for (Map node : nodes) {
-            assertEquals(JSONNull.getInstance(), node.get("attributes"));
-            assertEquals(JSONNull.getInstance(), node.get("metrics"));
+            JsonNode caches = node.get("caches");
 
-            Collection<Map> caches = (Collection)node.get("caches");
+            assertFalse(caches.isNull());
 
             Collection<IgniteCacheProxy<?, ?>> publicCaches = grid(0).context().cache().publicCaches();
 
-            assertNotNull(caches);
             assertEquals(publicCaches.size(), caches.size());
 
-            for (Map cache : caches) {
-                final String cacheName = cache.get("name").equals("") ? null : (String)cache.get("name");
+            for (JsonNode cache : caches) {
+                String cacheName0 = cache.get("name").asText();
+
+                final String cacheName = cacheName0.equals("") ? null : cacheName0;
 
                 IgniteCacheProxy<?, ?> publicCache = F.find(publicCaches, null, new P1<IgniteCacheProxy<?, ?>>() {
                     @Override public boolean apply(IgniteCacheProxy<?, ?> c) {
@@ -1122,9 +1125,9 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
                 assertNotNull(publicCache);
 
-                CacheMode cacheMode = CacheMode.valueOf((String)cache.get("mode"));
+                CacheMode cacheMode = CacheMode.valueOf(cache.get("mode").asText());
 
-                assertEquals(publicCache.getConfiguration(CacheConfiguration.class).getCacheMode(),cacheMode);
+                assertEquals(publicCache.getConfiguration(CacheConfiguration.class).getCacheMode(), cacheMode);
             }
         }
     }
@@ -1136,31 +1139,30 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.NODE.key(), "attr", "true", "mtr", "true", "id",
             grid(0).localNode().id().toString()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Topology command result: " + ret);
 
-        jsonEquals(ret, pattern("\\{.+\\}", true));
+        JsonNode res = jsonResponse(ret);
 
-        ret = content(F.asMap("cmd", GridRestCommand.NODE.key(), "attr", "false", "mtr", "false", "ip", LOC_HOST));
+        assertTrue(res.get("attributes").isObject());
+        assertTrue(res.get("metrics").isObject());
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        ret = content(F.asMap("cmd", GridRestCommand.NODE.key(), "attr", "false", "mtr", "false", "ip", LOC_HOST));
 
         info("Topology command result: " + ret);
 
-        jsonEquals(ret, pattern("\\{.+\\}", true));
+        res = jsonResponse(ret);
+
+        assertTrue(res.get("attributes").isNull());
+        assertTrue(res.get("metrics").isNull());
 
         ret = content(F.asMap("cmd", GridRestCommand.NODE.key(), "attr", "false", "mtr", "false", "ip", LOC_HOST, "id",
             UUID.randomUUID().toString()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Topology command result: " + ret);
 
-        jsonEquals(ret, pattern("null", true));
+        res = jsonResponse(ret);
+
+        assertTrue(res.isNull());
     }
 
     /**
@@ -1173,52 +1175,41 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testExe() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.EXE.key()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Exe command result: " + ret);
 
-        jsonEquals(ret, pattern("null", false));
+        assertResponseContainsError(ret);
 
         // Attempt to execute unknown task (UNKNOWN_TASK) will result in exception on server.
         ret = content(F.asMap("cmd", GridRestCommand.EXE.key(), "name", "UNKNOWN_TASK"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Exe command result: " + ret);
 
-        jsonEquals(ret, pattern("null", false));
+        assertResponseContainsError(ret);
 
         grid(0).compute().localDeployTask(TestTask1.class, TestTask1.class.getClassLoader());
         grid(0).compute().localDeployTask(TestTask2.class, TestTask2.class.getClassLoader());
 
         ret = content(F.asMap("cmd", GridRestCommand.EXE.key(), "name", TestTask1.class.getName()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Exe command result: " + ret);
 
-        jsonEquals(ret, pattern("\\{.+\\}", true));
+        JsonNode res = jsonTaskResult(ret);
 
-        ret = content(F.asMap("cmd", GridRestCommand.EXE.key(), "name", TestTask2.class.getName()));
+        assertTrue(res.isNull());
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        ret = content(F.asMap("cmd", GridRestCommand.EXE.key(), "name", TestTask2.class.getName()));
 
         info("Exe command result: " + ret);
 
-        jsonEquals(ret, pattern("\\{.+" + TestTask2.RES + ".+\\}", true));
+        res = jsonTaskResult(ret);
 
-        ret = content(F.asMap("cmd", GridRestCommand.RESULT.key()));
+        assertEquals(TestTask2.RES, res.asText());
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        ret = content(F.asMap("cmd", GridRestCommand.RESULT.key()));
 
         info("Exe command result: " + ret);
 
-        jsonEquals(ret, pattern("null", false));
+        assertResponseContainsError(ret);
     }
 
     /**
@@ -1229,9 +1220,6 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testVisorGateway() throws Exception {
         ClusterNode locNode = grid(1).localNode();
 
-        final String successRes = pattern(
-            "\\{\\\"error\\\":\\\"\\\",\\\"finished\\\":true,\\\"id\\\":\\\"[^\\\"]+\\\",\\\"result\\\":.+}", true);
-
         final IgniteUuid cid = grid(1).context().cache().internalCache("person").context().dynamicDeploymentId();
 
         String ret = content(new VisorGatewayArgument(VisorCacheConfigurationCollectorTask.class)
@@ -1240,10 +1228,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheConfigurationCollectorTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheNodesTask.class)
             .forNode(locNode)
@@ -1251,10 +1236,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheNodesTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheLoadTask.class)
             .forNode(locNode)
@@ -1262,10 +1244,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheLoadTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheSwapBackupsTask.class)
             .forNode(locNode)
@@ -1273,10 +1252,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheSwapBackupsTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheRebalanceTask.class)
             .forNode(locNode)
@@ -1284,10 +1260,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheRebalanceTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheMetadataTask.class)
             .forNode(locNode)
@@ -1295,10 +1268,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheMetadataTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheResetMetricsTask.class)
             .forNode(locNode)
@@ -1306,10 +1276,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheResetMetricsTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorIgfsSamplingStateTask.class)
             .forNode(locNode)
@@ -1317,10 +1284,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorIgfsSamplingStateTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorIgfsProfilerClearTask.class)
             .forNode(locNode)
@@ -1328,10 +1292,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorIgfsProfilerClearTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorIgfsProfilerTask.class)
             .forNode(locNode)
@@ -1339,10 +1300,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorIgfsProfilerTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorIgfsFormatTask.class)
             .forNode(locNode)
@@ -1350,10 +1308,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorIgfsFormatTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorIgfsResetMetricsTask.class)
             .forNode(locNode)
@@ -1361,20 +1316,14 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorIgfsResetMetricsTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorThreadDumpTask.class)
             .forNode(locNode));
 
         info("VisorThreadDumpTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorLatestTextFilesTask.class)
             .forNode(locNode)
@@ -1382,20 +1331,14 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorLatestTextFilesTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorLatestVersionTask.class)
             .forNode(locNode));
 
         info("VisorLatestVersionTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorFileBlockTask.class)
             .forNode(locNode)
@@ -1403,10 +1346,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorFileBlockTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorNodePingTask.class)
             .forNode(locNode)
@@ -1414,45 +1354,31 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorNodePingTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorNodeConfigurationCollectorTask.class)
             .forNode(locNode));
 
         info("VisorNodeConfigurationCollectorTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorComputeResetMetricsTask.class)
             .forNode(locNode));
 
         info("VisorComputeResetMetricsTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorQueryTask.class)
             .forNode(locNode)
-            .argument(VisorQueryArg.class, "person", URLEncoder.encode("select * from Person"), false, 1));
+            .argument(VisorQueryArg.class, "person", URLEncoder.encode("select * from Person", CHARSET), false, 1));
 
         info("VisorQueryTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        JsonNode res = jsonTaskResult(ret);
 
-        jsonEquals(ret, successRes);
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        final String qryId = (String)((Map)((Map)((Map)json.get("response")).get("result")).get("value")).get("queryId");
+        final String qryId = res.get("value").get("queryId").asText();
 
         ret = content(new VisorGatewayArgument(VisorQueryNextPageTask.class)
             .forNode(locNode)
@@ -1460,30 +1386,21 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorQueryNextPageTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorQueryCleanupTask.class)
             .map(UUID.class, Set.class, F.asMap(locNode.id(), qryId)));
 
         info("VisorQueryCleanupTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorResolveHostNameTask.class)
             .forNode(locNode));
 
         info("VisorResolveHostNameTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         // Multinode tasks
 
@@ -1492,10 +1409,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorComputeCancelSessionsTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheMetricsCollectorTask.class)
             .pair(Boolean.class, Set.class, false, "person"));
@@ -1508,39 +1422,27 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheMetricsCollectorTask (with nodes) result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorLogSearchTask.class)
             .argument(VisorLogSearchTask.VisorLogSearchArg.class, ".", ".", "abrakodabra.txt", 1));
 
         info("VisorLogSearchTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorNodeGcTask.class));
 
         info("VisorNodeGcTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorAckTask.class)
             .argument("MSG"));
 
         info("VisorAckTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorNodeEventsCollectorTask.class)
             .argument(VisorNodeEventsCollectorTask.VisorNodeEventsCollectorTaskArg.class,
@@ -1548,10 +1450,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorNodeEventsCollectorTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorNodeDataCollectorTask.class)
             .argument(VisorNodeDataCollectorTaskArg.class, false,
@@ -1559,30 +1458,21 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorNodeDataCollectorTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorComputeToggleMonitoringTask.class)
             .pair(String.class, Boolean.class, UUID.randomUUID(), false));
 
         info("VisorComputeToggleMonitoringTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorNodeSuppressedErrorsTask.class)
             .map(UUID.class, Long.class, new HashMap()));
 
         info("VisorNodeSuppressedErrorsTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheClearTask.class)
             .forNode(locNode)
@@ -1590,10 +1480,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheClearTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         /** Spring XML to start cache via Visor task. */
         final String START_CACHE =
@@ -1608,14 +1495,12 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
                     "</beans>";
 
         ret = content(new VisorGatewayArgument(VisorCacheStartTask.class)
-            .argument(VisorCacheStartTask.VisorCacheStartArg.class, false, "person2", URLEncoder.encode(START_CACHE)));
+            .argument(VisorCacheStartTask.VisorCacheStartArg.class, false, "person2",
+                URLEncoder.encode(START_CACHE, CHARSET)));
 
         info("VisorCacheStartTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheStopTask.class)
             .forNode(locNode)
@@ -1623,10 +1508,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheStopTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
     }
 
     /**
@@ -1635,10 +1517,9 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testVersion() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.VERSION.key()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        JsonNode res = jsonResponse(ret);
 
-        jsonEquals(ret, stringPattern(".+", true));
+        assertEquals(VER_STR, res.asText());
     }
 
     /**
@@ -1652,18 +1533,13 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         params.put("type", "Person");
         params.put("pageSize", "10");
         params.put("cacheName", "person");
-        params.put("qry", URLEncoder.encode(qry));
+        params.put("qry", URLEncoder.encode(qry, CHARSET));
         params.put("arg1", "1000");
         params.put("arg2", "2000");
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        List items = (List)((Map)json.get("response")).get("items");
+        JsonNode items = jsonResponse(ret).get("items");
 
         assertEquals(2, items.size());
 
@@ -1681,12 +1557,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        List items = (List)((Map)json.get("response")).get("items");
+        JsonNode items = jsonResponse(ret).get("items");
 
         assertEquals(4, items.size());
 
@@ -1705,12 +1576,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        List items = (List)((Map)json.get("response")).get("items");
+        JsonNode items = jsonResponse(ret).get("items");
 
         assertEquals(2, items.size());
 
@@ -1721,22 +1587,17 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
      * @throws Exception If failed.
      */
     public void testIncorrectFilterQueryScan() throws Exception {
+        String clsName = ScanFilter.class.getName() + 1;
+
         Map<String, String> params = new HashMap<>();
         params.put("cmd", GridRestCommand.EXECUTE_SCAN_QUERY.key());
         params.put("pageSize", "10");
         params.put("cacheName", "person");
-        params.put("className", ScanFilter.class.getName() + 1);
+        params.put("className", clsName);
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        String err = (String)json.get("error");
-
-        assertTrue(err.contains("Failed to find target class"));
+        assertResponseContainsError(ret, "Failed to find target class: " + clsName);
     }
 
     /**
@@ -1751,42 +1612,33 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         params.put("cmd", GridRestCommand.EXECUTE_SQL_QUERY.key());
         params.put("type", "String");
         params.put("pageSize", "1");
-        params.put("qry", URLEncoder.encode("select * from String"));
+        params.put("qry", URLEncoder.encode("select * from String", CHARSET));
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        Integer qryId = (Integer)((Map)json.get("response")).get("queryId");
+        JsonNode qryId = jsonResponse(ret).get("queryId");
 
-        assertNotNull(qryId);
+        assertFalse(jsonResponse(ret).get("queryId").isNull());
 
         ret = content(F.asMap("cmd", GridRestCommand.FETCH_SQL_QUERY.key(),
-            "pageSize", "1", "qryId", String.valueOf(qryId)));
+            "pageSize", "1", "qryId", qryId.asText()));
 
-        json = JSONObject.fromObject(ret);
+        JsonNode res = jsonResponse(ret);
 
-        Integer qryId0 = (Integer)((Map)json.get("response")).get("queryId");
-
-        Boolean last = (Boolean)((Map)json.get("response")).get("last");
+        JsonNode qryId0 = jsonResponse(ret).get("queryId");
 
         assertEquals(qryId0, qryId);
-        assertFalse(last);
+        assertFalse(res.get("last").asBoolean());
 
         ret = content(F.asMap("cmd", GridRestCommand.FETCH_SQL_QUERY.key(),
-            "pageSize", "1", "qryId", String.valueOf(qryId)));
-
-        json = JSONObject.fromObject(ret);
+            "pageSize", "1", "qryId", qryId.asText()));
 
-        qryId0 = (Integer)((Map)json.get("response")).get("queryId");
+        res = jsonResponse(ret);
 
-        last = (Boolean)((Map)json.get("response")).get("last");
+        qryId0 = jsonResponse(ret).get("queryId");
 
         assertEquals(qryId0, qryId);
-        assertTrue(last);
+        assertTrue(res.get("last").asBoolean());
 
         assertFalse(queryCursorFound());
     }
@@ -1801,16 +1653,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         params.put("cmd", GridRestCommand.EXECUTE_SQL_FIELDS_QUERY.key());
         params.put("pageSize", "10");
         params.put("cacheName", "person");
-        params.put("qry", URLEncoder.encode(qry));
+        params.put("qry", URLEncoder.encode(qry, CHARSET));
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        List items = (List)((Map)json.get("response")).get("items");
+        JsonNode items = jsonResponse(ret).get("items");
 
         assertEquals(4, items.size());
 
@@ -1827,29 +1674,25 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         params.put("cmd", GridRestCommand.EXECUTE_SQL_FIELDS_QUERY.key());
         params.put("pageSize", "10");
         params.put("cacheName", "person");
-        params.put("qry", URLEncoder.encode(qry));
+        params.put("qry", URLEncoder.encode(qry, CHARSET));
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        JsonNode res = jsonResponse(ret);
 
-        JSONObject json = JSONObject.fromObject(ret);
+        JsonNode items = res.get("items");
 
-        List items = (List)((Map)json.get("response")).get("items");
-
-        List meta = (List)((Map)json.get("response")).get("fieldsMetadata");
+        JsonNode meta = res.get("fieldsMetadata");
 
         assertEquals(4, items.size());
-
         assertEquals(2, meta.size());
 
-        JSONObject o = (JSONObject)meta.get(0);
+        JsonNode o = meta.get(0);
 
-        assertEquals("FIRSTNAME", o.get("fieldName"));
-        assertEquals("java.lang.String", o.get("fieldTypeName"));
-        assertEquals("person", o.get("schemaName"));
-        assertEquals("PERSON", o.get("typeName"));
+        assertEquals("FIRSTNAME", o.get("fieldName").asText());
+        assertEquals("java.lang.String", o.get("fieldTypeName").asText());
+        assertEquals("person", o.get("schemaName").asText());
+        assertEquals("PERSON", o.get("typeName").asText());
 
         assertFalse(queryCursorFound());
     }
@@ -1865,32 +1708,23 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         params.put("type", "Person");
         params.put("pageSize", "1");
         params.put("cacheName", "person");
-        params.put("qry", URLEncoder.encode(qry));
+        params.put("qry", URLEncoder.encode(qry, CHARSET));
         params.put("arg1", "1000");
         params.put("arg2", "2000");
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
+        JsonNode res = jsonResponse(ret);
 
-        List items = (List)((Map)json.get("response")).get("items");
-
-        assertEquals(1, items.size());
+        assertEquals(1, res.get("items").size());
 
         assertTrue(queryCursorFound());
 
-        Integer qryId = (Integer)((Map)json.get("response")).get("queryId");
-
-        assertNotNull(qryId);
+        assertFalse(res.get("queryId").isNull());
 
-        ret = content(F.asMap("cmd", GridRestCommand.CLOSE_SQL_QUERY.key(),
-            "cacheName", "person", "qryId", String.valueOf(qryId)));
+        String qryId = res.get("queryId").asText();
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        content(F.asMap("cmd", GridRestCommand.CLOSE_SQL_QUERY.key(), "cacheName", "person", "qryId", qryId));
 
         assertFalse(queryCursorFound());
     }
@@ -1906,7 +1740,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         params.put("type", "Person");
         params.put("pageSize", "1");
         params.put("cacheName", "person");
-        params.put("qry", URLEncoder.encode(qry));
+        params.put("qry", URLEncoder.encode(qry, CHARSET));
         params.put("arg1", "1000");
         params.put("arg2", "2000");
 
@@ -1915,12 +1749,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         for (int i = 0; i < 10; ++i)
             ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        List items = (List)((Map)json.get("response")).get("items");
+        JsonNode items = jsonResponse(ret).get("items");
 
         assertEquals(1, items.size());
 
@@ -2238,7 +2067,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
          * @param valCls Value class.
          * @param map Map.
          */
-        public VisorGatewayArgument map(Class keyCls, Class valCls, Map<?, ?> map) {
+        public VisorGatewayArgument map(Class keyCls, Class valCls, Map<?, ?> map) throws UnsupportedEncodingException {
             put("p" + idx++, Map.class.getName());
             put("p" + idx++, keyCls.getName());
             put("p" + idx++, valCls.getName());
@@ -2259,7 +2088,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
                 first = false;
             }
 
-            put("p" + idx++, URLEncoder.encode(sb.toString()));
+            put("p" + idx++, URLEncoder.encode(sb.toString(), CHARSET));
 
             return this;
         }
@@ -2285,7 +2114,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
             }
 
             return sb.toString();
-        };
+        }
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/SimplePerson.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/SimplePerson.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/SimplePerson.java
new file mode 100644
index 0000000..0185213
--- /dev/null
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/SimplePerson.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.rest;
+
+import java.sql.Date;
+
+/**
+ * Test class with public fields and without getters and setters.
+ */
+public class SimplePerson {
+    /** Person ID. */
+    public int id;
+
+    /** Person name. */
+    public String name;
+
+    /** Person birthday. */
+    public Date birthday;
+
+    /** Person salary. */
+    public double salary;
+
+    /** Must be excluded on serialization. */
+    public transient int age;
+
+    /** Must be excluded on serialization. */
+    protected String post;
+
+    /** Must be excluded on serialization. */
+    private int bonus;
+
+    /**
+     * Default constructor.
+     */
+    public SimplePerson() {
+        // No-op.
+    }
+
+    /**
+     * Full constructor.
+     *
+     * @param id Person ID.
+     * @param name Person name.
+     * @param birthday Person birthday.
+     * @param salary Person salary.
+     * @param age Person age.
+     * @param post Person post.
+     * @param bonus Person bonus.
+     */
+    public SimplePerson(int id, String name, Date birthday, double salary, int age, String post, int bonus) {
+        this.id = id;
+        this.name = name;
+        this.birthday = birthday;
+        this.salary = salary;
+        this.age = age;
+        this.post = post;
+        this.bonus = bonus;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/pom.xml
----------------------------------------------------------------------
diff --git a/modules/core/pom.xml b/modules/core/pom.xml
index 34368c8..5e32caf 100644
--- a/modules/core/pom.xml
+++ b/modules/core/pom.xml
@@ -76,6 +76,13 @@
         </dependency>
 
         <dependency>
+            <groupId>commons-collections</groupId>
+            <artifactId>commons-collections</artifactId>
+            <version>3.2.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
             <groupId>commons-dbcp</groupId>
             <artifactId>commons-dbcp</artifactId>
             <version>1.4</version>
@@ -153,14 +160,6 @@
         </dependency>
 
         <dependency>
-            <groupId>net.sf.json-lib</groupId>
-            <artifactId>json-lib</artifactId>
-            <version>${jsonlib.version}</version>
-            <classifier>jdk15</classifier>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
             <groupId>org.gridgain</groupId>
             <artifactId>ignite-shmem</artifactId>
             <version>1.0.0</version>

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/LessNamingBean.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/LessNamingBean.java b/modules/core/src/main/java/org/apache/ignite/internal/LessNamingBean.java
new file mode 100644
index 0000000..3b885f9
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/LessNamingBean.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal;
+
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+
+/**
+ * Marker interface for beans with less naming conventions i.e., without "get" and "set" prefixes.
+ */
+@GridToStringExclude
+public interface LessNamingBean {
+    // No-op.
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlIndexMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlIndexMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlIndexMetadata.java
index 539a156..94602f7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlIndexMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlIndexMetadata.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache.query;
 
 import java.io.Externalizable;
 import java.util.Collection;
+import org.apache.ignite.internal.LessNamingBean;
 
 /**
  * Ignite index descriptor.
@@ -27,7 +28,7 @@ import java.util.Collection;
  * {@link GridCacheSqlMetadata#indexes(String)} method.
  * @see GridCacheSqlMetadata
  */
-public interface GridCacheSqlIndexMetadata extends Externalizable {
+public interface GridCacheSqlIndexMetadata extends Externalizable, LessNamingBean {
     /**
      * Gets name of the index.
      *

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlMetadata.java
index 724962e..c82d2cb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlMetadata.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.cache.query;
 import java.io.Externalizable;
 import java.util.Collection;
 import java.util.Map;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.spi.indexing.IndexingSpi;
 import org.jetbrains.annotations.Nullable;
 
@@ -30,7 +31,7 @@ import org.jetbrains.annotations.Nullable;
  * can be used to gather information about what can
  * be queried using Ignite cache queries feature.
  */
-public interface GridCacheSqlMetadata extends Externalizable {
+public interface GridCacheSqlMetadata extends Externalizable, LessNamingBean {
     /**
      * Cache name.
      *

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteExceptionRegistry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteExceptionRegistry.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteExceptionRegistry.java
index 1c3a5b5..b7bb07e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteExceptionRegistry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteExceptionRegistry.java
@@ -26,6 +26,7 @@ import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.atomic.AtomicLong;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.S;
@@ -156,7 +157,7 @@ public class IgniteExceptionRegistry {
      * Detailed info about suppressed error.
      */
     @SuppressWarnings("PublicInnerClass")
-    public static class ExceptionInfo implements Serializable {
+    public static class ExceptionInfo implements Serializable, LessNamingBean {
         /** */
         private static final long serialVersionUID = 0L;
 
@@ -245,4 +246,4 @@ public class IgniteExceptionRegistry {
             return S.toString(ExceptionInfo.class, this);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCache.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCache.java
index f06813f..a440ac3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCache.java
@@ -21,12 +21,12 @@ import java.io.Serializable;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
-import java.util.Set;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter;
@@ -42,7 +42,7 @@ import org.jetbrains.annotations.Nullable;
 /**
  * Data transfer object for {@link IgniteCache}.
  */
-public class VisorCache implements Serializable {
+public class VisorCache implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheAffinityConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheAffinityConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheAffinityConfiguration.java
index 7aa6215..371a514 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheAffinityConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheAffinityConfiguration.java
@@ -21,6 +21,7 @@ import java.io.Serializable;
 import org.apache.ignite.cache.affinity.AffinityFunction;
 import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
 import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
 
@@ -29,7 +30,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.compactClass;
 /**
  * Data transfer object for affinity configuration properties.
  */
-public class VisorCacheAffinityConfiguration implements Serializable {
+public class VisorCacheAffinityConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -113,4 +114,4 @@ public class VisorCacheAffinityConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorCacheAffinityConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheAggregatedMetrics.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheAggregatedMetrics.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheAggregatedMetrics.java
index 0cba24b..c779051 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheAggregatedMetrics.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheAggregatedMetrics.java
@@ -23,12 +23,13 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for aggregated cache metrics.
  */
-public class VisorCacheAggregatedMetrics implements Serializable {
+public class VisorCacheAggregatedMetrics implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 


[42/50] [abbrv] ignite git commit: Ignite Web Console beta2.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger.jade
new file mode 100644
index 0000000..3406ff5
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger.jade
@@ -0,0 +1,65 @@
+//-
+    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.
+
+include ../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem.logger'
+-var form = 'logger'
+-var kind = model + '.kind'
+
+form.panel.panel-default(name=form novalidate)
+    .panel-heading(bs-collapse-toggle ng-click='ui.loadPanel("#{form}")')
+        ignite-form-panel-chevron
+        label Logger configuration
+        ignite-form-field-tooltip.tipLabel
+            | Logging functionality used throughout the system
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
+        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
+            .col-sm-6
+                .settings-row
+                    +dropdown('Logger:', kind, 'logger', 'true', 'Default',
+                        '[\
+                            {value: "Log4j", label: "Apache Log4j"},\
+                            {value: "Log4j2", label: "Apache Log4j 2"},\
+                            {value: "SLF4J", label: "Simple Logging Facade (SLF4J)"},\
+                            {value: "Java", label: "Java logger (JUL)"},\
+                            {value: "JCL", label: "Jakarta Commons Logging (JCL)"},\
+                            {value: "Null", label: "Null logger"},\
+                            {value: "Custom", label: "Custom"},\
+                            {value: undefined, label: "Default"}\
+                        ]',
+                        'Logger implementations\
+                        <ul>\
+                            <li>Apache Log4j - log4j-based logger</li>\
+                            <li>Apache Log4j 2 - Log4j2-based logger</li>\
+                            <li>Simple Logging Facade (SLF4J) - SLF4j-based logger</li>\
+                            <li>Java logger (JUL) - built in java logger</li>\
+                            <li>Jakarta Commons Logging (JCL) - wraps any JCL (Jakarta Commons Logging) loggers</li>\
+                            <li>Null logger - logger which does not output anything</li>\
+                            <li>Custom - custom logger implementation</li>\
+                            <li>Default - Apache Log4j if awailable on classpath or Java logger otherwise</li>\
+                        </ul>')
+                .settings-row(ng-show='#{kind} && (#{kind} === "Log4j2" || #{kind} === "Log4j" || #{kind} === "Custom")')
+                    .panel-details
+                        ignite-configuration-clusters-logger-log4j2(
+                            ng-show='#{kind} === "Log4j2"')
+                        ignite-configuration-clusters-logger-log4j(
+                            ng-show='#{kind} === "Log4j"')
+                        ignite-configuration-clusters-logger-custom(
+                            ng-show='#{kind} === "Custom"')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterLogger')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/custom.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/custom.directive.js b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/custom.directive.js
new file mode 100644
index 0000000..5bd586b
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/custom.directive.js
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+import template from './custom.jade!';
+
+export default ['igniteConfigurationClustersLoggerCustom', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/custom.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/custom.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/custom.jade
new file mode 100644
index 0000000..58dba15
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/custom.jade
@@ -0,0 +1,24 @@
+//-
+    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.
+
+include ../../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem.logger.Custom'
+-var required = 'backupItem.logger.kind === "Custom"'
+
+div
+    .details-row
+        +java-class('Class:', model + '.class', 'customLogger', 'true', required, 'Logger implementation class')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j.directive.js b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j.directive.js
new file mode 100644
index 0000000..64e4337
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j.directive.js
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+import template from './log4j.jade!';
+
+export default ['igniteConfigurationClustersLoggerLog4j', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j.jade
new file mode 100644
index 0000000..97f407d
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j.jade
@@ -0,0 +1,49 @@
+//-
+    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.
+
+include ../../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem.logger.Log4j'
+-var pathRequired = model + '.mode === "Path" && backupItem.logger.kind === "Log4j"'
+
+div
+    .details-row
+        +dropdown('Level:', model + '.level', 'log4jLevel', 'true', 'Default',
+            '[\
+                {value: "OFF", label: "OFF"},\
+                {value: "FATAL", label: "FATAL"},\
+                {value: "ERROR", label: "ERROR"},\
+                {value: "WARN", label: "WARN"},\
+                {value: "INFO", label: "INFO"},\
+                {value: "DEBUG", label: "DEBUG"},\
+                {value: "TRACE", label: "TRACE"},\
+                {value: "ALL", label: "ALL"},\
+                {value: undefined, label: "Default"}\
+            ]',
+            'Level for internal log4j implementation')
+    .details-row
+        +dropdown-required('Logger configuration:', model + '.mode', 'log4jMode', 'true', 'true', 'Choose logger mode',
+            '[\
+                {value: "Default", label: "Default"},\
+                {value: "Path", label: "Path"}\
+            ]',
+            'Choose logger configuration\
+            <ul>\
+                <li>Default - default logger</li>\
+                <li>Path - path or URI to XML configuration</li>\
+            </ul>')
+    .details-row(ng-show=pathRequired)
+        +text('Path:', model + '.path', 'log4jPath', pathRequired, 'Input path', 'Path or URI to XML configuration')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j2.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j2.directive.js b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j2.directive.js
new file mode 100644
index 0000000..ad891f7
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j2.directive.js
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+import template from './log4j2.jade!';
+
+export default ['igniteConfigurationClustersLoggerLog4j2', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j2.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j2.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j2.jade
new file mode 100644
index 0000000..b4cea90
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger/log4j2.jade
@@ -0,0 +1,38 @@
+//-
+    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.
+
+include ../../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem.logger.Log4j2'
+-var log4j2Required = 'backupItem.logger.kind === "Log4j2"'
+
+div
+    .details-row
+        +dropdown('Level:', model + '.level', 'log4j2Level', 'true', 'Default',
+            '[\
+                {value: "OFF", label: "OFF"},\
+                {value: "FATAL", label: "FATAL"},\
+                {value: "ERROR", label: "ERROR"},\
+                {value: "WARN", label: "WARN"},\
+                {value: "INFO", label: "INFO"},\
+                {value: "DEBUG", label: "DEBUG"},\
+                {value: "TRACE", label: "TRACE"},\
+                {value: "ALL", label: "ALL"},\
+                {value: undefined, label: "Default"}\
+            ]',
+            'Level for internal log4j2 implementation')
+    .details-row
+        +text('Path:', model + '.path', 'log4j2Path', log4j2Required, 'Input path', 'Path or URI to XML configuration')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/domains/query.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/domains/query.jade b/modules/web-console/src/main/js/app/modules/states/configuration/domains/query.jade
index 9974417..f66de92 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/domains/query.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/domains/query.jade
@@ -62,7 +62,7 @@ form.panel.panel-default(name='query' novalidate)
                 .content-not-available(ng-if='#{model}.queryMetadata === "Annotations"')
                     label Not available for annotated types
                 div(ng-if='#{model}.queryMetadata === "Configuration"')
-                    .settings-row(ng-init='queryFieldsTbl={type: "fields", model: "fields", focusId: "QryField", ui: "table-pair", keyName: "name", valueName: "className"}')
+                    .settings-row
                         ignite-form-group(ng-model='#{queryFields}' ng-form='#{queryFieldsForm}')
                             ignite-form-field-label(id='queryFields')
                                 | Fields
@@ -85,7 +85,7 @@ form.panel.panel-default(name='query' novalidate)
                                         tr
                                             td.col-sm-12
                                                 +table-pair-edit('queryFieldsTbl', 'new', 'Field name', 'Field full class name', false, true, '{{::queryFieldsTbl.focusId + $index}}', '-1', '/')
-                    .settings-row(ng-init='aliasesTbl={type: "aliases", model: "aliases", focusId: "Alias", ui: "table-pair", keyName: "field", valueName: "alias"}')
+                    .settings-row
                         ignite-form-group(ng-model='#{queryAliases}' ng-form='#{queryAliasesForm}')
                             ignite-form-field-label
                                 | Aliases

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/domains/store.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/domains/store.jade b/modules/web-console/src/main/js/app/modules/states/configuration/domains/store.jade
index c6c3351..d2a1dc6 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/domains/store.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/domains/store.jade
@@ -66,7 +66,7 @@ form.panel.panel-default(name=form novalidate)
         ignite-form-panel-chevron
         label Domain model for cache store
         ignite-form-field-tooltip.tipLabel
-            | Domain model properties for fields queries
+            | Domain model properties for binding database with cache via POJO cache store
         ignite-form-revert
     .panel-collapse(role='tabpanel' bs-collapse-target id=form)
         .panel-body(ng-if='ui.isPanelLoaded("#{form}")')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/igfs/misc.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/igfs/misc.jade b/modules/web-console/src/main/js/app/modules/states/configuration/igfs/misc.jade
index 7cc0354..fd42805 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/igfs/misc.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/igfs/misc.jade
@@ -79,7 +79,7 @@ form.panel.panel-default(name=form novalidate)
                         'If value of this flag is <b>true</b>, IGFS will skip expensive consistency checks. It is recommended to set\
                         this flag to <b>false</b>b> if your application has conflicting operations, or you do not how exactly users will\
                         use your system.')
-                .settings-row(ng-init='tblPathModes={type: "pathModes", model: "pathModes", focusId: "PathMode", ui: "table-pair", keyName: "path", valueName: "mode"}')
+                .settings-row
                     ignite-form-group(ng-model=pathModes ng-form=pathModesForm)
                         ignite-form-field-label
                             | Path modes

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/user/Auth.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/user/Auth.service.js b/modules/web-console/src/main/js/app/modules/user/Auth.service.js
index 8ed9f33..f0aa397 100644
--- a/modules/web-console/src/main/js/app/modules/user/Auth.service.js
+++ b/modules/web-console/src/main/js/app/modules/user/Auth.service.js
@@ -41,11 +41,15 @@ export default ['Auth', ['$http', '$rootScope', '$state', '$window', '$common',
             set authorized(auth) {
                 _authorized(auth);
             },
+            forgotPassword(userInfo) {
+                return $http.post('/api/v1/password/forgot', userInfo)
+                    .success(() => $state.go('password.send'))
+                    .error((err) => $common.showPopoverMessage(null, null, 'forgot_email', $common.errorMessage(err)));
+            },
             auth(action, userInfo) {
-                $http.post('/api/v1/' + action, userInfo)
-                    .then(User.read)
-                    .then((user) => {
-                        if (action !== 'password/forgot') {
+                return $http.post('/api/v1/' + action, userInfo)
+                    .success(() => {
+                        return User.read().then((user) => {
                             _authorized(true);
 
                             $root.$broadcast('user', user);
@@ -55,13 +59,12 @@ export default ['Auth', ['$http', '$rootScope', '$state', '$window', '$common',
                             $root.gettingStarted.tryShow();
 
                             agentMonitor.init();
-                        } else
-                            $state.go('password.send');
+                        });
                     })
-                    .catch((errMsg) => $common.showPopoverMessage(null, null, action === 'signup' ? 'signup_email' : 'signin_email', errMsg.data));
+                    .error((err) => $common.showPopoverMessage(null, null, action + '_email', $common.errorMessage(err)));
             },
             logout() {
-                $http.post('/api/v1/logout')
+                return $http.post('/api/v1/logout')
                     .then(() => {
                         User.clean();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/services/AgentMonitor.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/services/AgentMonitor.service.js b/modules/web-console/src/main/js/app/services/AgentMonitor.service.js
deleted file mode 100644
index 88995d5..0000000
--- a/modules/web-console/src/main/js/app/services/AgentMonitor.service.js
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * 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.
- */
-
-import io from 'socket.io-client'; // eslint-disable-line no-unused-vars
-
-class IgniteAgentMonitor {
-    constructor(socketFactory, $root, $q, $state, $modal, $common) {
-        this._scope = $root.$new();
-
-        $root.$on('$stateChangeStart', () => {
-            this.stopWatch();
-        });
-
-        // Pre-fetch modal dialogs.
-        this._downloadAgentModal = $modal({
-            scope: this._scope,
-            templateUrl: '/templates/agent-download.html',
-            show: false,
-            backdrop: 'static'
-        });
-
-        const _modalHide = this._downloadAgentModal.hide;
-
-        /**
-         * Special dialog hide function.
-         */
-        this._downloadAgentModal.hide = () => {
-            $common.hideAlert();
-
-            _modalHide();
-        };
-
-        /**
-         * Close dialog and go by specified link.
-         */
-        this._scope.back = () => {
-            this.stopWatch();
-
-            if (this._scope.backState)
-                this._scope.$$postDigest(() => $state.go(this._scope.backState));
-        };
-
-        this._scope.downloadAgent = () => {
-            const lnk = document.createElement('a');
-
-            lnk.setAttribute('href', '/api/v1/agent/download/zip');
-            lnk.setAttribute('target', '_self');
-            lnk.setAttribute('download', null);
-            lnk.style.display = 'none';
-
-            document.body.appendChild(lnk);
-
-            lnk.click();
-
-            document.body.removeChild(lnk);
-        };
-
-        this._scope.hasAgents = null;
-        this._scope.showModal = false;
-
-        this._evtOrderKey = $common.randomString(20);
-        this._evtThrottleCntrKey = $common.randomString(20);
-
-        /**
-         * @type {Socket}
-         */
-        this._socket = null;
-
-        this._socketFactory = socketFactory;
-
-        this._$q = $q;
-
-        this._$common = $common;
-    }
-
-    /**
-     * @private
-     */
-    checkModal() {
-        if (this._scope.showModal && !this._scope.hasAgents)
-            this._downloadAgentModal.$promise.then(this._downloadAgentModal.show);
-        else if ((this._scope.hasAgents || !this._scope.showModal) && this._downloadAgentModal.$isShown)
-            this._downloadAgentModal.hide();
-    }
-
-    /**
-     * @returns {Promise}
-     */
-    awaitAgent() {
-        if (this._scope.hasAgents)
-            return this._$q.when();
-
-        if (this._scope.hasAgents !== null)
-            this.checkModal();
-
-        const latch = this._$q.defer();
-
-        const offConnected = this._scope.$on('agent:connected', (event, success) => {
-            offConnected();
-
-            if (success)
-                return latch.resolve();
-
-            latch.reject();
-        });
-
-        return latch.promise;
-    }
-
-    init() {
-        this._socket = this._socketFactory();
-
-        this._socket.on('connect_error', () => {
-            this._scope.hasAgents = false;
-        });
-
-        this._socket.on('agent:count', ({count}) => {
-            this._scope.hasAgents = count > 0;
-
-            this.checkModal();
-
-            if (this._scope.hasAgents)
-                this._scope.$broadcast('agent:connected', true);
-        });
-
-        this._socket.on('disconnect', () => {
-            this._scope.hasAgents = false;
-
-            this.checkModal();
-        });
-    }
-
-    /**
-     * @param {Object} back
-     * @returns {Promise}
-     */
-    startWatch(back) {
-        this._scope.backState = back.state;
-        this._scope.backText = back.text;
-
-        this._scope.agentGoal = back.goal;
-
-        this._scope.showModal = true;
-
-        return this.awaitAgent();
-    }
-
-    /**
-     *
-     * @param {String} event
-     * @param {Object} [args]
-     * @returns {Promise}
-     * @private
-     */
-    _emit(event, ...args) {
-        if (!this._socket)
-            return this._$q.reject('Failed to connect to agent');
-
-        const latch = this._$q.defer();
-
-        const onDisconnect = () => {
-            this._socket.removeListener('disconnect', onDisconnect);
-
-            latch.reject('Connection to server was closed');
-        };
-
-        this._socket.on('disconnect', onDisconnect);
-
-        args.push((err, res) => {
-            this._socket.removeListener('disconnect', onDisconnect);
-
-            if (err)
-                latch.reject(err);
-
-            latch.resolve(res);
-        });
-
-        this._socket.emit(event, ...args);
-
-        return latch.promise;
-    }
-
-    drivers() {
-        return this._emit('schemaImport:drivers');
-    }
-
-    /**
-     *
-     * @param {Object} preset
-     * @returns {Promise}
-     */
-    schemas(preset) {
-        return this._emit('schemaImport:schemas', preset);
-    }
-
-    /**
-     *
-     * @param {Object} preset
-     * @returns {Promise}
-     */
-    tables(preset) {
-        return this._emit('schemaImport:tables', preset);
-    }
-
-    /**
-     * @param {String} errMsg
-     */
-    showNodeError(errMsg) {
-        this._downloadAgentModal.show();
-
-        this._$common.showError(errMsg);
-    }
-
-    /**
-     *
-     * @param {String} event
-     * @param {Object} [args]
-     * @returns {Promise}
-     * @private
-     */
-    _rest(event, ...args) {
-        return this._downloadAgentModal.$promise
-            .then(() => this._emit(event, ...args));
-    }
-
-    /**
-     * @param {Boolean} [attr]
-     * @param {Boolean} [mtr]
-     * @returns {Promise}
-     */
-    topology(attr, mtr) {
-        return this._rest('node:topology', !!attr, !!mtr);
-    }
-
-    /**
-     * @param {int} [queryId]
-     * @returns {Promise}
-     */
-    queryClose(queryId) {
-        return this._rest('node:query:close', queryId);
-    }
-
-    /**
-     * @param {String} cacheName Cache name.
-     * @param {int} pageSize
-     * @param {String} [query] Query if null then scan query.
-     * @returns {Promise}
-     */
-    query(cacheName, pageSize, query) {
-        return this._rest('node:query', _.isEmpty(cacheName) ? null : cacheName, pageSize, query);
-    }
-
-    /**
-     * @param {String} cacheName Cache name.
-     * @param {String} [query] Query if null then scan query.
-     * @returns {Promise}
-     */
-    queryGetAll(cacheName, query) {
-        return this._rest('node:query:getAll', _.isEmpty(cacheName) ? null : cacheName, query);
-    }
-
-    /**
-     * @param {String} [cacheName] Cache name.
-     * @returns {Promise}
-     */
-    metadata(cacheName) {
-        return this._rest('node:cache:metadata', _.isEmpty(cacheName) ? null : cacheName);
-    }
-
-    /**
-     * @param {int} queryId
-     * @param {int} pageSize
-     * @returns {Promise}
-     */
-    next(queryId, pageSize) {
-        return this._rest('node:query:fetch', queryId, pageSize);
-    }
-
-    collect() {
-        return this._rest('node:visor:collect', this._evtOrderKey, this._evtThrottleCntrKey);
-    }
-
-    /**
-     * Clear specified cache on specified node.
-     * @param {String} nid Node id.
-     * @param {String} cacheName Cache name.
-     * @returns {Promise}
-     */
-    cacheClear(nid, cacheName) {
-        return this._rest('node:cache:clear', nid, cacheName);
-    }
-
-    /**
-     * Stop specified cache on specified node.
-     * @param {String} nid Node id.
-     * @param {String} cacheName Cache name.
-     * @returns {Promise}
-     */
-    cacheStop(nid, cacheName) {
-        return this._rest('node:cache:stop', nid, cacheName);
-    }
-
-    /**
-     * Ping node.
-     * @param {String} nid Node id.
-     * @returns {Promise}
-     */
-    ping(nid) {
-        return this._rest('node:ping', nid);
-    }
-
-    stopWatch() {
-        this._scope.showModal = false;
-
-        this.checkModal();
-
-        this._scope.$broadcast('agent:connected', false);
-    }
-}
-
-IgniteAgentMonitor.$inject = ['igniteSocketFactory', '$rootScope', '$q', '$state', '$modal', '$common'];
-
-export default ['IgniteAgentMonitor', IgniteAgentMonitor];

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/services/cleanup.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/services/cleanup.service.js b/modules/web-console/src/main/js/app/services/cleanup.service.js
index 380beda..bec9ea3 100644
--- a/modules/web-console/src/main/js/app/services/cleanup.service.js
+++ b/modules/web-console/src/main/js/app/services/cleanup.service.js
@@ -32,7 +32,9 @@ export default ['$cleanup', () => {
                     dist[key] = attr;
                 }
             });
-        } else if ((_.isString(original) && original.length) || _.isNumber(original) || _.isBoolean(original))
+        } else if (_.isBoolean(original) && original === true)
+            dist = original;
+        else if ((_.isString(original) && original.length) || _.isNumber(original))
             dist = original;
         else if (_.isArray(original) && original.length)
             dist = _.map(original, (value) => cleanup(value, {}));

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/build/system.config.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/build/system.config.js b/modules/web-console/src/main/js/build/system.config.js
index edd9e9e..20af865 100644
--- a/modules/web-console/src/main/js/build/system.config.js
+++ b/modules/web-console/src/main/js/build/system.config.js
@@ -18,15 +18,15 @@ System.config({
     "angular": "github:angular/bower-angular@1.5.5",
     "angular-animate": "github:angular/bower-angular-animate@1.5.5",
     "angular-drag-and-drop-lists": "github:marceljuenemann/angular-drag-and-drop-lists@1.4.0",
-    "angular-gridster": "github:ManifestWebDesign/angular-gridster@0.13.5",
+    "angular-gridster": "github:ManifestWebDesign/angular-gridster@0.13.9",
     "angular-motion": "github:mgcrea/angular-motion@0.4.4",
-    "angular-nvd3": "github:krispo/angular-nvd3@1.0.6",
+    "angular-nvd3": "github:krispo/angular-nvd3@1.0.7",
     "angular-retina": "github:jrief/angular-retina@0.3.8",
     "angular-sanitize": "github:angular/bower-angular-sanitize@1.5.5",
     "angular-smart-table": "github:lorenzofox3/Smart-Table@2.1.8",
     "angular-socket-io": "github:btford/angular-socket-io@0.7.0",
     "angular-strap": "github:mgcrea/angular-strap@2.3.8",
-    "angular-tree-control": "github:wix/angular-tree-control@0.2.25",
+    "angular-tree-control": "github:wix/angular-tree-control@0.2.26",
     "angular-ui-grid": "github:angular-ui/bower-ui-grid@3.1.1",
     "angular-ui-router": "github:angular-ui/ui-router@0.2.18",
     "angular-ui-router-metatags": "github:tinusn/ui-router-metatags@1.0.3",
@@ -39,11 +39,11 @@ System.config({
     "css": "github:systemjs/plugin-css@0.1.21",
     "file-saver": "github:eligrey/FileSaver.js@master",
     "font-awesome": "npm:font-awesome@4.5.0",
-    "jade": "github:johnsoftek/plugin-jade@0.6.0",
+    "jade": "github:johnsoftek/plugin-jade@0.6.3",
     "jquery": "github:components/jquery@2.2.1",
-    "json": "github:systemjs/plugin-json@0.1.0",
+    "json": "github:systemjs/plugin-json@0.1.2",
     "jszip": "github:Stuk/jszip@2.6.0",
-    "lodash": "github:lodash/lodash@4.11.1",
+    "lodash": "github:lodash/lodash@4.13.0",
     "pdfmake": "github:bpampuch/pdfmake@0.1.20",
     "query-command-supported": "github:zenorocha/document.queryCommandSupported@1.0.0",
     "socket.io-client": "github:socketio/socket.io-client@1.4.5",
@@ -69,12 +69,11 @@ System.config({
     "github:eligrey/FileSaver.js@master": {
       "blob": "github:eligrey/Blob.js@master"
     },
-    "github:johnsoftek/plugin-jade@0.6.0": {
-      "jade-compiler": "npm:jade@1.11.0",
-      "text": "github:systemjs/plugin-text@0.0.4"
+    "github:johnsoftek/plugin-jade@0.6.3": {
+      "jade-compiler": "npm:jade@1.11.0"
     },
     "github:jspm/nodelibs-assert@0.1.0": {
-      "assert": "npm:assert@1.3.0"
+      "assert": "npm:assert@1.4.0"
     },
     "github:jspm/nodelibs-buffer@0.1.0": {
       "buffer": "npm:buffer@3.6.0"
@@ -100,7 +99,7 @@ System.config({
       "path-browserify": "npm:path-browserify@0.0.0"
     },
     "github:jspm/nodelibs-process@0.1.2": {
-      "process": "npm:process@0.11.2"
+      "process": "npm:process@0.11.3"
     },
     "github:jspm/nodelibs-stream@0.1.0": {
       "stream-browserify": "npm:stream-browserify@1.0.0"
@@ -117,7 +116,7 @@ System.config({
     "github:jspm/nodelibs-vm@0.1.0": {
       "vm-browserify": "npm:vm-browserify@0.0.4"
     },
-    "github:krispo/angular-nvd3@1.0.6": {
+    "github:krispo/angular-nvd3@1.0.7": {
       "d3": "npm:d3@3.5.14",
       "nvd3": "npm:nvd3@1.8.1"
     },
@@ -132,7 +131,7 @@ System.config({
       "angular-sanitize": "github:angular/bower-angular-sanitize@1.5.5"
     },
     "github:twbs/bootstrap@3.3.6": {
-      "jquery": "npm:jquery@2.2.3"
+      "jquery": "npm:jquery@2.2.4"
     },
     "npm:acorn-globals@1.0.9": {
       "acorn": "npm:acorn@2.7.0"
@@ -150,7 +149,7 @@ System.config({
       "stream": "github:jspm/nodelibs-stream@0.1.0"
     },
     "npm:align-text@0.1.4": {
-      "kind-of": "npm:kind-of@3.0.2",
+      "kind-of": "npm:kind-of@3.0.3",
       "longest": "npm:longest@1.0.1",
       "repeat-string": "npm:repeat-string@1.5.4"
     },
@@ -163,7 +162,11 @@ System.config({
     "npm:asap@1.0.0": {
       "process": "github:jspm/nodelibs-process@0.1.2"
     },
-    "npm:assert@1.3.0": {
+    "npm:assert@1.4.0": {
+      "assert": "github:jspm/nodelibs-assert@0.1.0",
+      "buffer": "github:jspm/nodelibs-buffer@0.1.0",
+      "buffer-shims": "npm:buffer-shims@1.0.0",
+      "process": "github:jspm/nodelibs-process@0.1.2",
       "util": "npm:util@0.10.3"
     },
     "npm:async@0.2.10": {
@@ -172,6 +175,9 @@ System.config({
     "npm:babel-runtime@5.8.38": {
       "process": "github:jspm/nodelibs-process@0.1.2"
     },
+    "npm:buffer-shims@1.0.0": {
+      "buffer": "github:jspm/nodelibs-buffer@0.1.0"
+    },
     "npm:buffer@3.6.0": {
       "base64-js": "npm:base64-js@0.0.8",
       "child_process": "github:jspm/nodelibs-child_process@0.1.0",
@@ -182,7 +188,7 @@ System.config({
     },
     "npm:center-align@0.1.3": {
       "align-text": "npm:align-text@0.1.4",
-      "lazy-cache": "npm:lazy-cache@1.0.3"
+      "lazy-cache": "npm:lazy-cache@1.0.4"
     },
     "npm:clean-css@3.4.12": {
       "buffer": "github:jspm/nodelibs-buffer@0.1.0",
@@ -223,7 +229,7 @@ System.config({
       "fs": "github:jspm/nodelibs-fs@0.1.2",
       "path": "github:jspm/nodelibs-path@0.1.0",
       "process": "github:jspm/nodelibs-process@0.1.2",
-      "systemjs-json": "github:systemjs/plugin-json@0.1.0"
+      "systemjs-json": "github:systemjs/plugin-json@0.1.2"
     },
     "npm:core-util-is@1.0.2": {
       "buffer": "github:jspm/nodelibs-buffer@0.1.0"
@@ -250,6 +256,9 @@ System.config({
     "npm:is-buffer@1.1.3": {
       "buffer": "github:jspm/nodelibs-buffer@0.1.0"
     },
+    "npm:isarray@1.0.0": {
+      "systemjs-json": "github:systemjs/plugin-json@0.1.2"
+    },
     "npm:jade@1.11.0": {
       "buffer": "github:jspm/nodelibs-buffer@0.1.0",
       "character-parser": "npm:character-parser@1.2.1",
@@ -260,7 +269,7 @@ System.config({
       "mkdirp": "npm:mkdirp@0.5.1",
       "path": "github:jspm/nodelibs-path@0.1.0",
       "process": "github:jspm/nodelibs-process@0.1.2",
-      "systemjs-json": "github:systemjs/plugin-json@0.1.0",
+      "systemjs-json": "github:systemjs/plugin-json@0.1.2",
       "transformers": "npm:transformers@2.1.0",
       "uglify-js": "npm:uglify-js@2.6.2",
       "void-elements": "npm:void-elements@2.0.1",
@@ -272,11 +281,11 @@ System.config({
       "is-promise": "npm:is-promise@2.1.0",
       "promise": "npm:promise@6.1.0"
     },
-    "npm:kind-of@3.0.2": {
+    "npm:kind-of@3.0.3": {
       "buffer": "github:jspm/nodelibs-buffer@0.1.0",
       "is-buffer": "npm:is-buffer@1.1.3"
     },
-    "npm:lazy-cache@1.0.3": {
+    "npm:lazy-cache@1.0.4": {
       "process": "github:jspm/nodelibs-process@0.1.2"
     },
     "npm:mkdirp@0.5.1": {
@@ -299,7 +308,7 @@ System.config({
     "npm:path-browserify@0.0.0": {
       "process": "github:jspm/nodelibs-process@0.1.2"
     },
-    "npm:process@0.11.2": {
+    "npm:process@0.11.3": {
       "assert": "github:jspm/nodelibs-assert@0.1.0"
     },
     "npm:promise@2.0.0": {
@@ -335,7 +344,7 @@ System.config({
       "amdefine": "npm:amdefine@1.0.0",
       "process": "github:jspm/nodelibs-process@0.1.2"
     },
-    "npm:source-map@0.5.3": {
+    "npm:source-map@0.5.6": {
       "process": "github:jspm/nodelibs-process@0.1.2"
     },
     "npm:stream-browserify@1.0.0": {
@@ -369,7 +378,7 @@ System.config({
       "fs": "github:jspm/nodelibs-fs@0.1.2",
       "path": "github:jspm/nodelibs-path@0.1.0",
       "process": "github:jspm/nodelibs-process@0.1.2",
-      "source-map": "npm:source-map@0.5.3",
+      "source-map": "npm:source-map@0.5.6",
       "uglify-to-browserify": "npm:uglify-to-browserify@1.0.2",
       "yargs": "npm:yargs@3.10.0"
     },

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/controllers/admin-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/controllers/admin-controller.js b/modules/web-console/src/main/js/controllers/admin-controller.js
index 5abee04..f46bab0 100644
--- a/modules/web-console/src/main/js/controllers/admin-controller.js
+++ b/modules/web-console/src/main/js/controllers/admin-controller.js
@@ -32,21 +32,21 @@ consoleModule.controller('adminController', [
                         user.userName = user.firstName + ' ' + user.lastName;
                         user.countryCode = Countries.getByName(user.country).code;
                         user.label = user.userName + ' ' + user.email + ' ' +
-                            (user.company || '') + ' ' + (user.country || '');
-                    })
+                            (user.company || '') + ' ' + (user.countryCode || '');
+                    });
                 })
                 .catch((err) => $common.showError(err));
         };
 
         _reloadUsers();
 
-        $scope.becomeUser = function (user) {
+        $scope.becomeUser = function(user) {
             $http.get('/api/v1/admin/become', { params: {viewedUserId: user._id}})
                 .then(User.read)
-                .then((user) => {
-                    $rootScope.$broadcast('user', user);
+                .then((becomeUser) => {
+                    $rootScope.$broadcast('user', becomeUser);
 
-                    $state.go('base.configuration.clusters')
+                    $state.go('base.configuration.clusters');
                 })
                 .catch((errMsg) => $common.showError($common.errorMessage(errMsg)));
         };
@@ -64,7 +64,7 @@ consoleModule.controller('adminController', [
                             $common.showInfo('User has been removed: "' + user.userName + '"');
                         })
                         .error((errMsg, status) => {
-                            if (status == 503)
+                            if (status === 503)
                                 $common.showInfo(errMsg);
                             else
                                 $common.showError('Failed to remove user: "' + $common.errorMessage(errMsg) + '"');

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/controllers/caches-controller.js b/modules/web-console/src/main/js/controllers/caches-controller.js
index 8f4bedd..ac4d951 100644
--- a/modules/web-console/src/main/js/controllers/caches-controller.js
+++ b/modules/web-console/src/main/js/controllers/caches-controller.js
@@ -20,14 +20,14 @@ import consoleModule from 'controllers/common-module';
 
 consoleModule.controller('cachesController', [
     '$scope', '$http', '$state', '$filter', '$timeout', '$common', '$confirm', '$clone', '$loading', '$cleanup', '$unsavedChangesGuard',
-    function ($scope, $http, $state, $filter, $timeout, $common, $confirm, $clone, $loading, $cleanup, $unsavedChangesGuard) {
+    function($scope, $http, $state, $filter, $timeout, $common, $confirm, $clone, $loading, $cleanup, $unsavedChangesGuard) {
         $unsavedChangesGuard.install($scope);
 
-        var emptyCache = {empty: true};
+        const emptyCache = {empty: true};
 
-        var __original_value;
+        let __original_value;
 
-        var blank = {
+        const blank = {
             evictionPolicy: {},
             cacheStoreFactory: {},
             nearConfiguration: {}
@@ -44,15 +44,15 @@ consoleModule.controller('cachesController', [
         $scope.saveBtnTipText = $common.saveBtnTipText;
         $scope.widthIsSufficient = $common.widthIsSufficient;
 
-        var showPopoverMessage = $common.showPopoverMessage;
+        const showPopoverMessage = $common.showPopoverMessage;
 
-        $scope.contentVisible = function () {
-            var item = $scope.backupItem;
+        $scope.contentVisible = function() {
+            const item = $scope.backupItem;
 
             return !item.empty && (!item._id || _.find($scope.displayedRows, {_id: item._id}));
         };
 
-        $scope.toggleExpanded = function () {
+        $scope.toggleExpanded = function() {
             $scope.ui.expanded = !$scope.ui.expanded;
 
             $common.hidePopover();
@@ -71,10 +71,9 @@ consoleModule.controller('cachesController', [
         }
 
         function cacheDomains(item) {
-            return _.reduce($scope.domains, function (memo, domain) {
-                if (item && _.includes(item.domains, domain.value)) {
+            return _.reduce($scope.domains, function(memo, domain) {
+                if (item && _.includes(item.domains, domain.value))
                     memo.push(domain.meta);
-                }
 
                 return memo;
             }, []);
@@ -84,18 +83,15 @@ consoleModule.controller('cachesController', [
 
         // When landing on the page, get caches and show them.
         $http.post('/api/v1/configuration/caches/list')
-            .success(function (data) {
-                var validFilter = $filter('domainsValidation');
+            .success(function(data) {
+                const validFilter = $filter('domainsValidation');
 
                 $scope.spaces = data.spaces;
-
-                _.forEach(data.caches, function (cache) {
-                    cache.label = _cacheLbl(cache);
-                });
-
                 $scope.caches = data.caches;
 
-                $scope.clusters = _.map(data.clusters, function (cluster) {
+                _.forEach($scope.caches, (cache) => cache.label = _cacheLbl(cache));
+
+                $scope.clusters = _.map(data.clusters, function(cluster) {
                     return {
                         value: cluster._id,
                         label: cluster.name,
@@ -103,7 +99,7 @@ consoleModule.controller('cachesController', [
                     };
                 });
 
-                $scope.domains = _.sortBy(_.map(validFilter(data.domains, true, false), function (domain) {
+                $scope.domains = _.sortBy(_.map(validFilter(data.domains, true, false), function(domain) {
                     return {
                         value: domain._id,
                         label: domain.valueType,
@@ -112,13 +108,13 @@ consoleModule.controller('cachesController', [
                     };
                 }), 'label');
 
-                if ($state.params.id)
-                    $scope.createItem($state.params.id);
+                if ($state.params.linkId)
+                    $scope.createItem($state.params.linkId);
                 else {
-                    var lastSelectedCache = angular.fromJson(sessionStorage.lastSelectedCache);
+                    const lastSelectedCache = angular.fromJson(sessionStorage.lastSelectedCache);
 
                     if (lastSelectedCache) {
-                        var idx = _.findIndex($scope.caches, function (cache) {
+                        const idx = _.findIndex($scope.caches, function(cache) {
                             return cache._id === lastSelectedCache;
                         });
 
@@ -135,30 +131,29 @@ consoleModule.controller('cachesController', [
                 }
 
                 $scope.$watch('ui.inputForm.$valid', function(valid) {
-                    if (valid && __original_value === JSON.stringify($cleanup($scope.backupItem))) {
+                    if (valid && _.isEqual(__original_value, $cleanup($scope.backupItem)))
                         $scope.ui.inputForm.$dirty = false;
-                    }
                 });
 
-                $scope.$watch('backupItem', function (val) {
-                    var form = $scope.ui.inputForm;
+                $scope.$watch('backupItem', function(val) {
+                    const form = $scope.ui.inputForm;
 
-                    if (form.$pristine || (form.$valid && __original_value === JSON.stringify($cleanup(val))))
+                    if (form.$pristine || (form.$valid && _.isEqual(__original_value, $cleanup(val))))
                         form.$setPristine();
                     else
                         form.$setDirty();
                 }, true);
             })
-            .catch(function (errMsg) {
+            .catch(function(errMsg) {
                 $common.showError(errMsg);
             })
-            .finally(function () {
+            .finally(function() {
                 $scope.ui.ready = true;
                 $scope.ui.inputForm.$setPristine();
                 $loading.finish('loadingCachesScreen');
             });
 
-        $scope.selectItem = function (item, backup) {
+        $scope.selectItem = function(item, backup) {
             function selectItem() {
                 $scope.selectedItem = item;
 
@@ -181,7 +176,7 @@ consoleModule.controller('cachesController', [
 
                 $scope.backupItem = angular.merge({}, blank, $scope.backupItem);
 
-                __original_value = JSON.stringify($cleanup($scope.backupItem));
+                __original_value = $cleanup($scope.backupItem);
 
                 if ($common.getQueryVariable('new'))
                     $state.go('base.configuration.caches');
@@ -190,44 +185,49 @@ consoleModule.controller('cachesController', [
             $common.confirmUnsavedChanges($scope.backupItem && $scope.ui.inputForm.$dirty, selectItem);
         };
 
-        function prepareNewItem(id) {
+        $scope.linkId = () => $scope.backupItem._id ? $scope.backupItem._id : 'create';
+
+        function prepareNewItem(linkId) {
             return {
                 space: $scope.spaces[0]._id,
                 cacheMode: 'PARTITIONED',
                 atomicityMode: 'ATOMIC',
                 readFromBackup: true,
                 copyOnRead: true,
-                clusters: id && _.find($scope.clusters, {value: id})
-                    ? [id] : _.map($scope.clusters, function (cluster) { return cluster.value; }),
-                domains: id && _.find($scope.domains, { value: id }) ? [id] : [],
+                clusters: linkId && _.find($scope.clusters, {value: linkId})
+                    ? [linkId] : _.map($scope.clusters, function(cluster) { return cluster.value; }),
+                domains: linkId && _.find($scope.domains, { value: linkId }) ? [linkId] : [],
                 cacheStoreFactory: {CacheJdbcBlobStoreFactory: {connectVia: 'DataSource'}}
             };
         }
 
         // Add new cache.
-        $scope.createItem = function (id) {
-            $timeout(function () {
-                $common.ensureActivePanel($scope.ui, 'general', 'cacheName');
-            });
+        $scope.createItem = function(linkId) {
+            $timeout(() => $common.ensureActivePanel($scope.ui, 'general', 'cacheName'));
 
-            $scope.selectItem(undefined, prepareNewItem(id));
+            $scope.selectItem(null, prepareNewItem(linkId));
         };
 
-        function checkDataSources() {
-            var clusters = _.filter($scope.clusters, function (cluster) {
-                return _.includes($scope.backupItem.clusters, cluster.value);
-            });
+        function cacheClusters() {
+            return _.filter($scope.clusters, (cluster) => _.includes($scope.backupItem.clusters, cluster.value));
+        }
 
-            var checkRes = { checked: true };
+        function clusterCaches(cluster) {
+            const caches = _.filter($scope.caches,
+                (cache) => cache._id !== $scope.backupItem._id && _.includes(cluster.caches, cache._id));
 
-            var failCluster = _.find(clusters, function (cluster) {
-                var caches = _.filter($scope.caches, function (cache) {
-                    return cache._id !== $scope.backupItem._id && _.find(cluster.caches, function (clusterCache) {
-                        return clusterCache === cache._id;
-                    });
-                });
+            caches.push($scope.backupItem);
 
-                caches.push($scope.backupItem);
+            return caches;
+        }
+
+        function checkDataSources() {
+            const clusters = cacheClusters();
+
+            let checkRes = {checked: true};
+
+            const failCluster = _.find(clusters, (cluster) => {
+                const caches = clusterCaches(cluster);
 
                 checkRes = $common.checkCachesDataSources(caches, $scope.backupItem);
 
@@ -245,129 +245,88 @@ consoleModule.controller('cachesController', [
             return true;
         }
 
-        // Check cache logical consistency.
-        function validate(item) {
-            $common.hidePopover();
-
-            if ($common.isEmptyString(item.name))
-                return showPopoverMessage($scope.ui, 'general', 'cacheName', 'Cache name should not be empty!');
-
-            if (item.memoryMode === 'ONHEAP_TIERED' && item.offHeapMaxMemory > 0 && !$common.isDefined(item.evictionPolicy.kind))
-                return showPopoverMessage($scope.ui, 'memory', 'evictionPolicyKind', 'Eviction policy should not be configured!');
+        function checkSQLSchemas() {
+            const clusters = cacheClusters();
 
-            var form = $scope.ui.inputForm;
-            var errors = form.$error;
-            var errKeys = Object.keys(errors);
+            let checkRes = {checked: true};
 
-            if (errKeys && errKeys.length > 0) {
-                var firstErrorKey = errKeys[0];
+            const failCluster = _.find(clusters, (cluster) => {
+                const caches = clusterCaches(cluster);
 
-                var firstError = errors[firstErrorKey][0];
-                var actualError = firstError.$error[firstErrorKey][0];
+                checkRes = $common.checkCacheSQLSchemas(caches, $scope.backupItem);
 
-                var errNameFull = actualError.$name;
-                var errNameShort = errNameFull;
+                return !checkRes.checked;
+            });
 
-                if (errNameShort.endsWith('TextInput'))
-                    errNameShort = errNameShort.substring(0, errNameShort.length - 9);
+            if (!checkRes.checked) {
+                return showPopoverMessage($scope.ui, 'query', 'sqlSchema',
+                    'Found cache "' + checkRes.secondCache.name + '" in cluster "' + failCluster.label + '" ' +
+                    'with the same SQL schema name "' + checkRes.firstCache.sqlSchema + '"', 10000);
+            }
 
-                var extractErrorMessage = function (errName) {
-                    try {
-                        return errors[firstErrorKey][0].$errorMessages[errName][firstErrorKey];
-                    }
-                    catch(ignored) {
-                        try {
-                            msg = form[firstError.$name].$errorMessages[errName][firstErrorKey];
-                        }
-                        catch(ignited) {
-                            return false;
-                        }
-                    }
-                };
+            return true;
+        }
 
-                var msg = extractErrorMessage(errNameFull) || extractErrorMessage(errNameShort) || 'Invalid value!';
+        function checkStoreFactoryBean(storeFactory, beanFieldId) {
+            if (!$common.isValidJavaIdentifier('Data source bean', storeFactory.dataSourceBean, beanFieldId, $scope.ui, 'store'))
+                return false;
 
-                return showPopoverMessage($scope.ui, firstError.$name, errNameFull, msg);
-            }
+            return checkDataSources();
+        }
 
-            if (item.memoryMode === 'OFFHEAP_VALUES' && !_.isEmpty(item.domains))
-                return showPopoverMessage($scope.ui, 'memory', 'memoryMode',
-                    'Query indexing could not be enabled while values are stored off-heap!');
+        function checkStoreFactory(item) {
+            const cacheStoreFactorySelected = item.cacheStoreFactory && item.cacheStoreFactory.kind;
 
-            if (item.memoryMode === 'OFFHEAP_TIERED' && !$common.isDefined(item.offHeapMaxMemory))
-                return showPopoverMessage($scope.ui, 'memory', 'offHeapMaxMemory',
-                    'Off-heap max memory should be specified!');
+            if (cacheStoreFactorySelected) {
+                const storeFactory = item.cacheStoreFactory[item.cacheStoreFactory.kind];
 
-            var cacheStoreFactorySelected = item.cacheStoreFactory && item.cacheStoreFactory.kind;
+                if (item.cacheStoreFactory.kind === 'CacheJdbcPojoStoreFactory' && !checkStoreFactoryBean(storeFactory, 'pojoDataSourceBean'))
+                    return false;
 
-            if (cacheStoreFactorySelected) {
-                var storeFactory = item.cacheStoreFactory[item.cacheStoreFactory.kind];
+                if (item.cacheStoreFactory.kind === 'CacheJdbcBlobStoreFactory' && storeFactory.connectVia !== 'URL'
+                    && !checkStoreFactoryBean(storeFactory, 'blobDataSourceBean'))
+                    return false;
+            }
 
-                if (item.cacheStoreFactory.kind === 'CacheJdbcPojoStoreFactory') {
-                    if ($common.isEmptyString(storeFactory.dataSourceBean))
-                        return showPopoverMessage($scope.ui, 'store', 'dataSourceBean',
-                            'Data source bean name should not be empty!');
+            if ((item.readThrough || item.writeThrough) && !cacheStoreFactorySelected)
+                return showPopoverMessage($scope.ui, 'store', 'cacheStoreFactory', (item.readThrough ? 'Read' : 'Write') + ' through are enabled but store is not configured!');
 
-                    if (!$common.isValidJavaIdentifier('Data source bean', storeFactory.dataSourceBean, 'dataSourceBean', $scope.ui, 'store'))
-                        return false;
+            if (item.writeBehindEnabled && !cacheStoreFactorySelected)
+                return showPopoverMessage($scope.ui, 'store', 'cacheStoreFactory', 'Write behind enabled but store is not configured!');
 
-                    if (!storeFactory.dialect)
-                        return showPopoverMessage($scope.ui, 'store', 'pojoDialect',
-                            'Dialect should not be empty!');
+            if (cacheStoreFactorySelected && !item.readThrough && !item.writeThrough)
+                return showPopoverMessage($scope.ui, 'store', 'readThroughTooltip', 'Store is configured but read/write through are not enabled!');
 
-                    if (!checkDataSources())
-                        return false;
-                }
+            return true;
+        }
 
-                if (item.cacheStoreFactory.kind === 'CacheJdbcBlobStoreFactory') {
-                    if (storeFactory.connectVia === 'URL') {
-                        if ($common.isEmptyString(storeFactory.connectionUrl))
-                            return showPopoverMessage($scope.ui, 'store', 'connectionUrl',
-                                'Connection URL should not be empty!');
+        // Check cache logical consistency.
+        function validate(item) {
+            $common.hidePopover();
 
-                        if ($common.isEmptyString(storeFactory.user))
-                            return showPopoverMessage($scope.ui, 'store', 'user',
-                                'User should not be empty!');
-                    }
-                    else {
-                        if ($common.isEmptyString(storeFactory.dataSourceBean))
-                            return showPopoverMessage($scope.ui, 'store', 'dataSourceBean',
-                                'Data source bean name should not be empty!');
+            if ($common.isEmptyString(item.name))
+                return showPopoverMessage($scope.ui, 'general', 'cacheName', 'Cache name should not be empty!');
 
-                        if (!$common.isValidJavaIdentifier('Data source bean', storeFactory.dataSourceBean, 'dataSourceBean', $scope.ui, 'store'))
-                            return false;
+            if (item.memoryMode === 'ONHEAP_TIERED' && item.offHeapMaxMemory > 0 && !$common.isDefined(item.evictionPolicy.kind))
+                return showPopoverMessage($scope.ui, 'memory', 'evictionPolicyKind', 'Eviction policy should not be configured!');
 
-                        if (!storeFactory.dialect)
-                            return showPopoverMessage($scope.ui, 'store', 'blobDialect',
-                                'Database should not be empty!');
+            if (!$common.checkFieldValidators($scope.ui))
+                return false;
 
-                        if (!checkDataSources())
-                            return false;
-                    }
-                }
-            }
+            if (item.memoryMode === 'OFFHEAP_VALUES' && !_.isEmpty(item.domains))
+                return showPopoverMessage($scope.ui, 'memory', 'memoryMode', 'Query indexing could not be enabled while values are stored off-heap!');
 
-            if ((item.readThrough || item.writeThrough) && !cacheStoreFactorySelected)
-                return showPopoverMessage($scope.ui, 'store', 'cacheStoreFactory',
-                    (item.readThrough ? 'Read' : 'Write') + ' through are enabled but store is not configured!');
+            if (item.memoryMode === 'OFFHEAP_TIERED' && (!$common.isDefined(item.offHeapMaxMemory) || item.offHeapMaxMemory < 0))
+                return showPopoverMessage($scope.ui, 'memory', 'offHeapMaxMemory', 'Off-heap max memory should be specified!');
 
-            if (item.writeBehindEnabled && !cacheStoreFactorySelected)
-                return showPopoverMessage($scope.ui, 'store', 'cacheStoreFactory',
-                    'Write behind enabled but store is not configured!');
+            if (!checkSQLSchemas())
+                return false;
 
-            if (cacheStoreFactorySelected) {
-                if (!item.readThrough && !item.writeThrough)
-                    return showPopoverMessage($scope.ui, 'store', 'readThroughTooltip',
-                        'Store is configured but read/write through are not enabled!');
-            }
+            if (!checkStoreFactory(item))
+                return false;
 
             if (item.writeBehindFlushSize === 0 && item.writeBehindFlushFrequency === 0)
-                return showPopoverMessage($scope.ui, 'store', 'writeBehindFlushSize',
-                    'Both "Flush frequency" and "Flush size" are not allowed as 0!');
-
-            if (item.cacheMode !== 'LOCAL' && item.rebalanceMode !== 'NONE' && item.rebalanceBatchSize === 0)
-                return showPopoverMessage($scope.ui, 'rebalance', 'rebalanceBatchSize',
-                    'Batch size should be more than 0 if rebalance mode is "SYNC" or "ASYNC" !', 10000);
+                return showPopoverMessage($scope.ui, 'store', 'writeBehindFlushSize', 'Both "Flush frequency" and "Flush size" are not allowed as 0!');
 
             return true;
         }
@@ -375,12 +334,12 @@ consoleModule.controller('cachesController', [
         // Save cache in database.
         function save(item) {
             $http.post('/api/v1/configuration/caches/save', item)
-                .success(function (_id) {
+                .success(function(_id) {
                     item.label = _cacheLbl(item);
 
                     $scope.ui.inputForm.$setPristine();
 
-                    var idx = _.findIndex($scope.caches, function (cache) {
+                    const idx = _.findIndex($scope.caches, function(cache) {
                         return cache._id === _id;
                     });
 
@@ -391,18 +350,32 @@ consoleModule.controller('cachesController', [
                         $scope.caches.push(item);
                     }
 
+                    _.forEach($scope.clusters, (cluster) => {
+                        if (_.includes(item.clusters, cluster.value))
+                            cluster.caches = _.union(cluster.caches, [_id]);
+                        else
+                            _.remove(cluster.caches, (id) => id === _id);
+                    });
+
+                    _.forEach($scope.domains, (domain) => {
+                        if (_.includes(item.domains, domain.value))
+                            domain.meta.caches = _.union(domain.meta.caches, [_id]);
+                        else
+                            _.remove(domain.meta.caches, (id) => id === _id);
+                    });
+
                     $scope.selectItem(item);
 
                     $common.showInfo('Cache "' + item.name + '" saved.');
                 })
-                .error(function (errMsg) {
+                .error(function(errMsg) {
                     $common.showError(errMsg);
                 });
         }
 
         // Save cache.
-        $scope.saveItem = function () {
-            var item = $scope.backupItem;
+        $scope.saveItem = function() {
+            const item = $scope.backupItem;
 
             angular.extend(item, $common.autoCacheStoreConfiguration(item, cacheDomains(item)));
 
@@ -411,41 +384,43 @@ consoleModule.controller('cachesController', [
         };
 
         function _cacheNames() {
-            return _.map($scope.caches, function (cache) {
+            return _.map($scope.caches, function(cache) {
                 return cache.name;
             });
         }
 
         // Clone cache with new name.
-        $scope.cloneItem = function () {
+        $scope.cloneItem = function() {
             if (validate($scope.backupItem)) {
-                $clone.confirm($scope.backupItem.name, _cacheNames()).then(function (newName) {
-                    var item = angular.copy($scope.backupItem);
+                $clone.confirm($scope.backupItem.name, _cacheNames()).then(function(newName) {
+                    const item = angular.copy($scope.backupItem);
 
                     delete item._id;
 
                     item.name = newName;
 
+                    delete item.sqlSchema;
+
                     save(item);
                 });
             }
         };
 
         // Remove cache from db.
-        $scope.removeItem = function () {
-            var selectedItem = $scope.selectedItem;
+        $scope.removeItem = function() {
+            const selectedItem = $scope.selectedItem;
 
             $confirm.confirm('Are you sure you want to remove cache: "' + selectedItem.name + '"?')
-                .then(function () {
-                    var _id = selectedItem._id;
+                .then(function() {
+                    const _id = selectedItem._id;
 
-                    $http.post('/api/v1/configuration/caches/remove', {_id: _id})
-                        .success(function () {
+                    $http.post('/api/v1/configuration/caches/remove', {_id})
+                        .success(function() {
                             $common.showInfo('Cache has been removed: ' + selectedItem.name);
 
-                            var caches = $scope.caches;
+                            const caches = $scope.caches;
 
-                            var idx = _.findIndex(caches, function (cache) {
+                            const idx = _.findIndex(caches, function(cache) {
                                 return cache._id === _id;
                             });
 
@@ -454,37 +429,46 @@ consoleModule.controller('cachesController', [
 
                                 if (caches.length > 0)
                                     $scope.selectItem(caches[0]);
-                                else
+                                else {
                                     $scope.backupItem = emptyCache;
+                                    $scope.ui.inputForm.$setPristine();
+                                }
+
+                                _.forEach($scope.clusters, (cluster) => _.remove(cluster.caches, (id) => id === _id));
+                                _.forEach($scope.domains, (domain) => _.remove(domain.meta.caches, (id) => id === _id));
                             }
                         })
-                        .error(function (errMsg) {
+                        .error(function(errMsg) {
                             $common.showError(errMsg);
                         });
                 });
         };
 
         // Remove all caches from db.
-        $scope.removeAllItems = function () {
+        $scope.removeAllItems = function() {
             $confirm.confirm('Are you sure you want to remove all caches?')
-                .then(function () {
+                .then(function() {
                     $http.post('/api/v1/configuration/caches/remove/all')
-                        .success(function () {
+                        .success(function() {
                             $common.showInfo('All caches have been removed');
 
                             $scope.caches = [];
+
+                            _.forEach($scope.clusters, (cluster) => cluster.caches = []);
+                            _.forEach($scope.domains, (domain) => domain.meta.caches = []);
+
                             $scope.backupItem = emptyCache;
                             $scope.ui.inputForm.$setPristine();
                         })
-                        .error(function (errMsg) {
+                        .error(function(errMsg) {
                             $common.showError(errMsg);
                         });
                 });
         };
 
-        $scope.resetAll = function () {
+        $scope.resetAll = function() {
             $confirm.confirm('Are you sure you want to undo all changes for current cache?')
-                .then(function () {
+                .then(function() {
                     $scope.backupItem = $scope.selectedItem ? angular.copy($scope.selectedItem) : prepareNewItem();
                     $scope.ui.inputForm.$setPristine();
                 });


[49/50] [abbrv] ignite git commit: Merge remote-tracking branch 'remotes/origin/master' into ignite-1232

Posted by sb...@apache.org.
Merge remote-tracking branch 'remotes/origin/master' into ignite-1232

# Conflicts:
#	modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
#	modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoPolicy.java
#	modules/core/src/main/java/org/apache/ignite/internal/processors/closure/GridClosureProcessor.java
#	modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsIpcHandler.java
#	modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
#	modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2AbstractKeyValueRow.java
#	modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
#	modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
#	modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuerySplitter.java
#	modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/bc1902b8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/bc1902b8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/bc1902b8

Branch: refs/heads/ignite-1232
Commit: bc1902b8098ce783894f3051c374b0152f2260c3
Parents: 1c19f72 cbb77c9
Author: sboikov <sb...@gridgain.com>
Authored: Tue Jun 28 16:04:28 2016 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Tue Jun 28 16:04:28 2016 +0300

----------------------------------------------------------------------
 .gitignore                                      |   42 +-
 RELEASE_NOTES.txt                               |   89 +
 assembly/dependencies-fabric-lgpl.xml           |    3 +
 assembly/dependencies-fabric.xml                |    3 +
 assembly/dependencies-schema-import.xml         |    1 +
 assembly/release-fabric-base.xml                |   30 +
 assembly/release-schema-import.xml              |    2 +-
 config/hadoop/default-config.xml                |  111 +-
 examples/config/filesystem/example-igfs.xml     |    3 -
 examples/pom.xml                                |    2 +-
 examples/schema-import/pom.xml                  |    2 +-
 .../java/org/apache/ignite/schema/Demo.java     |   23 +-
 .../ignite/schema/H2DataSourceFactory.java      |   35 +
 .../CacheContinuousAsyncQueryExample.java       |  138 +
 .../datagrid/CacheContinuousQueryExample.java   |   13 +-
 .../store/CacheLoadOnlyStoreExample.java        |  171 +
 .../datastructures/IgniteLockExample.java       |  293 ++
 .../streaming/StreamVisitorExample.java         |   31 +-
 examples/src/main/resources/person.csv          |   20 +
 .../ignite/examples/CacheExamplesSelfTest.java  |   16 +
 modules/aop/pom.xml                             |    2 +-
 modules/apache-license-gen/pom.xml              |    2 +-
 modules/aws/pom.xml                             |   40 +-
 modules/benchmarks/pom.xml                      |    2 +-
 .../internal/benchmarks/model/IntValue.java     |   19 +-
 modules/camel/pom.xml                           |    2 +-
 modules/cassandra/README.txt                    |   32 +
 modules/cassandra/licenses/apache-2.0.txt       |  202 ++
 modules/cassandra/pom.xml                       |  337 ++
 .../store/cassandra/CassandraCacheStore.java    |  409 +++
 .../cassandra/CassandraCacheStoreFactory.java   |  200 +
 .../store/cassandra/common/CassandraHelper.java |  133 +
 .../cassandra/common/PropertyMappingHelper.java |  220 ++
 .../store/cassandra/common/RandomSleeper.java   |  104 +
 .../store/cassandra/common/SystemHelper.java    |   46 +
 .../store/cassandra/datasource/Credentials.java |   37 +
 .../store/cassandra/datasource/DataSource.java  |  550 +++
 .../cassandra/datasource/PlainCredentials.java  |   50 +
 .../persistence/KeyPersistenceSettings.java     |  274 ++
 .../KeyValuePersistenceSettings.java            |  478 +++
 .../persistence/PersistenceController.java      |  421 +++
 .../persistence/PersistenceSettings.java        |  335 ++
 .../persistence/PersistenceStrategy.java        |   62 +
 .../store/cassandra/persistence/PojoField.java  |  219 ++
 .../cassandra/persistence/PojoKeyField.java     |   91 +
 .../cassandra/persistence/PojoValueField.java   |  152 +
 .../persistence/ValuePersistenceSettings.java   |  107 +
 .../cassandra/serializer/JavaSerializer.java    |   81 +
 .../cassandra/serializer/KryoSerializer.java    |   93 +
 .../store/cassandra/serializer/Serializer.java  |   43 +
 .../session/BatchExecutionAssistant.java        |   95 +
 .../cassandra/session/BatchLoaderAssistant.java |   47 +
 .../cassandra/session/CassandraSession.java     |   60 +
 .../cassandra/session/CassandraSessionImpl.java |  832 +++++
 .../cassandra/session/ExecutionAssistant.java   |   77 +
 .../session/GenericBatchExecutionAssistant.java |   71 +
 .../session/LoadCacheCustomQueryWorker.java     |  105 +
 .../cassandra/session/pool/SessionPool.java     |  173 +
 .../cassandra/session/pool/SessionWrapper.java  |   71 +
 .../store/cassandra/utils/DDLGenerator.java     |   64 +
 .../aws/cassandra/cassandra-bootstrap.sh        |  373 ++
 .../bootstrap/aws/cassandra/cassandra-env.sh    |  283 ++
 .../bootstrap/aws/cassandra/cassandra-start.sh  |  550 +++
 .../aws/cassandra/cassandra-template.yaml       |  889 +++++
 .../bootstrap/aws/ignite/ignite-bootstrap.sh    |  384 ++
 .../ignite/ignite-cassandra-server-template.xml |  177 +
 .../src/test/bootstrap/aws/ignite/ignite-env.sh |   25 +
 .../test/bootstrap/aws/ignite/ignite-start.sh   |  637 ++++
 .../src/test/bootstrap/aws/logs-collector.sh    |  102 +
 .../tests/ignite-cassandra-client-template.xml  |  173 +
 .../test/bootstrap/aws/tests/tests-bootstrap.sh |  379 ++
 .../test/bootstrap/aws/tests/tests-report.sh    |  590 +++
 .../src/test/bootstrap/aws/tests/tests-run.sh   |  715 ++++
 .../CassandraDirectPersistenceLoadTest.java     |  107 +
 .../tests/CassandraDirectPersistenceTest.java   |  371 ++
 .../apache/ignite/tests/DDLGeneratorTest.java   |   43 +
 .../tests/IgnitePersistentStoreLoadTest.java    |  111 +
 .../ignite/tests/IgnitePersistentStoreTest.java |  369 ++
 .../org/apache/ignite/tests/load/Generator.java |   27 +
 .../apache/ignite/tests/load/IntGenerator.java  |   33 +
 .../ignite/tests/load/LoadTestDriver.java       |  238 ++
 .../apache/ignite/tests/load/LongGenerator.java |   28 +
 .../ignite/tests/load/PersonGenerator.java      |   43 +
 .../ignite/tests/load/PersonIdGenerator.java    |   31 +
 .../ignite/tests/load/StringGenerator.java      |   28 +
 .../org/apache/ignite/tests/load/Worker.java    |  429 +++
 .../tests/load/cassandra/BulkReadWorker.java    |   63 +
 .../tests/load/cassandra/BulkWriteWorker.java   |   52 +
 .../ignite/tests/load/cassandra/ReadWorker.java |   51 +
 .../tests/load/cassandra/WriteWorker.java       |   51 +
 .../tests/load/ignite/BulkReadWorker.java       |   52 +
 .../tests/load/ignite/BulkWriteWorker.java      |   52 +
 .../ignite/tests/load/ignite/ReadWorker.java    |   51 +
 .../ignite/tests/load/ignite/WriteWorker.java   |   51 +
 .../org/apache/ignite/tests/pojos/Person.java   |  246 ++
 .../org/apache/ignite/tests/pojos/PersonId.java |  110 +
 .../ignite/tests/utils/CacheStoreHelper.java    |   64 +
 .../tests/utils/CassandraAdminCredentials.java  |   36 +
 .../ignite/tests/utils/CassandraHelper.java     |  358 ++
 .../tests/utils/CassandraLifeCycleBean.java     |  149 +
 .../utils/CassandraRegularCredentials.java      |   36 +
 .../ignite/tests/utils/TestCacheSession.java    |   91 +
 .../apache/ignite/tests/utils/TestsHelper.java  |  375 ++
 .../src/test/resources/log4j.properties         |  119 +
 .../tests/cassandra/connection-settings.xml     |   48 +
 .../tests/cassandra/connection.properties       |   17 +
 .../tests/cassandra/credentials.properties      |   22 +
 .../tests/cassandra/embedded-cassandra.yaml     |  119 +
 .../ignite/tests/cassandra/keyspaces.properties |   17 +
 .../tests/persistence/blob/ignite-config.xml    |  100 +
 .../persistence/blob/persistence-settings-1.xml |   21 +
 .../persistence/blob/persistence-settings-2.xml |   21 +
 .../persistence/blob/persistence-settings-3.xml |   29 +
 .../tests/persistence/pojo/ignite-config.xml    |  119 +
 .../persistence/pojo/persistence-settings-1.xml |   21 +
 .../persistence/pojo/persistence-settings-2.xml |   21 +
 .../persistence/pojo/persistence-settings-3.xml |  173 +
 .../persistence/primitive/ignite-config.xml     |  100 +
 .../primitive/ignite-remote-client-config.xml   |   95 +
 .../primitive/ignite-remote-server-config.xml   |  106 +
 .../primitive/persistence-settings-1.xml        |   21 +
 .../primitive/persistence-settings-2.xml        |   21 +
 .../src/test/resources/tests.properties         |   50 +
 .../src/test/scripts/cassandra-load-tests.bat   |   41 +
 .../src/test/scripts/cassandra-load-tests.sh    |   39 +
 .../src/test/scripts/ignite-load-tests.bat      |   41 +
 .../src/test/scripts/ignite-load-tests.sh       |   39 +
 modules/cassandra/src/test/scripts/jvm-opt.sh   |   21 +
 modules/cassandra/src/test/scripts/jvm-opts.bat |   24 +
 modules/clients/pom.xml                         |   10 +-
 modules/clients/src/test/config/jdbc-config.xml |    3 +-
 .../client/ClientDefaultCacheSelfTest.java      |  119 +-
 .../ignite/internal/client/ClientHttpTask.java  |   33 +-
 .../ignite/internal/client/ClientTcpTask.java   |   10 +-
 .../ClientAbstractMultiNodeSelfTest.java        |    8 +-
 .../integration/ClientAbstractSelfTest.java     |   92 +-
 .../internal/jdbc2/JdbcConnectionSelfTest.java  |    2 +
 .../internal/jdbc2/JdbcNoDefaultCacheTest.java  |  161 +
 .../JettyRestProcessorAbstractSelfTest.java     | 1428 +++++---
 .../rest/JettyRestProcessorSignedSelfTest.java  |    5 +-
 .../JettyRestProcessorUnsignedSelfTest.java     |    5 +-
 .../rest/RestBinaryProtocolSelfTest.java        |    4 +-
 .../rest/RestMemcacheProtocolSelfTest.java      |    4 +-
 .../internal/processors/rest/SimplePerson.java  |   74 +
 .../ignite/jdbc/JdbcNoDefaultCacheTest.java     |  161 +
 .../jdbc/suite/IgniteJdbcDriverTestSuite.java   |    3 +
 modules/cloud/pom.xml                           |    2 +-
 modules/codegen/pom.xml                         |    2 +-
 .../ignite/codegen/MessageCodeGenerator.java    |  133 +-
 modules/core/pom.xml                            |   17 +-
 .../src/main/java/org/apache/ignite/Ignite.java |   21 +-
 .../java/org/apache/ignite/IgniteCache.java     |  217 +-
 .../java/org/apache/ignite/IgniteCondition.java |  338 ++
 .../org/apache/ignite/IgniteJdbcDriver.java     |    2 +-
 .../main/java/org/apache/ignite/IgniteLock.java |  489 +++
 .../apache/ignite/IgniteSystemProperties.java   |   75 +-
 .../main/java/org/apache/ignite/Ignition.java   |   19 +-
 .../ignite/cache/CacheInterceptorEntry.java     |   39 +
 .../cache/CacheWriteSynchronizationMode.java    |    5 +-
 .../ignite/cache/affinity/AffinityFunction.java |    2 +
 .../affinity/fair/FairAffinityFunction.java     |   83 +-
 .../rendezvous/RendezvousAffinityFunction.java  |   41 +-
 .../cache/query/CacheQueryEntryEvent.java       |   12 +-
 .../ignite/cache/query/ContinuousQuery.java     |   27 +
 .../store/jdbc/CacheAbstractJdbcStore.java      |    4 +
 .../cache/store/jdbc/CacheJdbcBlobStore.java    |   20 +-
 .../cache/store/jdbc/CacheJdbcPojoStore.java    |    2 +-
 .../store/jdbc/CacheJdbcPojoStoreFactory.java   |   59 +-
 .../org/apache/ignite/compute/ComputeJob.java   |    2 +-
 .../ignite/compute/ComputeJobAfterSend.java     |    2 +-
 .../compute/ComputeJobBeforeFailover.java       |    2 +-
 .../ignite/compute/ComputeJobContext.java       |    2 +-
 .../compute/ComputeJobContinuationAdapter.java  |   12 +-
 .../ignite/compute/ComputeLoadBalancer.java     |   12 +-
 .../org/apache/ignite/compute/ComputeTask.java  |   26 +-
 .../ignite/compute/ComputeTaskAdapter.java      |    8 +-
 .../compute/ComputeTaskNoResultCache.java       |    6 +-
 .../ignite/compute/ComputeTaskSession.java      |    4 +-
 .../ignite/compute/ComputeTaskSplitAdapter.java |    8 +-
 .../apache/ignite/compute/gridify/Gridify.java  |    2 +-
 .../configuration/CacheConfiguration.java       |    7 +
 .../configuration/ConnectorConfiguration.java   |    3 +
 .../configuration/FileSystemConfiguration.java  |  154 +-
 .../configuration/HadoopConfiguration.java      |   37 +-
 .../configuration/IgniteConfiguration.java      |  152 +-
 .../ignite/configuration/OdbcConfiguration.java |  118 +
 .../configuration/TransactionConfiguration.java |   40 +
 .../igfs/IgfsGroupDataBlocksKeyMapper.java      |   43 +-
 .../igfs/IgfsIpcEndpointConfiguration.java      |   28 +
 .../java/org/apache/ignite/igfs/IgfsPath.java   |   48 +-
 .../org/apache/ignite/igfs/IgfsPathSummary.java |   32 +-
 .../apache/ignite/igfs/mapreduce/IgfsTask.java  |    6 +-
 .../ignite/internal/GridCodegenConverter.java   |   56 +
 .../internal/GridEventConsumeHandler.java       |    3 +-
 .../ignite/internal/GridKernalContext.java      |   16 +
 .../ignite/internal/GridKernalContextImpl.java  |   28 +-
 .../apache/ignite/internal/GridLoggerProxy.java |    3 +-
 .../internal/GridMessageListenHandler.java      |    3 +-
 .../ignite/internal/GridTaskSessionImpl.java    |    2 +-
 .../org/apache/ignite/internal/GridTopic.java   |    5 +-
 .../ignite/internal/IgniteComponentType.java    |    4 +-
 .../ignite/internal/IgniteEventsImpl.java       |   11 +-
 .../apache/ignite/internal/IgniteKernal.java    |  110 +-
 .../ignite/internal/IgniteMessagingImpl.java    |    7 +-
 .../ignite/internal/IgniteNodeAttributes.java   |   10 +
 .../ignite/internal/IgniteServicesImpl.java     |    2 +-
 .../org/apache/ignite/internal/IgnitionEx.java  |   88 +-
 .../apache/ignite/internal/LessNamingBean.java  |   28 +
 .../ignite/internal/MarshallerContextImpl.java  |   91 +-
 .../internal/binary/BinaryClassDescriptor.java  |   43 +-
 .../ignite/internal/binary/BinaryContext.java   |  203 +-
 .../internal/binary/BinaryFieldAccessor.java    |    1 +
 .../internal/binary/BinaryObjectImpl.java       |   66 +-
 .../binary/BinaryObjectOffheapImpl.java         |   40 +-
 .../internal/binary/BinaryReaderExImpl.java     |   75 +-
 .../ignite/internal/binary/BinarySchema.java    |   11 +-
 .../ignite/internal/binary/BinaryTypeImpl.java  |    8 +
 .../ignite/internal/binary/BinaryUtils.java     |  249 +-
 .../internal/binary/BinaryWriterExImpl.java     |    7 +-
 .../internal/binary/GridBinaryMarshaller.java   |    7 +-
 .../binary/builder/BinaryBuilderReader.java     |   11 +-
 .../binary/builder/BinaryObjectBuilderImpl.java |  107 +-
 .../GridClientConnectionManagerAdapter.java     |   25 +-
 .../connection/GridClientNioTcpConnection.java  |    3 +
 .../GridClientOptimizedMarshaller.java          |    4 +-
 .../GridClientZipOptimizedMarshaller.java       |  167 +
 .../impl/GridTcpRouterNioListenerAdapter.java   |   11 +-
 .../internal/cluster/ClusterGroupAdapter.java   |   24 +-
 .../ignite/internal/cluster/ClusterGroupEx.java |   14 +-
 .../internal/direct/DirectMessageReader.java    |    7 +-
 .../internal/direct/DirectMessageWriter.java    |    4 +-
 .../direct/state/DirectMessageState.java        |    7 +-
 .../stream/v2/DirectByteBufferStreamImplV2.java |    2 +-
 .../ignite/internal/jdbc/JdbcStatement.java     |    9 +-
 .../ignite/internal/jdbc2/JdbcConnection.java   |   21 +-
 .../ignite/internal/jdbc2/JdbcQueryTask.java    |   15 +
 .../ignite/internal/jdbc2/JdbcStatement.java    |    7 +-
 .../internal/managers/GridManagerAdapter.java   |   21 +-
 .../managers/communication/GridIoManager.java   |  238 +-
 .../communication/GridIoMessageFactory.java     |   28 +-
 .../deployment/GridDeploymentCommunication.java |    3 +-
 .../discovery/GridDiscoveryManager.java         |  149 +-
 .../affinity/GridAffinityAssignment.java        |   64 +-
 .../affinity/GridAffinityAssignmentCache.java   |  312 +-
 .../GridAffinityFunctionContextImpl.java        |    9 +
 .../affinity/GridAffinityProcessor.java         |    8 +-
 .../processors/affinity/GridAffinityUtils.java  |    3 +-
 .../cache/CacheAffinityChangeMessage.java       |  160 +
 .../cache/CacheAffinitySharedManager.java       | 1795 +++++++++
 .../cache/CacheClusterMetricsMXBeanImpl.java    |  410 +++
 .../cache/CacheEvictableEntryImpl.java          |    2 +-
 .../processors/cache/CacheInvokeEntry.java      |   41 +-
 .../processors/cache/CacheLazyEntry.java        |   56 +-
 .../cache/CacheLocalMetricsMXBeanImpl.java      |  410 +++
 .../cache/CacheMetricsMXBeanImpl.java           |  410 ---
 .../processors/cache/CacheObjectContext.java    |    3 +
 .../processors/cache/CacheOperationFilter.java  |   61 +
 .../cache/CacheWeakQueryIteratorsHolder.java    |  169 +-
 .../cache/DynamicCacheChangeRequest.java        |   17 +
 .../cache/DynamicCacheDescriptor.java           |   49 +
 .../processors/cache/GridCacheAdapter.java      | 1335 ++++---
 .../cache/GridCacheAffinityManager.java         |  144 +-
 .../processors/cache/GridCacheAtomicFuture.java |    5 -
 .../cache/GridCacheClearAllRunnable.java        |    3 +-
 .../cache/GridCacheConcurrentMap.java           | 1996 +---------
 .../cache/GridCacheConcurrentMapImpl.java       |  344 ++
 .../processors/cache/GridCacheContext.java      |   85 +-
 .../cache/GridCacheDeploymentManager.java       |    2 +-
 .../processors/cache/GridCacheEntryEx.java      |   35 +-
 .../processors/cache/GridCacheEntrySet.java     |  113 -
 .../cache/GridCacheEvictionManager.java         |   34 +-
 .../processors/cache/GridCacheIoManager.java    |   48 +-
 .../processors/cache/GridCacheKeySet.java       |  104 -
 .../processors/cache/GridCacheLogger.java       |    3 +-
 .../processors/cache/GridCacheMapEntry.java     | 1014 ++++--
 .../processors/cache/GridCacheMvcc.java         |    7 +
 .../cache/GridCacheMvccCandidate.java           |   16 +-
 .../processors/cache/GridCacheMvccManager.java  |   20 +-
 .../GridCachePartitionExchangeManager.java      |  233 +-
 .../processors/cache/GridCachePreloader.java    |   23 +-
 .../cache/GridCachePreloaderAdapter.java        |   17 +-
 .../processors/cache/GridCacheProcessor.java    |  360 +-
 .../processors/cache/GridCacheProxyImpl.java    |  112 +-
 .../processors/cache/GridCacheReturn.java       |   10 +-
 .../cache/GridCacheSharedContext.java           |   54 +-
 .../processors/cache/GridCacheSwapManager.java  |  139 +-
 .../processors/cache/GridCacheTtlManager.java   |   26 +-
 .../processors/cache/GridCacheUtils.java        |  164 +-
 .../processors/cache/GridNoStorageCacheMap.java |  107 +
 .../processors/cache/IgniteCacheProxy.java      |  113 +-
 .../processors/cache/IgniteInternalCache.java   |  121 +-
 .../processors/cache/KeyCacheObject.java        |   11 +
 .../processors/cache/KeyCacheObjectImpl.java    |   32 +-
 .../cache/affinity/GridCacheAffinityImpl.java   |    2 +-
 .../binary/CacheObjectBinaryProcessorImpl.java  |   69 +-
 .../CacheDataStructuresManager.java             |    4 +-
 .../distributed/GridCacheCommittedTxInfo.java   |    1 +
 .../distributed/GridCacheTxRecoveryFuture.java  |   65 +-
 .../GridCacheTxRecoveryResponse.java            |   22 +-
 .../GridDistributedCacheAdapter.java            |    6 +-
 .../distributed/GridDistributedLockRequest.java |   19 +-
 .../GridDistributedLockResponse.java            |    8 -
 .../GridDistributedTxFinishRequest.java         |   21 +-
 .../GridDistributedTxPrepareRequest.java        |   26 +-
 .../GridDistributedTxPrepareResponse.java       |   18 +-
 .../GridDistributedTxRemoteAdapter.java         |   20 +-
 .../GridDistributedUnlockRequest.java           |   16 +-
 .../dht/CacheDistributedGetFutureAdapter.java   |    3 -
 .../dht/GridCachePartitionedConcurrentMap.java  |  271 ++
 .../dht/GridClientPartitionTopology.java        |   23 +-
 .../dht/GridDhtAffinityAssignmentResponse.java  |  198 +-
 .../dht/GridDhtAssignmentFetchFuture.java       |   80 +-
 .../distributed/dht/GridDhtCacheAdapter.java    |  163 +-
 .../distributed/dht/GridDhtCacheEntry.java      |   35 +-
 .../cache/distributed/dht/GridDhtGetFuture.java |   76 +-
 .../distributed/dht/GridDhtGetSingleFuture.java |    6 +
 .../distributed/dht/GridDhtLocalPartition.java  |  154 +-
 .../distributed/dht/GridDhtLockFuture.java      |   47 +-
 .../distributed/dht/GridDhtLockRequest.java     |   16 +-
 .../dht/GridDhtOffHeapCacheEntry.java           |    8 +
 .../dht/GridDhtPartitionTopology.java           |   21 +-
 .../dht/GridDhtPartitionTopologyImpl.java       |  615 ++--
 .../dht/GridDhtTransactionalCacheAdapter.java   |   72 +-
 .../distributed/dht/GridDhtTxFinishFuture.java  |   29 +-
 .../cache/distributed/dht/GridDhtTxLocal.java   |  210 +-
 .../distributed/dht/GridDhtTxLocalAdapter.java  |   15 +-
 .../distributed/dht/GridDhtTxPrepareFuture.java |   52 +-
 .../cache/distributed/dht/GridDhtTxRemote.java  |    9 +-
 .../distributed/dht/GridDhtUnlockRequest.java   |   15 +-
 .../distributed/dht/GridNoStorageCacheMap.java  |  122 -
 .../dht/GridPartitionedGetFuture.java           |   17 +-
 .../dht/GridPartitionedSingleGetFuture.java     |   17 +-
 .../dht/atomic/GridDhtAtomicCache.java          |  656 ++--
 .../atomic/GridDhtAtomicOffHeapCacheEntry.java  |    8 +
 .../dht/atomic/GridDhtAtomicUpdateFuture.java   |  144 +-
 .../dht/atomic/GridDhtAtomicUpdateRequest.java  |  149 +-
 .../GridNearAtomicAbstractUpdateFuture.java     |  244 ++
 .../GridNearAtomicSingleUpdateFuture.java       |  645 ++++
 .../dht/atomic/GridNearAtomicUpdateFuture.java  | 1398 +++----
 .../dht/atomic/GridNearAtomicUpdateRequest.java |   31 +-
 .../dht/colocated/GridDhtColocatedCache.java    |   30 +-
 .../colocated/GridDhtColocatedLockFuture.java   |   88 +-
 .../GridDhtColocatedOffHeapCacheEntry.java      |    8 +
 .../colocated/GridDhtDetachedCacheEntry.java    |    2 +-
 .../dht/preloader/GridDhtForceKeysFuture.java   |    9 +-
 .../dht/preloader/GridDhtPartitionDemander.java |   57 +-
 .../dht/preloader/GridDhtPartitionMap2.java     |    9 +-
 .../dht/preloader/GridDhtPartitionSupplier.java |   37 +-
 .../GridDhtPartitionsExchangeFuture.java        | 1575 ++++----
 .../dht/preloader/GridDhtPreloader.java         |  158 +-
 .../distributed/near/GridNearAtomicCache.java   |   44 +-
 .../distributed/near/GridNearCacheAdapter.java  |  114 +-
 .../distributed/near/GridNearCacheEntry.java    |  118 +-
 .../distributed/near/GridNearGetFuture.java     |   50 +-
 .../distributed/near/GridNearGetRequest.java    |   45 +-
 .../distributed/near/GridNearLockFuture.java    |   13 +-
 .../distributed/near/GridNearLockRequest.java   |   16 +-
 ...arOptimisticSerializableTxPrepareFuture.java |    5 +-
 .../near/GridNearOptimisticTxPrepareFuture.java |   34 +-
 ...ridNearOptimisticTxPrepareFutureAdapter.java |   16 +-
 .../near/GridNearSingleGetRequest.java          |   24 +-
 .../near/GridNearTransactionalCache.java        |    7 +-
 .../near/GridNearTxFinishFuture.java            |  123 +-
 .../near/GridNearTxFinishRequest.java           |   46 +-
 .../cache/distributed/near/GridNearTxLocal.java |   96 +-
 .../near/GridNearTxPrepareFutureAdapter.java    |   12 +-
 .../distributed/near/GridNearTxRemote.java      |   24 +-
 .../distributed/near/GridNearUnlockRequest.java |   21 +-
 .../processors/cache/dr/GridCacheDrManager.java |    4 +-
 .../cache/dr/GridOsCacheDrManager.java          |    2 +-
 .../processors/cache/local/GridLocalCache.java  |    7 +-
 .../cache/local/GridLocalCacheEntry.java        |   27 -
 .../cache/local/GridLocalLockFuture.java        |   77 +-
 .../local/atomic/GridLocalAtomicCache.java      |  172 +-
 .../processors/cache/query/CacheQuery.java      |   10 +-
 .../cache/query/CacheQueryFuture.java           |   13 +-
 .../query/GridCacheDistributedQueryManager.java |  100 +-
 .../cache/query/GridCacheLocalQueryManager.java |   34 +-
 .../cache/query/GridCacheQueryAdapter.java      |  175 +-
 .../cache/query/GridCacheQueryErrorFuture.java  |   12 +-
 .../query/GridCacheQueryFutureAdapter.java      |   10 +-
 .../cache/query/GridCacheQueryManager.java      |  574 ++-
 .../cache/query/GridCacheSqlIndexMetadata.java  |    3 +-
 .../cache/query/GridCacheSqlMetadata.java       |    3 +-
 .../continuous/CacheContinuousQueryEntry.java   |   40 +-
 .../continuous/CacheContinuousQueryEvent.java   |    7 +
 .../continuous/CacheContinuousQueryHandler.java |  605 +++-
 .../CacheContinuousQueryListener.java           |    6 +-
 .../continuous/CacheContinuousQueryManager.java |  226 +-
 .../query/jdbc/GridCacheQueryJdbcTask.java      |   59 +-
 .../jdbc/GridCacheQueryJdbcValidationTask.java  |   10 +-
 .../store/GridCacheStoreManagerAdapter.java     |   32 +-
 .../cache/transactions/IgniteInternalTx.java    |   40 +-
 .../transactions/IgniteTransactionsImpl.java    |    9 +-
 .../cache/transactions/IgniteTxAdapter.java     |  386 +-
 .../cache/transactions/IgniteTxEntry.java       |   72 +-
 .../cache/transactions/IgniteTxHandler.java     |  139 +-
 .../IgniteTxImplicitSingleStateImpl.java        |   53 +-
 .../transactions/IgniteTxLocalAdapter.java      |  531 +--
 .../cache/transactions/IgniteTxLocalEx.java     |   26 +-
 .../cache/transactions/IgniteTxManager.java     |  570 ++-
 .../IgniteTxRemoteSingleStateImpl.java          |   30 +
 .../IgniteTxRemoteStateAdapter.java             |   16 +-
 .../transactions/IgniteTxRemoteStateImpl.java   |   72 +-
 .../cache/transactions/IgniteTxState.java       |   11 +-
 .../cache/transactions/IgniteTxStateAware.java  |   34 +
 .../cache/transactions/IgniteTxStateImpl.java   |   42 +-
 .../cache/transactions/TxDeadlock.java          |  159 +
 .../cache/transactions/TxDeadlockDetection.java |  599 +++
 .../processors/cache/transactions/TxLock.java   |  225 ++
 .../cache/transactions/TxLockList.java          |  134 +
 .../cache/transactions/TxLocksRequest.java      |  205 ++
 .../cache/transactions/TxLocksResponse.java     |  318 ++
 .../GridCacheLazyPlainVersionedEntry.java       |  107 +
 .../version/GridCachePlainVersionedEntry.java   |    7 +-
 .../cache/version/GridCacheVersion.java         |   14 +-
 .../cache/version/GridCacheVersionEx.java       |    9 +
 .../cache/version/GridCacheVersionManager.java  |   21 +-
 .../cacheobject/IgniteCacheObjectProcessor.java |   17 +
 .../IgniteCacheObjectProcessorImpl.java         |   41 +-
 .../processors/clock/GridClockServer.java       |    3 +-
 .../closure/GridClosureProcessor.java           |  416 ++-
 .../processors/cluster/GridUpdateNotifier.java  |    3 +-
 .../continuous/GridContinuousHandler.java       |    4 +-
 .../continuous/GridContinuousProcessor.java     |  286 +-
 .../StartRoutineAckDiscoveryMessage.java        |   22 +-
 .../StartRoutineDiscoveryMessage.java           |   22 +-
 .../datastreamer/DataStreamProcessor.java       |    8 +-
 .../datastreamer/DataStreamerImpl.java          |   40 +-
 .../datastructures/DataStructuresProcessor.java |  167 +-
 .../datastructures/GridCacheAtomicLongImpl.java |    3 +-
 .../GridCacheAtomicReferenceImpl.java           |    4 +-
 .../GridCacheAtomicSequenceImpl.java            |    3 +-
 .../GridCacheAtomicStampedImpl.java             |    3 +-
 .../GridCacheCountDownLatchImpl.java            |   57 +-
 .../datastructures/GridCacheLockEx.java         |   52 +
 .../datastructures/GridCacheLockImpl.java       | 1538 ++++++++
 .../datastructures/GridCacheLockState.java      |  353 ++
 .../datastructures/GridCacheQueueProxy.java     |    3 +-
 .../datastructures/GridCacheSemaphoreEx.java    |    5 +
 .../datastructures/GridCacheSemaphoreImpl.java  |  197 +-
 .../datastructures/GridCacheSetImpl.java        |    9 +-
 .../datastructures/GridCacheSetProxy.java       |    3 +-
 .../processors/hadoop/HadoopJobInfo.java        |    3 +-
 .../processors/hadoop/HadoopNoopProcessor.java  |   24 +-
 .../internal/processors/igfs/IgfsAsyncImpl.java |    6 -
 .../internal/processors/igfs/IgfsBlockKey.java  |   30 +-
 .../processors/igfs/IgfsBlockLocationImpl.java  |   87 +-
 .../IgfsColocatedMetadataAffinityKeyMapper.java |   47 +
 .../internal/processors/igfs/IgfsContext.java   |   14 +-
 .../processors/igfs/IgfsCreateResult.java       |   66 +
 .../processors/igfs/IgfsDataManager.java        |  373 +-
 .../processors/igfs/IgfsDeleteResult.java       |   62 +
 .../processors/igfs/IgfsDeleteWorker.java       |  111 +-
 .../processors/igfs/IgfsDirectoryInfo.java      |  284 ++
 .../internal/processors/igfs/IgfsEntryInfo.java |  319 ++
 .../ignite/internal/processors/igfs/IgfsEx.java |   21 -
 .../processors/igfs/IgfsFileAffinityRange.java  |   32 +-
 .../internal/processors/igfs/IgfsFileImpl.java  |   78 +-
 .../internal/processors/igfs/IgfsFileInfo.java  |  519 +--
 .../internal/processors/igfs/IgfsFileMap.java   |   50 +-
 .../processors/igfs/IgfsFileWorkerBatch.java    |   75 +-
 .../IgfsFileWorkerBatchCancelledException.java  |   51 +
 .../igfs/IgfsFragmentizerManager.java           |  107 +-
 .../internal/processors/igfs/IgfsImpl.java      |  623 ++--
 .../processors/igfs/IgfsInputStreamAdapter.java |    5 +-
 .../processors/igfs/IgfsInputStreamImpl.java    |   40 +-
 .../igfs/IgfsInvalidRangeException.java         |    4 +-
 .../processors/igfs/IgfsIpcHandler.java         |  108 +-
 ...zySecondaryFileSystemPositionedReadable.java |   77 +
 .../processors/igfs/IgfsListingEntry.java       |  161 +-
 .../processors/igfs/IgfsMetaManager.java        | 3157 +++++++---------
 .../processors/igfs/IgfsNodePredicate.java      |   80 +
 .../igfs/IgfsOutputStreamAdapter.java           |  265 --
 .../processors/igfs/IgfsOutputStreamImpl.java   |  642 ++--
 .../internal/processors/igfs/IgfsPathIds.java   |  325 ++
 .../processors/igfs/IgfsPathsCreateResult.java  |   64 +
 .../internal/processors/igfs/IgfsProcessor.java |  107 +-
 .../IgfsSecondaryFileSystemCreateContext.java   |  111 +
 .../IgfsSecondaryInputStreamDescriptor.java     |    6 +-
 .../IgfsSecondaryOutputStreamDescriptor.java    |   73 -
 .../internal/processors/igfs/IgfsServer.java    |    2 +-
 .../internal/processors/igfs/IgfsUtils.java     |  613 +++-
 .../igfs/client/IgfsClientAbstractCallable.java |  125 +
 .../igfs/client/IgfsClientAffinityCallable.java |   95 +
 .../igfs/client/IgfsClientDeleteCallable.java   |   77 +
 .../igfs/client/IgfsClientExistsCallable.java   |   58 +
 .../igfs/client/IgfsClientInfoCallable.java     |   59 +
 .../client/IgfsClientListFilesCallable.java     |   61 +
 .../client/IgfsClientListPathsCallable.java     |   60 +
 .../igfs/client/IgfsClientMkdirsCallable.java   |   82 +
 .../igfs/client/IgfsClientRenameCallable.java   |   80 +
 .../igfs/client/IgfsClientSetTimesCallable.java |   87 +
 .../igfs/client/IgfsClientSizeCallable.java     |   59 +
 .../igfs/client/IgfsClientSummaryCallable.java  |   59 +
 .../igfs/client/IgfsClientUpdateCallable.java   |   81 +
 .../meta/IgfsClientMetaIdsForPathCallable.java  |   65 +
 .../meta/IgfsClientMetaInfoForPathCallable.java |   63 +
 .../igfs/data/IgfsDataPutProcessor.java         |   99 +
 .../meta/IgfsMetaDirectoryCreateProcessor.java  |  182 +
 .../IgfsMetaDirectoryListingAddProcessor.java   |  136 +
 ...IgfsMetaDirectoryListingRemoveProcessor.java |  132 +
 ...IgfsMetaDirectoryListingRenameProcessor.java |  133 +
 ...gfsMetaDirectoryListingReplaceProcessor.java |  130 +
 .../igfs/meta/IgfsMetaFileCreateProcessor.java  |  194 +
 .../igfs/meta/IgfsMetaFileLockProcessor.java    |  107 +
 .../meta/IgfsMetaFileRangeDeleteProcessor.java  |  111 +
 .../meta/IgfsMetaFileRangeUpdateProcessor.java  |  120 +
 .../meta/IgfsMetaFileReserveSpaceProcessor.java |  120 +
 .../igfs/meta/IgfsMetaFileUnlockProcessor.java  |  166 +
 .../meta/IgfsMetaUpdatePropertiesProcessor.java |  121 +
 .../igfs/meta/IgfsMetaUpdateTimesProcessor.java |  113 +
 .../internal/processors/igfs/package-info.java  |    2 +-
 .../processors/job/GridJobProcessor.java        |   20 +-
 .../internal/processors/job/GridJobWorker.java  |    4 +-
 .../processors/odbc/OdbcBufferedParser.java     |   81 +
 .../processors/odbc/OdbcColumnMeta.java         |  110 +
 .../processors/odbc/OdbcHandshakeRequest.java   |   49 +
 .../processors/odbc/OdbcHandshakeResult.java    |   66 +
 .../processors/odbc/OdbcMessageParser.java      |  277 ++
 .../processors/odbc/OdbcNioListener.java        |  179 +
 .../processors/odbc/OdbcNioServerBuffer.java    |  114 +
 .../internal/processors/odbc/OdbcProcessor.java |  165 +
 .../processors/odbc/OdbcQueryCloseRequest.java  |   49 +
 .../processors/odbc/OdbcQueryCloseResult.java   |   40 +
 .../odbc/OdbcQueryExecuteRequest.java           |   78 +
 .../processors/odbc/OdbcQueryExecuteResult.java |   54 +
 .../processors/odbc/OdbcQueryFetchRequest.java  |   61 +
 .../processors/odbc/OdbcQueryFetchResult.java   |   66 +
 .../odbc/OdbcQueryGetColumnsMetaRequest.java    |   74 +
 .../odbc/OdbcQueryGetColumnsMetaResult.java     |   42 +
 .../odbc/OdbcQueryGetTablesMetaRequest.java     |   85 +
 .../odbc/OdbcQueryGetTablesMetaResult.java      |   42 +
 .../internal/processors/odbc/OdbcRequest.java   |   58 +
 .../processors/odbc/OdbcRequestHandler.java     |  362 ++
 .../internal/processors/odbc/OdbcResponse.java  |   96 +
 .../internal/processors/odbc/OdbcTableMeta.java |   85 +
 .../internal/processors/odbc/OdbcUtils.java     |   56 +
 .../offheap/GridOffHeapProcessor.java           |   12 +
 .../platform/PlatformAbstractBootstrap.java     |   17 +-
 .../processors/platform/PlatformBootstrap.java  |    6 +-
 .../processors/platform/PlatformContext.java    |   11 +-
 .../platform/PlatformContextImpl.java           |   74 +-
 .../PlatformDefaultJavaObjectFactory.java       |   62 +
 .../processors/platform/PlatformIgnition.java   |   18 +-
 .../platform/PlatformJavaObjectFactoryEx.java   |   36 +
 .../PlatformJavaObjectFactoryProxy.java         |  192 +
 .../PlatformJavaObjectSingletonFactory.java     |   48 +
 .../platform/PlatformNoopProcessor.java         |   19 +-
 .../processors/platform/PlatformProcessor.java  |   26 +
 .../platform/PlatformProcessorImpl.java         |  102 +-
 .../platform/cache/PlatformCache.java           |   56 +-
 .../affinity/PlatformAffinityFunction.java      |  242 ++
 .../query/PlatformContinuousQueryImpl.java      |   50 +-
 .../callback/PlatformCallbackGateway.java       |   90 +-
 .../callback/PlatformCallbackUtils.java         |   46 +
 .../platform/cluster/PlatformClusterGroup.java  |   19 +
 .../platform/compute/PlatformCompute.java       |    7 +-
 .../datastreamer/PlatformDataStreamer.java      |    7 +-
 .../dotnet/PlatformDotNetCacheStore.java        |   27 +-
 .../PlatformDotNetConfigurationClosure.java     |    5 -
 .../platform/services/PlatformServices.java     |  249 +-
 .../utils/PlatformConfigurationUtils.java       |  409 ++-
 .../platform/utils/PlatformFutureUtils.java     |    2 +-
 .../platform/utils/PlatformUtils.java           |  197 +
 .../processors/plugin/CachePluginManager.java   |   25 +
 .../GridResourceJobContextInjector.java         |    4 +-
 .../message/GridClientHandshakeRequest.java     |    4 +-
 .../handlers/cache/GridCacheCommandHandler.java |    2 +-
 .../handlers/query/QueryCommandHandler.java     |    8 +-
 .../handlers/task/GridTaskCommandHandler.java   |    2 +-
 .../protocols/tcp/GridTcpRestNioListener.java   |   19 +-
 .../rest/protocols/tcp/GridTcpRestProtocol.java |   19 +-
 .../service/GridServiceAssignments.java         |   10 +-
 .../service/GridServiceNotFoundException.java   |    4 +-
 .../service/GridServiceProcessor.java           |  801 +++--
 .../processors/service/GridServiceProxy.java    |  332 +-
 .../service/LazyServiceConfiguration.java       |  129 +
 .../processors/service/ServiceContextImpl.java  |   29 +-
 .../service/ServiceDescriptorImpl.java          |   17 +-
 .../processors/task/GridTaskProcessor.java      |    6 +-
 .../processors/task/GridTaskWorker.java         |   56 +-
 .../apache/ignite/internal/util/ClassCache.java |   32 +
 .../org/apache/ignite/internal/util/F0.java     |    4 +-
 .../internal/util/GridExecutionStatistics.java  |  106 -
 .../ignite/internal/util/GridLeanSet.java       |    1 +
 .../ignite/internal/util/HostAndPortRange.java  |  205 ++
 .../internal/util/IgniteExceptionRegistry.java  |    5 +-
 .../ignite/internal/util/IgniteUtils.java       |  138 +-
 .../util/StripedCompositeReadWriteLock.java     |   24 +-
 .../internal/util/future/GridFutureAdapter.java |    3 +-
 .../shmem/IpcSharedMemoryServerEndpoint.java    |    6 +-
 .../ignite/internal/util/lang/GridFunc.java     |   99 +-
 .../ignite/internal/util/lang/GridTuple.java    |    2 -
 .../ignite/internal/util/lang/GridTuple3.java   |    2 -
 .../ignite/internal/util/lang/GridTuple4.java   |    2 -
 .../ignite/internal/util/lang/GridTuple5.java   |    2 -
 .../ignite/internal/util/lang/GridTuple6.java   |    2 -
 .../ignite/internal/util/lang/GridTupleV.java   |    1 +
 .../internal/util/nio/GridDirectParser.java     |    4 +-
 .../util/nio/GridNioRecoveryDescriptor.java     |   21 +-
 .../ignite/internal/util/nio/GridNioServer.java |   70 +-
 .../util/offheap/unsafe/GridUnsafeMap.java      |    4 +-
 .../apache/ignite/internal/util/typedef/PN.java |    2 +-
 .../apache/ignite/internal/util/typedef/X.java  |    2 +-
 .../ignite/internal/visor/cache/VisorCache.java |   75 +-
 .../cache/VisorCacheAffinityConfiguration.java  |    5 +-
 .../visor/cache/VisorCacheAffinityNodeTask.java |   70 +
 .../cache/VisorCacheAggregatedMetrics.java      |    3 +-
 .../visor/cache/VisorCacheConfiguration.java    |    8 +-
 .../cache/VisorCacheDefaultConfiguration.java   |    5 +-
 .../cache/VisorCacheEvictionConfiguration.java  |    5 +-
 .../internal/visor/cache/VisorCacheMetrics.java |   14 +-
 .../cache/VisorCacheNearConfiguration.java      |    5 +-
 .../visor/cache/VisorCachePartition.java        |   90 +
 .../visor/cache/VisorCachePartitions.java       |   89 +
 .../visor/cache/VisorCachePartitionsTask.java   |  152 +
 .../cache/VisorCacheQueryConfiguration.java     |    3 +-
 .../visor/cache/VisorCacheQueryMetrics.java     |    5 +-
 .../cache/VisorCacheRebalanceConfiguration.java |    5 +-
 .../visor/cache/VisorCacheResetMetricsTask.java |    2 +-
 .../cache/VisorCacheStoreConfiguration.java     |    3 +-
 .../cache/VisorCacheTypeFieldMetadata.java      |    3 +-
 .../visor/cache/VisorCacheTypeMetadata.java     |    3 +-
 .../internal/visor/cache/VisorCacheV3.java      |   52 +
 .../internal/visor/cache/VisorCacheV4.java      |  124 +
 .../visor/compute/VisorGatewayTask.java         |  362 ++
 .../internal/visor/debug/VisorThreadInfo.java   |    5 +-
 .../visor/debug/VisorThreadLockInfo.java        |    5 +-
 .../internal/visor/event/VisorGridEvent.java    |    5 +-
 .../internal/visor/file/VisorFileBlock.java     |    5 +-
 .../ignite/internal/visor/igfs/VisorIgfs.java   |    5 +-
 .../internal/visor/igfs/VisorIgfsEndpoint.java  |    5 +-
 .../internal/visor/igfs/VisorIgfsMetrics.java   |    5 +-
 .../visor/igfs/VisorIgfsProfilerEntry.java      |    5 +-
 .../visor/igfs/VisorIgfsProfilerTask.java       |   20 +-
 .../VisorIgfsProfilerUniformityCounters.java    |    5 +-
 .../visor/log/VisorLogSearchResult.java         |    5 +-
 .../visor/node/VisorAtomicConfiguration.java    |    5 +-
 .../visor/node/VisorBasicConfiguration.java     |    5 +-
 .../node/VisorExecutorServiceConfiguration.java |    5 +-
 .../visor/node/VisorGridConfiguration.java      |    5 +-
 .../visor/node/VisorIgfsConfiguration.java      |    3 +-
 .../visor/node/VisorLifecycleConfiguration.java |    5 +-
 .../visor/node/VisorMetricsConfiguration.java   |    5 +-
 .../visor/node/VisorNodeDataCollectorJob.java   |   49 +-
 .../node/VisorNodeDataCollectorTaskResult.java  |    5 +-
 .../node/VisorPeerToPeerConfiguration.java      |    5 +-
 .../visor/node/VisorRestConfiguration.java      |    5 +-
 .../node/VisorSegmentationConfiguration.java    |    5 +-
 .../visor/node/VisorSpisConfiguration.java      |    5 +-
 .../node/VisorTransactionConfiguration.java     |    5 +-
 .../internal/visor/query/VisorQueryField.java   |    5 +-
 .../internal/visor/query/VisorQueryResult.java  |    5 +-
 .../internal/visor/util/VisorTaskUtils.java     |   14 +-
 .../WebSessionAttributeProcessor.java           |  134 +
 .../internal/websession/WebSessionEntity.java   |  193 +
 .../apache/ignite/lang/IgniteAsyncCallback.java |  111 +
 .../java/org/apache/ignite/lang/IgniteUuid.java |    2 +-
 .../ignite/logger/java/JavaLoggerFormatter.java |    4 +-
 .../apache/ignite/marshaller/Marshaller.java    |    6 +-
 .../platform/PlatformJavaObjectFactory.java     |   36 +
 .../ignite/plugin/CachePluginProvider.java      |   11 +
 .../extensions/communication/MessageReader.java |    9 +
 .../plugin/security/SecurityPermissionSet.java  |    5 +-
 .../ignite/plugin/security/SecuritySubject.java |    5 +-
 .../SpringApplicationContextResource.java       |    4 +-
 .../apache/ignite/resources/SpringResource.java |   15 +-
 .../ignite/services/ServiceConfiguration.java   |   14 +-
 .../ignite/spi/IgniteNodeValidationResult.java  |    8 +-
 .../org/apache/ignite/spi/IgniteSpiAdapter.java |   29 +-
 .../jobstealing/JobStealingCollisionSpi.java    |   14 +-
 .../jobstealing/JobStealingDisabled.java        |    2 +-
 .../communication/tcp/TcpCommunicationSpi.java  |   52 +-
 .../tcp/TcpCommunicationSpiMBean.java           |    8 +-
 .../ignite/spi/discovery/tcp/ClientImpl.java    |   15 +-
 .../ignite/spi/discovery/tcp/ServerImpl.java    |  740 ++--
 .../spi/discovery/tcp/TcpDiscoveryImpl.java     |   13 +-
 .../spi/discovery/tcp/TcpDiscoverySpi.java      |   38 +-
 .../tcp/internal/TcpDiscoveryNode.java          |   18 +-
 .../ipfinder/jdbc/BasicJdbcIpFinderDialect.java |   28 +
 .../tcp/ipfinder/jdbc/JdbcIpFinderDialect.java  |   28 +
 .../jdbc/OracleJdbcIpFinderDialect.java         |   28 +
 .../ipfinder/jdbc/TcpDiscoveryJdbcIpFinder.java |   69 +-
 .../sharedfs/TcpDiscoverySharedFsIpFinder.java  |   60 +-
 .../messages/TcpDiscoveryAbstractMessage.java   |    4 +-
 .../TcpDiscoveryClientHeartbeatMessage.java     |    1 +
 .../TcpDiscoveryClientReconnectMessage.java     |   16 +
 .../TcpDiscoveryCustomEventMessage.java         |   13 +-
 .../TcpDiscoveryJoinRequestMessage.java         |   16 +-
 .../TcpDiscoveryStatusCheckMessage.java         |   18 +-
 .../spi/indexing/IndexingQueryFilter.java       |    9 +
 .../spi/loadbalancing/LoadBalancingSpi.java     |    8 +-
 .../adaptive/AdaptiveLoadBalancingSpi.java      |   20 +-
 .../adaptive/AdaptiveLoadProbe.java             |    2 +-
 .../roundrobin/RoundRobinLoadBalancingSpi.java  |    6 +-
 .../WeightedRandomLoadBalancingSpi.java         |   14 +-
 .../thread/IgniteStripedThreadPoolExecutor.java |  164 +-
 .../org/apache/ignite/thread/IgniteThread.java  |   34 +-
 .../ignite/thread/IgniteThreadFactory.java      |    7 +-
 .../apache/ignite/transactions/Transaction.java |   19 +-
 .../TransactionDeadlockException.java           |   42 +
 .../TransactionTimeoutException.java            |    5 +-
 .../resources/META-INF/classnames.properties    |  104 +-
 .../core/src/main/resources/ignite.properties   |    2 +-
 modules/core/src/test/config/igfs-loopback.xml  |    7 -
 modules/core/src/test/config/igfs-shmem.xml     |    7 -
 .../config/websession/example-cache-base.xml    |  148 +
 .../config/websession/example-cache-client.xml  |   33 +
 .../test/config/websession/example-cache.xml    |  128 +-
 .../test/config/websession/example-cache2.xml   |   31 +
 .../GridCacheAffinityBackupsSelfTest.java       |    2 +-
 .../affinity/AffinityClientNodeSelfTest.java    |    4 +-
 ...ityFunctionBackupFilterAbstractSelfTest.java |  131 +-
 .../affinity/AffinityHistoryCleanupTest.java    |  414 +++
 ...airAffinityFunctionBackupFilterSelfTest.java |    9 +
 .../fair/FairAffinityFunctionNodesSelfTest.java |    2 +
 .../local/LocalAffinityFunctionTest.java        |   80 +
 ...ousAffinityFunctionBackupFilterSelfTest.java |    9 +
 .../CacheJdbcPojoStoreAbstractSelfTest.java     |   69 +-
 ...eJdbcStoreAbstractMultithreadedSelfTest.java |   25 +-
 .../cache/store/jdbc/H2DataSourceFactory.java   |   35 +
 .../ignite/cache/store/jdbc/model/Person.java   |   25 +
 .../ignite/igfs/IgfsEventsAbstractSelfTest.java |   24 +-
 .../igfs/IgfsFragmentizerAbstractSelfTest.java  |    4 +-
 .../ignite/igfs/IgfsFragmentizerSelfTest.java   |    2 -
 .../ignite/internal/ClusterGroupSelfTest.java   |   30 +-
 .../internal/ClusterNodeMetricsSelfTest.java    |  101 +-
 .../ComputeJobCancelWithServiceSelfTest.java    |  154 +
 .../ignite/internal/GridAffinitySelfTest.java   |    9 +-
 ...omputationBinarylizableClosuresSelfTest.java |  413 +++
 .../GridEventStorageCheckAllEventsSelfTest.java |   30 +-
 .../ignite/internal/GridGetOrStartSelfTest.java |   70 +
 .../GridTaskCancelSingleNodeSelfTest.java       |   37 +-
 .../internal/GridTaskExecutionSelfTest.java     |   90 +-
 .../GridTaskFailoverAffinityRunTest.java        |    6 +-
 .../IgniteClientReconnectAbstractTest.java      |   15 +-
 .../IgniteClientReconnectAtomicsTest.java       |   66 +-
 .../IgniteClientReconnectCollectionsTest.java   |    4 +-
 .../IgniteClientReconnectComputeTest.java       |    6 +-
 ...eClientReconnectContinuousProcessorTest.java |   60 +-
 .../IgniteClientReconnectFailoverTest.java      |    2 +
 .../IgniteClientReconnectServicesTest.java      |    4 +-
 .../IgniteClientReconnectStreamerTest.java      |    2 +-
 ...eConcurrentEntryProcessorAccessStopTest.java |   82 +
 .../internal/TestRecordingCommunicationSpi.java |   65 +-
 .../ignite/internal/binary/AffinityKey.java     |   69 +
 .../binary/BinaryMarshallerSelfTest.java        |  223 +-
 .../BinaryObjectBuilderAdditionalSelfTest.java  |  144 +-
 ...naryObjectBuilderDefaultMappersSelfTest.java |    2 +-
 .../binary/GridBinaryAffinityKeySelfTest.java   |   15 +
 .../binary/GridBinaryWildcardsSelfTest.java     |   53 +-
 ...aultBinaryMappersBinaryMetaDataSelfTest.java |   17 +
 .../GridDiscoveryManagerAttributesSelfTest.java |  126 +
 .../BinaryObjectOffHeapUnswapTemporaryTest.java |  368 ++
 .../cache/CacheAffinityCallSelfTest.java        |   85 +-
 .../cache/CacheClientStoreSelfTest.java         |  209 +-
 ...GetEntryOptimisticReadCommittedSeltTest.java |    2 +-
 ...erceptorPartitionCounterLocalSanityTest.java |  687 ++++
 ...torPartitionCounterRandomOperationsTest.java | 1054 ++++++
 .../CacheMetricsForClusterGroupSelfTest.java    |    2 +-
 .../processors/cache/CacheNamesSelfTest.java    |   16 +-
 .../CacheNamesWithSpecialCharactersTest.java    |   71 +
 ...cheNearUpdateTopologyChangeAbstractTest.java |    2 +
 .../cache/CacheReadThroughRestartSelfTest.java  |    2 +
 .../CacheStartupInDeploymentModesTest.java      |  230 ++
 .../CacheStoreUsageMultinodeAbstractTest.java   |    5 +-
 .../cache/CacheSwapUnswapGetTest.java           |    4 +-
 .../processors/cache/CacheTxFastFinishTest.java |  253 ++
 .../cache/CrossCacheTxRandomOperationsTest.java |   13 +-
 .../EntryVersionConsistencyReadThroughTest.java |  265 ++
 .../cache/GridCacheAbstractFullApiSelfTest.java |  127 +-
 .../GridCacheAbstractLocalStoreSelfTest.java    |  480 ++-
 .../cache/GridCacheAbstractMetricsSelfTest.java |  124 +-
 .../GridCacheAbstractRemoveFailureTest.java     |   10 +-
 .../cache/GridCacheDeploymentSelfTest.java      |    2 +
 .../cache/GridCacheEntryVersionSelfTest.java    |    2 +-
 .../GridCacheOffHeapValuesEvictionSelfTest.java |   18 +-
 .../GridCachePartitionedLocalStoreSelfTest.java |    6 -
 ...chePartitionedOffHeapLocalStoreSelfTest.java |    6 -
 .../GridCachePreloadingEvictionsSelfTest.java   |    4 +-
 .../GridCacheReplicatedLocalStoreSelfTest.java  |    6 -
 ...ridCacheStoreManagerDeserializationTest.java |  354 ++
 .../cache/GridCacheStoreValueBytesSelfTest.java |    2 +-
 ...acheTcpClientDiscoveryMultiThreadedTest.java |    2 +-
 .../processors/cache/GridCacheTestEntryEx.java  |   18 +-
 ...cheTransactionalAbstractMetricsSelfTest.java |    4 +-
 .../cache/GridCacheTtlManagerSelfTest.java      |    2 +-
 ...ridCacheTxPartitionedLocalStoreSelfTest.java |    6 -
 ...idCacheValueConsistencyAbstractSelfTest.java |    9 +-
 .../GridCacheVersionTopologyChangeTest.java     |  246 ++
 ...calCacheStoreManagerDeserializationTest.java |  101 +
 .../cache/IgniteCacheAbstractTest.java          |    8 +-
 .../IgniteCacheBinaryObjectsScanSelfTest.java   |    2 +
 .../IgniteCacheConfigVariationsFullApiTest.java |   50 +-
 .../IgniteCacheEntryListenerAbstractTest.java   |   16 +-
 .../IgniteCacheEntryProcessorNodeJoinTest.java  |  147 +-
 ...niteCacheExpireAndUpdateConsistencyTest.java |  437 +++
 .../cache/IgniteCacheIncrementTxTest.java       |  299 ++
 .../IgniteCacheInterceptorSelfTestSuite.java    |    2 +
 ...gniteCacheInvokeReadThroughAbstractTest.java |  382 ++
 ...iteCacheInvokeReadThroughSingleNodeTest.java |  106 +
 .../cache/IgniteCacheInvokeReadThroughTest.java |  182 +-
 .../cache/IgniteCacheNearLockValueSelfTest.java |    2 +-
 .../IgniteCacheP2pUnmarshallingErrorTest.java   |    1 -
 ...CacheP2pUnmarshallingRebalanceErrorTest.java |   36 +-
 .../IgniteCacheP2pUnmarshallingTxErrorTest.java |    2 +
 .../cache/IgniteCachePeekModesAbstractTest.java |    8 +-
 .../IgniteCacheReadThroughEvictionSelfTest.java |  297 ++
 ...acheReadThroughEvictionsVariationsSuite.java |   58 +
 .../IgniteCacheReadThroughStoreCallTest.java    |  288 ++
 .../IgniteClientAffinityAssignmentSelfTest.java |    2 +-
 ...niteDynamicCacheStartStopConcurrentTest.java |    6 +-
 .../IgniteDynamicClientCacheStartSelfTest.java  |  107 +-
 .../cache/IgniteTxConfigCacheSelfTest.java      |  249 ++
 .../IgniteTxExceptionAbstractSelfTest.java      |   38 +-
 .../cache/IgniteTxReentryAbstractSelfTest.java  |    2 +-
 .../IgniteTxStoreExceptionAbstractSelfTest.java |    8 +-
 ...rceptorCacheConfigVariationsFullApiTest.java |  118 +
 ...terceptorWithKeepBinaryCacheFullApiTest.java |  124 +
 .../MarshallerCacheJobRunNodeRestartTest.java   |  307 ++
 .../cache/WithKeepBinaryCacheFullApiTest.java   | 1234 +++++++
 .../CacheKeepBinaryWithInterceptorTest.java     |  419 +++
 ...acheBinaryObjectUserClassloaderSelfTest.java |  274 ++
 .../GridCacheBinaryObjectsAbstractSelfTest.java |  261 +-
 ...eAbstractDataStructuresFailoverSelfTest.java |  264 +-
 ...actQueueFailoverDataConsistencySelfTest.java |    2 +-
 .../GridCacheQueueCleanupSelfTest.java          |    4 +-
 .../GridCacheSequenceApiSelfAbstractTest.java   |   37 -
 .../GridCacheSetAbstractSelfTest.java           |    5 +-
 .../GridCacheSetFailoverAbstractSelfTest.java   |    8 +-
 .../IgniteClientDataStructuresAbstractTest.java |   70 +
 .../IgniteCountDownLatchAbstractSelfTest.java   |  156 +-
 .../IgniteDataStructureUniqueNameTest.java      |   16 +-
 .../IgniteLockAbstractSelfTest.java             | 1629 +++++++++
 .../IgniteSemaphoreAbstractSelfTest.java        |   31 +
 .../local/IgniteLocalLockSelfTest.java          |  110 +
 .../IgnitePartitionedLockSelfTest.java          |   33 +
 .../IgnitePartitionedQueueNoBackupsTest.java    |    6 +-
 .../IgnitePartitionedSetNoBackupsSelfTest.java  |    6 +-
 .../IgniteReplicatedLockSelfTest.java           |   33 +
 .../CacheGetInsideLockChangingTopologyTest.java |    6 +
 ...eLateAffinityAssignmentFairAffinityTest.java |   32 +
 ...ffinityAssignmentNodeJoinValidationTest.java |  134 +
 .../CacheLateAffinityAssignmentTest.java        | 2688 ++++++++++++++
 .../GridCacheAbstractJobExecutionTest.java      |    6 +-
 .../distributed/GridCacheLockAbstractTest.java  |    2 +-
 .../GridCacheTransformEventSelfTest.java        |    2 +-
 ...niteCacheClientNodeChangingTopologyTest.java |   37 +-
 ...teCacheClientNodePartitionsExchangeTest.java |   85 +-
 .../IgniteCacheClientReconnectTest.java         |    2 +
 .../distributed/IgniteCacheCreatePutTest.java   |  143 +-
 .../distributed/IgniteCacheGetRestartTest.java  |    4 +
 .../distributed/IgniteCacheManyClientsTest.java |    6 +
 .../IgniteCacheMessageWriteTimeoutTest.java     |  129 +
 .../IgniteCacheNearRestartRollbackSelfTest.java |   28 +-
 .../distributed/IgniteCachePrimarySyncTest.java |   45 +-
 .../IgniteCacheReadFromBackupTest.java          |   12 +-
 .../IgniteCacheServerNodeConcurrentStart.java   |    3 +
 .../IgniteCacheSingleGetMessageTest.java        |    8 +-
 .../IgniteCacheTxIteratorSelfTest.java          |  241 ++
 .../IgniteTxCachePrimarySyncTest.java           | 1114 ++++++
 ...teSynchronizationModesMultithreadedTest.java |  422 +++
 .../dht/GridCacheColocatedDebugTest.java        |    2 +-
 .../dht/GridCacheDhtEvictionSelfTest.java       |   15 +-
 .../GridCacheDhtPreloadMessageCountTest.java    |    6 +-
 .../distributed/dht/GridCacheDhtTestUtils.java  |    9 +-
 ...ePartitionedNearDisabledMetricsSelfTest.java |    2 +-
 ...idCachePartitionedPreloadEventsSelfTest.java |   11 +
 ...ridCachePartitionedUnloadEventsSelfTest.java |    2 +
 .../dht/GridCacheTxNodeFailureSelfTest.java     |   12 +-
 .../dht/IgniteCacheConcurrentPutGetRemove.java  |  201 ++
 .../IgniteCachePutRetryAbstractSelfTest.java    |    4 +-
 ...imaryWriteOrderMultiNodeFullApiSelfTest.java |   35 +
 ...AtomicPartitionedTckMetricsSelfTestImpl.java |   92 +-
 .../near/GridCacheNearJobExecutionSelfTest.java |    2 -
 .../near/GridCacheNearMetricsSelfTest.java      |  152 +-
 .../near/GridCacheNearMultiNodeSelfTest.java    |    4 +-
 .../near/GridCacheNearOneNodeSelfTest.java      |    4 +-
 .../near/GridCacheNearReadersSelfTest.java      |    2 +
 .../near/GridCacheNearTxForceKeyTest.java       |    6 +-
 ...idCachePartitionedHitsAndMissesSelfTest.java |    2 +-
 ...LateAffDisabledMultiNodeFullApiSelfTest.java |   34 +
 ...achePartitionedMultiNodeCounterSelfTest.java |   43 +-
 ...achePartitionedMultiNodeFullApiSelfTest.java |    2 +
 ...achePartitionedPreloadLifecycleSelfTest.java |  102 +-
 ...idCacheRendezvousAffinityClientSelfTest.java |    2 +
 ...cingDelayedPartitionMapExchangeSelfTest.java |   14 +-
 .../GridCacheRebalancingSyncSelfTest.java       |  245 +-
 .../GridCacheReplicatedJobExecutionTest.java    |    2 -
 .../IgniteCacheSyncRebalanceModeSelfTest.java   |  116 +
 ...CacheReplicatedPreloadLifecycleSelfTest.java |  132 +-
 .../IgniteCacheExpiryPolicyAbstractTest.java    |    3 +-
 .../IgniteCacheExpiryPolicyTestSuite.java       |    6 +
 .../IgniteCacheLoaderWriterAbstractTest.java    |   10 +
 ...CacheLocalOffHeapAndSwapMetricsSelfTest.java |  415 ---
 .../CacheOffHeapAndSwapMetricsSelfTest.java     |  621 ++++
 ...dCacheAtomicLocalTckMetricsSelfTestImpl.java |   92 +-
 ...FailoverAtomicPrimaryWriteOrderSelfTest.java |   50 +
 ...sQueryAsyncFailoverTxReplicatedSelfTest.java |   37 +
 ...eContinuousQueryAsyncFailoverTxSelfTest.java |   44 +
 ...eContinuousQueryAsyncFilterListenerTest.java |  986 +++++
 ...acheContinuousQueryExecuteInPrimaryTest.java |  306 ++
 ...ryFactoryAsyncFilterRandomOperationTest.java |  131 +
 ...usQueryFactoryFilterRandomOperationTest.java |  725 ++++
 .../CacheContinuousQueryFactoryFilterTest.java  |  714 ----
 ...ContinuousQueryFailoverAbstractSelfTest.java |  112 +-
 .../CacheContinuousQueryLostPartitionTest.java  |   14 +-
 ...ontinuousQueryOperationFromCallbackTest.java |  627 ++++
 .../CacheContinuousQueryOrderingEventTest.java  |  722 ++++
 ...acheContinuousQueryRandomOperationsTest.java |  553 ++-
 ...inuousQueryRandomOperationsTwoNodesTest.java |   28 +
 .../CacheContinuousQueryVariationsTest.java     |  949 +++++
 ...CacheKeepBinaryIterationNearEnabledTest.java |   44 +
 ...acheKeepBinaryIterationStoreEnabledTest.java |   90 +
 ...CacheKeepBinaryIterationSwapEnabledTest.java |   56 +
 .../CacheKeepBinaryIterationTest.java           |  471 +++
 ...yRemoteFilterMissingInClassPathSelfTest.java |  237 ++
 ...ridCacheContinuousQueryAbstractSelfTest.java |    2 +-
 .../GridCacheContinuousQueryConcurrentTest.java |  466 +++
 ...niteCacheContinuousQueryBackupQueueTest.java |  135 +
 ...eCacheContinuousQueryImmutableEntryTest.java |  205 ++
 ...BehindStorePartitionedMultiNodeSelfTest.java |   11 +-
 .../transactions/DepthFirstSearchTest.java      |  252 ++
 .../transactions/TxDeadlockDetectionTest.java   |  495 +++
 ...simisticDeadlockDetectionCrossCacheTest.java |  165 +
 .../TxPessimisticDeadlockDetectionTest.java     |  487 +++
 .../cluster/GridAddressResolverSelfTest.java    |   97 +
 ...gniteComputeConfigVariationsFullApiTest.java | 2011 +++++++++++
 .../continuous/GridMessageListenSelfTest.java   |   30 +-
 .../IgniteNoCustomEventsOnNodeStart.java        |   85 +
 .../processors/igfs/IgfsAbstractSelfTest.java   |  247 +-
 ...lockMessageSystemPoolStarvationSelfTest.java |  299 ++
 .../igfs/IgfsClientCacheSelfTest.java           |  139 -
 .../igfs/IgfsDataManagerSelfTest.java           |   67 +-
 .../igfs/IgfsDualAbstractSelfTest.java          |   30 +-
 .../igfs/IgfsDualAsyncClientSelfTest.java       |   28 +
 .../igfs/IgfsDualSyncClientSelfTest.java        |   28 +
 .../processors/igfs/IgfsFileInfoSelfTest.java   |   31 +-
 .../igfs/IgfsMetaManagerSelfTest.java           |  125 +-
 .../processors/igfs/IgfsModesSelfTest.java      |    1 +
 .../processors/igfs/IgfsOneClientNodeTest.java  |    7 +-
 .../igfs/IgfsPrimaryClientSelfTest.java         |   30 +
 .../igfs/IgfsPrimaryMultiNodeSelfTest.java      |   28 +
 .../IgfsPrimaryOptimziedMarshallerSelfTest.java |   28 +
 ...PrimaryRelaxedConsistencyClientSelfTest.java |   28 +
 ...maryRelaxedConsistencyMultiNodeSelfTest.java |   28 +
 .../IgfsPrimaryRelaxedConsistencySelfTest.java  |   28 +
 .../processors/igfs/IgfsProcessorSelfTest.java  |   71 +-
 .../igfs/IgfsProcessorValidationSelfTest.java   |   70 +-
 .../processors/igfs/IgfsSizeSelfTest.java       |  151 +-
 .../processors/igfs/IgfsStartCacheTest.java     |    9 +-
 .../processors/igfs/IgfsStreamsSelfTest.java    |   27 +-
 .../processors/igfs/IgfsTaskSelfTest.java       |    2 +-
 ...niteMessagingConfigVariationFullApiTest.java |  484 +++
 .../odbc/OdbcProcessorValidationSelfTest.java   |  144 +
 .../service/GridServiceClientNodeTest.java      |  102 +-
 ...GridServiceProxyClientReconnectSelfTest.java |  124 +
 .../GridServiceProxyNodeStopSelfTest.java       |    2 +-
 ...gniteServiceConfigVariationsFullApiTest.java |  350 ++
 ...yment2ClassLoadersDefaultMarshallerTest.java |  259 ++
 ...eployment2ClassLoadersJdkMarshallerTest.java |   31 +
 ...ent2ClassLoadersOptimizedMarshallerTest.java |   31 +
 ...oymentClassLoadingDefaultMarshallerTest.java |  212 ++
 ...DeploymentClassLoadingJdkMarshallerTest.java |   31 +
 ...mentClassLoadingOptimizedMarshallerTest.java |   31 +
 .../internal/util/IgniteUtilsSelfTest.java      |   15 +
 ...GridUnsafeDataOutputArraySizingSelfTest.java |  144 +-
 .../unsafe/GridOffheapSnapTreeSelfTest.java     |    2 +-
 .../ignite/jvmtest/ConcurrentMapTest.java       |    3 +-
 .../cache/GridCacheDataStructuresLoadTest.java  |   53 +
 .../GridTcpCommunicationBenchmark.java          |   26 +-
 .../loadtests/hashmap/GridCacheTestContext.java |    2 +
 .../marshaller/MarshallerContextTestImpl.java   |    7 +
 .../GridP2PMissedResourceCacheSizeSelfTest.java |    6 +-
 .../platform/PlatformAttributeNodeFilter.java   |   31 +
 .../platform/PlatformCacheEntryEventFilter.java |  193 +
 .../PlatformCacheEntryEventFilterFactory.java   |   59 +
 .../platform/PlatformComputeEchoTask.java       |   11 +-
 ...latformDefaultJavaObjectFactorySelfTest.java |  185 +
 .../platform/PlatformDeployServiceTask.java     |  360 ++
 .../PlatformJavaObjectFactoryProxySelfTest.java |  220 ++
 .../ignite/platform/PlatformSqlQueryTask.java   |  117 +
 .../platform/PlatformStartIgniteTask.java       |    1 +
 .../ignite/platform/PlatformStopIgniteTask.java |    1 +
 .../ignite/platform/PlatformStringTestTask.java |   67 +
 .../platform/javaobject/TestJavaObject.java     |  271 ++
 .../javaobject/TestJavaObjectNoDefaultCtor.java |   49 +
 .../TestJavaObjectNoDefaultCtorFactory.java     |   68 +
 .../GridTcpCommunicationSpiConfigSelfTest.java  |   22 +
 .../tcp/TcpClientDiscoverySpiSelfTest.java      |   48 +-
 .../spi/discovery/tcp/TcpDiscoverySelfTest.java |  221 +-
 .../tcp/TcpDiscoverySpiConfigSelfTest.java      |   22 +
 .../TcpDiscoverySpiFailureTimeoutSelfTest.java  |   23 +-
 .../spi/discovery/tcp/TestTcpDiscoverySpi.java  |    5 +-
 .../TcpDiscoverySharedFsIpFinderSelfTest.java   |   25 +
 .../vm/TcpDiscoveryVmIpFinderSelfTest.java      |   75 +
 .../properties/NotStringSystemPropertyTest.java |  124 +
 .../ignite/testframework/GridTestUtils.java     |    5 +-
 .../configvariations/ConfigVariations.java      |    2 +-
 .../ConfigVariationsTestSuiteBuilder.java       |   31 +-
 .../configvariations/VariationsTestsConfig.java |   21 +-
 .../testframework/junits/GridAbstractTest.java  |    6 +-
 .../junits/GridTestKernalContext.java           |    1 +
 ...IgniteCacheConfigVariationsAbstractTest.java |   21 +-
 .../IgniteConfigVariationsAbstractTest.java     |  282 +-
 .../ignite/testframework/junits/IgniteMock.java |   10 +
 .../junits/common/GridCommonAbstractTest.java   |  169 +-
 .../multijvm/IgniteCacheProcessProxy.java       |    8 +
 .../multijvm/IgniteClusterProcessProxy.java     |    5 +
 .../junits/multijvm/IgniteProcessProxy.java     |    7 +
 ...naryObjectsTxDeadlockDetectionTestSuite.java |   37 +
 .../ignite/testsuites/IgniteBasicTestSuite.java |    9 +-
 .../testsuites/IgniteBinaryCacheTestSuite.java  |    2 +
 ...IgniteBinaryObjectsComputeGridTestSuite.java |    7 +-
 .../IgniteBinaryObjectsTestSuite.java           |   11 +-
 .../IgniteCacheDataStructuresSelfTestSuite.java |   17 +-
 .../IgniteCacheFullApiSelfTestSuite.java        |    6 +
 .../IgniteCacheMetricsSelfTestSuite.java        |    4 +-
 .../ignite/testsuites/IgniteCacheTestSuite.java |   16 +-
 .../testsuites/IgniteCacheTestSuite2.java       |    7 +
 .../testsuites/IgniteCacheTestSuite3.java       |    4 +
 .../testsuites/IgniteCacheTestSuite4.java       |   24 +-
 .../testsuites/IgniteCacheTestSuite5.java       |   18 +-
 ...teBasicConfigVariationsFullApiTestSuite.java |   72 +
 ...iteContinuousQueryConfigVariationsSuite.java |   60 +
 .../ignite/testsuites/IgniteIgfsTestSuite.java  |   30 +-
 .../testsuites/IgniteKernalSelfTestSuite.java   |   21 +
 .../IgniteMarshallerSelfTestSuite.java          |    2 +-
 ...essagingConfigVariationFullApiTestSuite.java |   72 +
 .../testsuites/IgnitePlatformsTestSuite.java    |   41 +
 ...ServiceConfigVariationsFullApiTestSuite.java |   92 +
 ...orCacheConfigVariationsFullApiTestSuite.java |   41 +
 .../TxDeadlockDetectionTestSuite.java           |   44 +
 ...ryCacheConfigVariationsFullApiTestSuite.java |   71 +
 modules/docker/1.6.0/Dockerfile                 |   44 +
 modules/docker/1.6.0/run.sh                     |   51 +
 modules/docker/Dockerfile                       |   24 +-
 modules/extdata/p2p/pom.xml                     |    2 +-
 ...CacheDeploymentCachePluginConfiguration.java |    7 +
 .../apache/ignite/tests/p2p/NoopService.java    |   41 +
 .../apache/ignite/tests/p2p/NoopService2.java   |   41 +
 .../extdata/uri/modules/uri-dependency/pom.xml  |    2 +-
 modules/extdata/uri/pom.xml                     |    2 +-
 modules/flink/README.txt                        |   33 +
 modules/flink/licenses/apache-2.0.txt           |  202 ++
 modules/flink/pom.xml                           |  167 +
 .../apache/ignite/sink/flink/IgniteSink.java    |  204 ++
 .../apache/ignite/sink/flink/package-info.java  |   22 +
 .../sink/flink/FlinkIgniteSinkSelfTest.java     |  188 +
 .../flink/FlinkIgniteSinkSelfTestSuite.java     |   38 +
 .../flink/src/test/resources/example-ignite.xml |   70 +
 modules/flume/pom.xml                           |    2 +-
 modules/gce/pom.xml                             |    2 +-
 modules/geospatial/pom.xml                      |    2 +-
 modules/hadoop/pom.xml                          |    2 +-
 .../hadoop/fs/BasicHadoopFileSystemFactory.java |   56 +-
 .../fs/CachingHadoopFileSystemFactory.java      |    7 +-
 .../fs/IgniteHadoopIgfsSecondaryFileSystem.java |   46 +-
 .../fs/KerberosHadoopFileSystemFactory.java     |    4 +-
 .../hadoop/fs/v1/IgniteHadoopFileSystem.java    |   19 +-
 .../hadoop/fs/v2/IgniteHadoopFileSystem.java    |   21 +-
 .../mapreduce/IgniteHadoopMapReducePlanner.java |   72 +-
 .../ignite/hadoop/util/BasicUserNameMapper.java |  112 +
 .../hadoop/util/ChainedUserNameMapper.java      |   94 +
 .../hadoop/util/KerberosUserNameMapper.java     |  137 +
 .../ignite/hadoop/util/UserNameMapper.java      |   37 +
 .../apache/ignite/hadoop/util/package-info.java |   22 +
 .../processors/hadoop/HadoopClassLoader.java    |   49 +-
 .../processors/hadoop/HadoopContext.java        |    3 +-
 .../processors/hadoop/HadoopDefaultJobInfo.java |    8 +-
 .../hadoop/igfs/HadoopIgfsProperties.java       |   11 +-
 .../hadoop/igfs/HadoopIgfsWrapper.java          |   11 +-
 .../hadoop/jobtracker/HadoopJobTracker.java     |   22 +-
 .../shuffle/collections/HadoopMultimapBase.java |   90 +-
 .../child/HadoopChildProcessRunner.java         |    4 +-
 .../processors/hadoop/v2/HadoopV2Job.java       |   14 +-
 .../hadoop/v2/HadoopV2JobResourceManager.java   |    6 +-
 .../hadoop/cache/HadoopTxConfigCacheTest.java   |   42 +
 .../util/BasicUserNameMapperSelfTest.java       |  133 +
 .../util/ChainedUserNameMapperSelfTest.java     |  107 +
 .../util/KerberosUserNameMapperSelfTest.java    |   99 +
 .../ignite/igfs/Hadoop1DualAbstractTest.java    |   51 +-
 .../igfs/HadoopFIleSystemFactorySelfTest.java   |    1 +
 ...oopFileSystemUniversalFileSystemAdapter.java |    8 +-
 .../HadoopIgfs20FileSystemAbstractSelfTest.java |    2 +
 .../igfs/HadoopIgfsDualAbstractSelfTest.java    |   11 +-
 .../apache/ignite/igfs/IgfsEventsTestSuite.java |   16 +-
 .../IgniteHadoopFileSystemAbstractSelfTest.java |    2 +
 ...IgniteHadoopFileSystemHandshakeSelfTest.java |  121 +-
 .../IgniteHadoopFileSystemLoggerSelfTest.java   |   21 +-
 .../hadoop/HadoopAbstractMapReduceTest.java     |  405 +++
 .../hadoop/HadoopClassLoaderTest.java           |    2 +-
 .../HadoopDefaultMapReducePlannerSelfTest.java  |    8 +-
 .../processors/hadoop/HadoopErrorSimulator.java |  326 ++
 .../HadoopMapReduceErrorResilienceTest.java     |  154 +
 .../processors/hadoop/HadoopMapReduceTest.java  |  379 +-
 .../hadoop/HadoopNoHadoopMapReduceTest.java     |   47 +
 .../hadoop/HadoopSnappyFullMapReduceTest.java   |    8 +
 .../processors/hadoop/HadoopSnappyTest.java     |    2 +-
 .../processors/hadoop/HadoopTasksV1Test.java    |    2 +-
 .../processors/hadoop/HadoopTasksV2Test.java    |    2 +-
 .../processors/hadoop/HadoopV2JobSelfTest.java  |    2 +-
 .../hadoop/examples/HadoopWordCount1Map.java    |   12 +
 .../hadoop/examples/HadoopWordCount1Reduce.java |    5 +
 .../hadoop/examples/HadoopWordCount2.java       |    2 +-
 .../examples/HadoopWordCount2Combiner.java      |   45 +
 .../hadoop/examples/HadoopWordCount2Mapper.java |   19 +-
 .../examples/HadoopWordCount2Reducer.java       |   43 +-
 .../collections/HadoopAbstractMapTest.java      |    6 +-
 .../testsuites/IgniteHadoopTestSuite.java       |   51 +-
 modules/hibernate/pom.xml                       |    2 +-
 .../HibernateL2CacheTransactionalSelfTest.java  |    9 +
 ...nateL2CacheTransactionalUseSyncSelfTest.java |   31 +
 .../testsuites/IgniteHibernateTestSuite.java    |    4 +-
 modules/indexing/pom.xml                        |    9 +-
 .../processors/query/h2/IgniteH2Indexing.java   |   63 +
 .../query/h2/opt/GridH2AbstractKeyValueRow.java |   23 +-
 .../query/h2/opt/GridH2IndexBase.java           |   28 +-
 .../query/h2/opt/GridH2KeyValueRowOffheap.java  |   17 +-
 .../processors/query/h2/sql/GridSqlConst.java   |    5 +
 .../processors/query/h2/sql/GridSqlJoin.java    |   17 +-
 .../query/h2/sql/GridSqlQuerySplitter.java      |    6 +-
 .../processors/query/h2/sql/GridSqlSelect.java  |    2 +-
 .../processors/query/h2/sql/GridSqlType.java    |    5 +
 .../query/h2/twostep/GridMapQueryExecutor.java  |    2 +-
 .../h2/twostep/GridReduceQueryExecutor.java     |    4 +-
 .../CacheAbstractQueryMetricsSelfTest.java      |    4 +-
 .../CacheOffheapBatchIndexingBaseTest.java      |  313 ++
 .../CacheOffheapBatchIndexingMultiTypeTest.java |  108 +
 ...CacheOffheapBatchIndexingSingleTypeTest.java |  161 +
 .../CacheOperationsWithExpirationTest.java      |  355 ++
 .../cache/GridCacheOffheapIndexGetSelfTest.java |   48 +
 .../cache/IgniteCacheAbstractQuerySelfTest.java |   34 +-
 .../IgniteCacheConfigVariationsQueryTest.java   |  505 +++
 .../cache/IgniteCacheOffheapIndexScanTest.java  |  195 +
 .../IgniteCacheQueryH2IndexingLeakTest.java     |  214 ++
 .../IgniteCacheStarvationOnRebalanceTest.java   |  166 +
 .../cache/IgniteClientReconnectQueriesTest.java |    4 +-
 .../IgniteCacheQueryNoRebalanceSelfTest.java    |   82 +
 .../IgniteCacheQueryNodeRestartSelfTest2.java   |    3 +
 .../query/IgniteSqlSplitterSelfTest.java        |   75 +
 .../query/h2/sql/GridQueryParsingTest.java      |   11 +-
 .../IgniteBinaryCacheQueryTestSuite.java        |    2 -
 .../IgniteBinaryCacheQueryTestSuite2.java       |   39 +
 .../IgniteBinaryCacheQueryTestSuite3.java       |   39 +
 .../IgniteBinaryCacheQueryTestSuite4.java       |   39 +
 ...gniteCacheConfigVariationQueryTestSuite.java |   41 +
 .../IgniteCacheQuerySelfTestSuite.java          |  109 +-
 .../IgniteCacheQuerySelfTestSuite2.java         |  111 +
 .../IgniteCacheQuerySelfTestSuite3.java         |  123 +
 .../IgniteCacheQuerySelfTestSuite4.java         |   56 +
 .../IgniteCacheWithIndexingTestSuite.java       |    4 +
 modules/jcl/pom.xml                             |    2 +-
 modules/jms11/pom.xml                           |    2 +-
 modules/jta/pom.xml                             |    2 +-
 .../websphere/WebSphereLibertyTmFactory.java    |   77 +
 .../cache/jta/websphere/WebSphereTmFactory.java |  244 ++
 .../cache/jta/websphere/package-info.java       |   22 +
 .../processors/cache/jta/CacheJtaManager.java   |   26 +-
 .../processors/cache/jta/CacheJtaResource.java  |  304 ++
 .../cache/jta/GridCacheXAResource.java          |  251 --
 .../cache/AbstarctCacheJtaSelfTest.java         |  183 -
 .../cache/AbstractCacheJtaSelfTest.java         |  183 +
 .../GridPartitionedCacheJtaFactorySelfTest.java |    2 +-
 ...rtitionedCacheJtaFactoryUseSyncSelfTest.java |   32 +
 ...titionedCacheJtaLookupClassNameSelfTest.java |    2 +-
 ...eplicatedCacheJtaFactoryUseSyncSelfTest.java |   32 +
 .../ignite/testsuites/IgniteJtaTestSuite.java   |    5 +
 modules/kafka/README.txt                        |   85 +-
 modules/kafka/pom.xml                           |    5 +-
 .../ignite/stream/kafka/KafkaStreamer.java      |    4 +-
 .../kafka/connect/IgniteSourceConnector.java    |   81 +
 .../kafka/connect/IgniteSourceConstants.java    |   44 +
 .../stream/kafka/connect/IgniteSourceTask.java  |  363 ++
 .../serialization/CacheEventConverter.java      |   66 +
 .../serialization/CacheEventDeserializer.java   |   54 +
 .../serialization/CacheEventSerializer.java     |   54 +
 .../kafka/IgniteKafkaStreamerSelfTestSuite.java |    4 +-
 .../kafka/KafkaIgniteStreamerSelfTest.java      |   11 +-
 .../ignite/stream/kafka/TestKafkaBroker.java    |   27 +-
 .../kafka/connect/IgniteSinkConnectorTest.java  |   21 +-
 .../connect/IgniteSourceConnectorMock.java      |   30 +
 .../connect/IgniteSourceConnectorTest.java      |  353 ++
 .../kafka/connect/IgniteSourceTaskMock.java     |   31 +
 .../kafka/connect/TestCacheEventFilter.java     |   31 +
 .../kafka/src/test/resources/example-ignite.xml |    4 +-
 modules/log4j/pom.xml                           |    2 +-
 modules/log4j2/pom.xml                          |    2 +-
 modules/mesos/pom.xml                           |   42 +-
 .../apache/ignite/mesos/ClusterProperties.java  |  133 +-
 .../apache/ignite/mesos/IgniteFramework.java    |   23 +-
 .../ignite/mesos/resource/IgniteProvider.java   |  198 +-
 .../ignite/mesos/resource/JettyServer.java      |   16 +-
 .../ignite/mesos/resource/ResourceProvider.java |   78 +-
 modules/mqtt/pom.xml                            |    2 +-
 modules/osgi-karaf/pom.xml                      |    2 +-
 modules/osgi-paxlogging/pom.xml                 |    2 +-
 modules/osgi/pom.xml                            |    2 +-
 modules/platforms/cpp/DEVNOTES.txt              |   66 +-
 modules/platforms/cpp/Makefile.am               |   61 +
 modules/platforms/cpp/Makefile.amrel            |   49 +
 modules/platforms/cpp/README.txt                |   29 +-
 modules/platforms/cpp/binary/Makefile.am        |   69 +
 .../platforms/cpp/binary/include/Makefile.am    |   46 +
 .../cpp/binary/include/ignite/binary/binary.h   |   34 +
 .../include/ignite/binary/binary_consts.h       |   86 +
 .../include/ignite/binary/binary_containers.h   |  650 ++++
 .../include/ignite/binary/binary_raw_reader.h   |  408 +++
 .../include/ignite/binary/binary_raw_writer.h   |  376 ++
 .../include/ignite/binary/binary_reader.h       |  446 +++
 .../binary/include/ignite/binary/binary_type.h  |  310 ++
 .../include/ignite/binary/binary_writer.h       |  414 +++
 .../include/ignite/impl/binary/binary_common.h  |  194 +
 .../ignite/impl/binary/binary_id_resolver.h     |  106 +
 .../ignite/impl/binary/binary_reader_impl.h     | 1422 ++++++++
 .../include/ignite/impl/binary/binary_schema.h  |  136 +
 .../ignite/impl/binary/binary_type_handler.h    |  102 +
 .../ignite/impl/binary/binary_type_manager.h    |  120 +
 .../ignite/impl/binary/binary_type_snapshot.h   |  122 +
 .../ignite/impl/binary/binary_type_updater.h    |   53 +
 .../include/ignite/impl/binary/binary_utils.h   |  546 +++
 .../ignite/impl/binary/binary_writer_impl.h     |  985 +++++
 .../include/ignite/impl/interop/interop.h       |   25 +
 .../ignite/impl/interop/interop_input_stream.h  |  250 ++
 .../ignite/impl/interop/interop_memory.h        |  269 ++
 .../ignite/impl/interop/interop_output_stream.h |  250 ++
 .../interop/interop_stream_position_guard.h     |   79 +
 .../cpp/binary/project/vs/binary.vcxproj        |  233 ++
 .../binary/project/vs/binary.vcxproj.filters    |  145 +
 .../cpp/binary/src/binary/binary_containers.cpp |   76 +
 .../cpp/binary/src/binary/binary_raw_reader.cpp |  166 +
 .../cpp/binary/src/binary/binary_raw_writer.cpp |  167 +
 .../cpp/binary/src/binary/binary_reader.cpp     |  173 +
 .../cpp/binary/src/binary/binary_type.cpp       |   51 +
 .../cpp/binary/src/binary/binary_writer.cpp     |  174 +
 .../src/impl/binary/binary_reader_impl.cpp      |  907 +++++
 .../binary/src/impl/binary/binary_schema.cpp    |  135 +
 .../src/impl/binary/binary_type_handler.cpp     |   78 +
 .../src/impl/binary/binary_type_manager.cpp     |  201 ++
 .../src/impl/binary/binary_type_snapshot.cpp    |   70 +
 .../src/impl/binary/binary_type_updater.cpp     |   32 +
 .../cpp/binary/src/impl/binary/binary_utils.cpp |  303 ++
 .../src/impl/binary/binary_writer_impl.cpp      |  770 ++++
 .../src/impl/interop/interop_input_stream.cpp   |  236 ++
 .../binary/src/impl/interop/interop_memory.cpp  |  171 +
 .../src/impl/interop/interop_output_stream.cpp  |  234 ++
 modules/platforms/cpp/common/Makefile.am        |   50 +-
 modules/platforms/cpp/common/configure.ac       |   62 -
 .../platforms/cpp/common/ignite-common.pc.in    |    9 -
 .../platforms/cpp/common/include/Makefile.am    |   15 +-
 .../common/include/ignite/common/concurrent.h   |  191 +-
 .../cpp/common/include/ignite/common/exports.h  |  182 -
 .../cpp/common/include/ignite/common/java.h     |  743 ----
 .../cpp/common/include/ignite/common/utils.h    |  208 +-
 .../platforms/cpp/common/include/ignite/date.h  |  138 +
 .../platforms/cpp/common/include/ignite/guid.h  |  172 +
 .../cpp/common/include/ignite/ignite_error.h    |  285 ++
 .../cpp/common/include/ignite/timestamp.h       |  166 +
 .../cpp/common/os/linux/include/Makefile.am     |    9 +-
 .../os/linux/include/ignite/common/common.h     |   57 +-
 .../linux/include/ignite/common/concurrent_os.h |    2 +-
 .../cpp/common/os/linux/src/common.cpp          |   59 -
 .../os/linux/src/common/concurrent_os.cpp       |  175 +
 .../cpp/common/os/linux/src/common/utils.cpp    |  136 +
 .../cpp/common/os/linux/src/concurrent_os.cpp   |  175 -
 .../os/win/include/ignite/common/common.h       |   26 +-
 .../win/include/ignite/common/concurrent_os.h   |    4 +-
 .../platforms/cpp/common/os/win/src/common.cpp  |   65 -
 .../common/os/win/src/common/concurrent_os.cpp  |  175 +
 .../cpp/common/os/win/src/common/utils.cpp      |  143 +
 .../cpp/common/os/win/src/concurrent_os.cpp     |  175 -
 .../cpp/common/project/vs/common.vcxproj        |   61 +-
 .../common/project/vs/common.vcxproj.filters    |   50 +-
 .../platforms/cpp/common/project/vs/module.def  |  132 -
 .../cpp/common/src/common/concurrent.cpp        |  105 +
 modules/platforms/cpp/common/src/concurrent.cpp |   94 -
 modules/platforms/cpp/common/src/date.cpp       |   83 +
 modules/platforms/cpp/common/src/exports.cpp    |  545 ---
 modules/platforms/cpp/common/src/guid.cpp       |   65 +
 .../platforms/cpp/common/src/ignite_error.cpp   |  226 ++
 modules/platforms/cpp/common/src/java.cpp       | 2735 --------------
 modules/platforms/cpp/common/src/timestamp.cpp  |  117 +
 modules/platforms/cpp/configure.ac              |  108 +
 modules/platforms/cpp/configure.acrel           |   93 +
 modules/platforms/cpp/core-test/Makefile.am     |   63 +-
 .../cpp/core-test/config/cache-query.xml        |    2 +
 .../cpp/core-test/config/cache-test.xml         |    6 +
 modules/platforms/cpp/core-test/configure.ac    |   62 -
 .../platforms/cpp/core-test/include/Makefile.am |   10 +-
 .../include/ignite/binary_test_utils.h          |   96 +
 .../cpp/core-test/project/vs/core-test.vcxproj  |   18 +-
 .../project/vs/core-test.vcxproj.filters        |    9 +
 .../src/binary_reader_writer_raw_test.cpp       |  124 +
 .../core-test/src/binary_reader_writer_test.cpp |  192 +
 .../cpp/core-test/src/binary_session_test.cpp   |   36 +
 .../cpp/core-test/src/cache_query_test.cpp      |  462 ++-
 .../platforms/cpp/core-test/src/cache_test.cpp  |   24 +
 .../cpp/core-test/src/concurrent_test.cpp       |   93 +
 .../cpp/core-test/src/ignite_error_test.cpp     |   45 +
 .../cpp/core-test/src/interop_test.cpp          |  148 +
 .../cpp/core-test/src/transactions_test.cpp     |  639 ++++
 modules/platforms/cpp/core/Makefile.am          |   86 +-
 modules/platforms/cpp/core/configure.ac         |   62 -
 modules/platforms/cpp/core/include/Makefile.am  |   83 +-
 .../cpp/core/include/ignite/binary/binary.h     |   34 -
 .../core/include/ignite/binary/binary_consts.h  |   86 -
 .../include/ignite/binary/binary_containers.h   |  530 ---
 .../include/ignite/binary/binary_raw_reader.h   |  355 --
 .../include/ignite/binary/binary_raw_writer.h   |  331 --
 .../core/include/ignite/binary/binary_reader.h  |  389 --
 .../core/include/ignite/binary/binary_type.h    |  310 --
 .../core/include/ignite/binary/binary_writer.h  |  367 --
 .../cpp/core/include/ignite/cache/cache.h       |  202 +-
 .../cpp/core/include/ignite/cache/cache_entry.h |   45 +-
 .../core/include/ignite/cache/cache_peek_mode.h |    6 +-
 .../cpp/core/include/ignite/cache/query/query.h |    6 +-
 .../include/ignite/cache/query/query_argument.h |   39 +-
 .../include/ignite/cache/query/query_cursor.h   |   70 +-
 .../ignite/cache/query/query_fields_cursor.h    |   52 +-
 .../ignite/cache/query/query_fields_row.h       |   59 +-
 .../include/ignite/cache/query/query_scan.h     |   18 +-
 .../core/include/ignite/cache/query/query_sql.h |   21 +-
 .../ignite/cache/query/query_sql_fields.h       |   21 +-
 .../include/ignite/cache/query/query_text.h     |    6 +-
 .../platforms/cpp/core/include/ignite/guid.h    |  117 -
 .../platforms/cpp/core/include/ignite/ignite.h  |   49 +-
 .../core/include/ignite/ignite_configuration.h  |   12 +-
 .../cpp/core/include/ignite/ignite_error.h      |  265 --
 .../cpp/core/include/ignite/ignition.h          |    7 +-
 .../include/ignite/impl/binary/binary_common.h  |  188 -
 .../ignite/impl/binary/binary_id_resolver.h     |  106 -
 .../ignite/impl/binary/binary_reader_impl.h     | 1309 -------
 .../include/ignite/impl/binary/binary_schema.h  |  136 -
 .../ignite/impl/binary/binary_type_handler.h    |  102 -
 .../ignite/impl/binary/binary_type_manager.h    |  120 -
 .../ignite/impl/binary/binary_type_snapshot.h   |  122 -
 .../ignite/impl/binary/binary_type_updater.h    |   53 -
 .../impl/binary/binary_type_updater_impl.h      |    8 +-
 .../include/ignite/impl/binary/binary_utils.h   |  344 --
 .../ignite/impl/binary/binary_writer_impl.h     |  913 -----
 .../core/include/ignite/impl/cache/cache_impl.h |   75 +-
 .../impl/cache/query/query_fields_row_impl.h    |   24 +-
 .../ignite/impl/cache/query/query_impl.h        |    9 +-
 .../core/include/ignite/impl/handle_registry.h  |    6 +-
 .../include/ignite/impl/ignite_environment.h    |   18 +-
 .../cpp/core/include/ignite/impl/ignite_impl.h  |   71 +-
 .../core/include/ignite/impl/interop/interop.h  |   25 -
 .../impl/interop/interop_external_memory.h      |   54 +
 .../ignite/impl/interop/interop_input_stream.h  |  250 --
 .../ignite/impl/interop/interop_memory.h        |  280 --
 .../ignite/impl/interop/interop_output_stream.h |  250 --
 .../interop/interop_stream_position_guard.h     |   79 -
 .../ignite/impl/interop/interop_target.h        |  142 +
 .../cpp/core/include/ignite/impl/operations.h   |   89 +-
 .../ignite/impl/transactions/transaction_impl.h |  220 ++
 .../impl/transactions/transactions_impl.h       |  138 +
 .../include/ignite/transactions/transaction.h   |  278 ++
 .../ignite/transactions/transaction_consts.h    |  144 +
 .../ignite/transactions/transaction_metrics.h   |  181 +
 .../include/ignite/transactions/transactions.h  |  180 +
 modules/platforms/cpp/core/namespaces.dox       |   10 +-
 .../cpp/core/os/linux/include/Makefile.am       |   23 -
 .../core/os/linux/include/ignite/impl/utils.h   |  155 -
 .../cpp/core/os/linux/src/impl/utils.cpp        |  439 ---
 .../cpp/core/os/win/include/ignite/impl/utils.h |  155 -
 .../cpp/core/os/win/src/impl/utils.cpp          |  453 ---
 .../platforms/cpp/core/project/vs/core.vcxproj  |   90 +-
 .../cpp/core/project/vs/core.vcxproj.filters    |  179 +-
 .../cpp/core/src/binary/binary_containers.cpp   |   76 -
 .../cpp/core/src/binary/binary_raw_reader.cpp   |  145 -
 .../cpp/core/src/binary/binary_raw_writer.cpp   |  147 -
 .../cpp/core/src/binary/binary_reader.cpp       |  152 -
 .../cpp/core/src/binary/binary_type.cpp         |   51 -
 .../cpp/core/src/binary/binary_writer.cpp       |  154 -
 modules/platforms/cpp/core/src/guid.cpp         |   65 -
 modules/platforms/cpp/core/src/ignite.cpp       |   12 +-
 modules/platforms/cpp/core/src/ignite_error.cpp |  222 --
 modules/platforms/cpp/core/src/ignition.cpp     |   16 +-
 .../core/src/impl/binary/binary_reader_impl.cpp |  760 ----
 .../cpp/core/src/impl/binary/binary_schema.cpp  |  135 -
 .../src/impl/binary/binary_type_handler.cpp     |   78 -
 .../src/impl/binary/binary_type_manager.cpp     |  201 --
 .../src/impl/binary/binary_type_snapshot.cpp    |   70 -
 .../src/impl/binary/binary_type_updater.cpp     |   32 -
 .../impl/binary/binary_type_updater_impl.cpp    |    5 +-
 .../cpp/core/src/impl/binary/binary_utils.cpp   |  211 --
 .../core/src/impl/binary/binary_writer_impl.cpp |  623 ----
 .../cpp/core/src/impl/cache/cache_impl.cpp      |  141 +-
 .../core/src/impl/cache/query/query_impl.cpp    |    3 +-
 .../cpp/core/src/impl/ignite_environment.cpp    |    3 +-
 .../platforms/cpp/core/src/impl/ignite_impl.cpp |   30 +-
 .../impl/interop/interop_external_memory.cpp    |   45 +
 .../src/impl/interop/interop_input_stream.cpp   |  235 --
 .../core/src/impl/interop/interop_memory.cpp    |  182 -
 .../src/impl/interop/interop_output_stream.cpp  |  233 --
 .../core/src/impl/interop/interop_target.cpp    |  142 +
 .../src/impl/transactions/transaction_impl.cpp  |  196 +
 .../src/impl/transactions/transactions_impl.cpp |  200 +
 .../cpp/core/src/transactions/transaction.cpp   |  204 ++
 .../cpp/core/src/transactions/transactions.cpp  |  142 +
 modules/platforms/cpp/cpp.dxg                   |    6 +-
 modules/platforms/cpp/examples/Makefile.am      |   26 +-
 modules/platforms/cpp/examples/README.txt       |   15 +-
 .../cpp/examples/config/example-cache.xml       |   77 -
 modules/platforms/cpp/examples/configure.ac     |   45 +-
 .../platforms/cpp/examples/include/Makefile.am  |    9 +-
 .../examples/include/ignite/examples/address.h  |   26 +-
 .../include/ignite/examples/organization.h      |   33 +-
 .../examples/include/ignite/examples/person.h   |  110 +
 .../cpp/examples/odbc-example/Makefile.am       |   57 +
 .../odbc-example/config/example-odbc.xml        |  113 +
 .../project/vs/odbc-example.vcxproj             |  108 +
 .../project/vs/odbc-example.vcxproj.filters     |   28 +
 .../examples/odbc-example/src/odbc_example.cpp  |  286 ++
 .../cpp/examples/project/vs/ignite-examples.sln |   17 +-
 .../examples/project/vs/ignite-examples.vcxproj |  107 -
 .../project/vs/ignite-examples.vcxproj.filters  |   30 -
 .../cpp/examples/putget-example/Makefile.am     |   56 +
 .../putget-example/config/example-cache.xml     |   75 +
 .../project/vs/putget-example.vcxproj           |  107 +
 .../project/vs/putget-example.vcxproj.filters   |   30 +
 .../putget-example/src/putget_example.cpp       |  126 +
 .../cpp/examples/query-example/Makefile.am      |   56 +
 .../query-example/config/query-example.xml      |  121 +
 .../project/vs/query-example.vcxproj            |  108 +
 .../project/vs/query-example.vcxproj.filters    |   27 +
 .../query-example/src/query_example.cpp         |  405 +++
 .../cpp/examples/src/putgetexample.cpp          |  126 -
 modules/platforms/cpp/ignite/Makefile.am        |   40 +-
 modules/platforms/cpp/ignite/configure.ac       |   62 -
 .../cpp/ignite/project/vs/ignite.vcxproj        |   47 +-
 .../ignite/project/vs/ignite.vcxproj.filters    |    8 -
 modules/platforms/cpp/ignite/src/ignite.cpp     |   10 +-
 modules/platforms/cpp/jni/Makefile.am           |   62 +
 modules/platforms/cpp/jni/include/Makefile.am   |   25 +
 .../cpp/jni/include/ignite/jni/exports.h        |  186 +
 .../platforms/cpp/jni/include/ignite/jni/java.h |  764 ++++
 .../cpp/jni/include/ignite/jni/utils.h          |  101 +
 .../platforms/cpp/jni/os/linux/src/utils.cpp    |  417 +++
 modules/platforms/cpp/jni/os/win/src/utils.cpp  |  428 +++
 modules/platforms/cpp/jni/project/README.TXT    |    1 +
 modules/platforms/cpp/jni/project/vs/README.TXT |    1 +
 .../platforms/cpp/jni/project/vs/jni.vcxproj    |  205 ++
 .../cpp/jni/project/vs/jni.vcxproj.filters      |   42 +
 modules/platforms/cpp/jni/project/vs/module.def |  137 +
 .../platforms/cpp/jni/project/vs/targetver.h    |   25 +
 modules/platforms/cpp/jni/src/exports.cpp       |  561 +++
 modules/platforms/cpp/jni/src/java.cpp          | 2871 +++++++++++++++
 modules/platforms/cpp/odbc-test/Makefile.am     |   81 +
 modules/platforms/cpp/odbc-test/README.TXT      |    1 +
 .../cpp/odbc-test/config/queries-test.xml       |   95 +
 .../platforms/cpp/odbc-test/include/Makefile.am |   23 +
 .../include/teamcity/teamcity_messages.h        |   55 +
 .../platforms/cpp/odbc-test/include/test_type.h |  130 +
 .../cpp/odbc-test/project/vs/odbc-test.vcxproj  |  200 +
 .../project/vs/odbc-test.vcxproj.filters        |   96 +
 .../src/application_data_buffer_test.cpp        | 1001 ++++++
 .../platforms/cpp/odbc-test/src/column_test.cpp |  290 ++
 .../cpp/odbc-test/src/configuration_test.cpp    |  224 ++
 .../cpp/odbc-test/src/connection_info_test.cpp  |  219 ++
 .../platforms/cpp/odbc-test/src/cursor_test.cpp |  205 ++
 .../platforms/cpp/odbc-test/src/parser_test.cpp |   87 +
 .../cpp/odbc-test/src/queries_test.cpp          |  516 +++
 .../platforms/cpp/odbc-test/src/row_test.cpp    |  208 ++
 .../odbc-test/src/teamcity/teamcity_boost.cpp   |  159 +
 .../src/teamcity/teamcity_messages.cpp          |  150 +
 .../cpp/odbc-test/src/utility_test.cpp          |   81 +
 modules/platforms/cpp/odbc/Makefile.am          |   84 +
 modules/platforms/cpp/odbc/README.txt           |   89 +
 modules/platforms/cpp/odbc/include/Makefile.am  |   58 +
 .../platforms/cpp/odbc/include/ignite/odbc.h    |  257 ++
 .../ignite/odbc/app/application_data_buffer.h   |  379 ++
 .../odbc/include/ignite/odbc/app/parameter.h    |  113 +
 .../cpp/odbc/include/ignite/odbc/column.h       |  155 +
 .../cpp/odbc/include/ignite/odbc/common_types.h |  225 ++
 .../include/ignite/odbc/config/configuration.h  |  164 +
 .../ignite/odbc/config/connection_info.h        |   98 +
 .../cpp/odbc/include/ignite/odbc/connection.h   |  281 ++
 .../cpp/odbc/include/ignite/odbc/cursor.h       |  114 +
 .../cpp/odbc/include/ignite/odbc/decimal.h      |  137 +
 .../ignite/odbc/diagnostic/diagnosable.h        |   82 +
 .../odbc/diagnostic/diagnosable_adapter.h       |  107 +
 .../ignite/odbc/diagnostic/diagnostic_record.h  |  165 +
 .../odbc/diagnostic/diagnostic_record_storage.h |  198 +
 .../cpp/odbc/include/ignite/odbc/environment.h  |  137 +
 .../cpp/odbc/include/ignite/odbc/message.h      |  751 ++++
 .../odbc/include/ignite/odbc/meta/column_meta.h |  195 +
 .../include/ignite/odbc/meta/primary_key_meta.h |  188 +
 .../odbc/include/ignite/odbc/meta/table_meta.h  |  166 +
 .../cpp/odbc/include/ignite/odbc/parser.h       |  137 +
 .../ignite/odbc/query/column_metadata_query.h   |  146 +
 .../odbc/include/ignite/odbc/query/data_query.h |  152 +
 .../ignite/odbc/query/foreign_keys_query.h      |  143 +
 .../ignite/odbc/query/primary_keys_query.h      |  137 +
 .../cpp/odbc/include/ignite/odbc/query/query.h  |  119 +
 .../ignite/odbc/query/special_columns_query.h   |  142 +
 .../ignite/odbc/query/table_metadata_query.h    |  150 +
 .../include/ignite/odbc/query/type_info_query.h |  118 +
 .../cpp/odbc/include/ignite/odbc/result_page.h  |  101 +
 .../cpp/odbc/include/ignite/odbc/row.h          |  132 +
 .../cpp/odbc/include/ignite/odbc/statement.h    |  525 +++
 .../include/ignite/odbc/system/odbc_constants.h |   45 +
 .../include/ignite/odbc/system/socket_client.h  |   92 +
 .../cpp/odbc/include/ignite/odbc/type_traits.h  |  316 ++
 .../cpp/odbc/include/ignite/odbc/utility.h      |  180 +
 .../cpp/odbc/install/ignite-odbc-install.ini    |    5 +
 .../cpp/odbc/install/install_amd64.cmd          |   40 +
 .../platforms/cpp/odbc/install/install_x86.cmd  |   21 +
 .../odbc/os/linux/src/system/socket_client.cpp  |  120 +
 .../odbc/os/win/src/system/socket_client.cpp    |  133 +
 modules/platforms/cpp/odbc/project/README.TXT   |    1 +
 .../platforms/cpp/odbc/project/vs/README.TXT    |    1 +
 .../platforms/cpp/odbc/project/vs/module.def    |   69 +
 .../platforms/cpp/odbc/project/vs/odbc.vcxproj  |  238 ++
 .../cpp/odbc/project/vs/odbc.vcxproj.filters    |  234 ++
 .../odbc/src/app/application_data_buffer.cpp    | 1216 +++++++
 .../platforms/cpp/odbc/src/app/parameter.cpp    |  175 +
 modules/platforms/cpp/odbc/src/column.cpp       |  488 +++
 modules/platforms/cpp/odbc/src/common_types.cpp |  120 +
 .../cpp/odbc/src/config/configuration.cpp       |  251 ++
 .../cpp/odbc/src/config/connection_info.cpp     |  428 +++
 modules/platforms/cpp/odbc/src/connection.cpp   |  347 ++
 modules/platforms/cpp/odbc/src/cursor.cpp       |   82 +
 modules/platforms/cpp/odbc/src/decimal.cpp      |  135 +
 .../odbc/src/diagnostic/diagnosable_adapter.cpp |   51 +
 .../odbc/src/diagnostic/diagnostic_record.cpp   |  241 ++
 .../diagnostic/diagnostic_record_storage.cpp    |  242 ++
 modules/platforms/cpp/odbc/src/entry_points.cpp |  694 ++++
 modules/platforms/cpp/odbc/src/environment.cpp  |  172 +
 .../platforms/cpp/odbc/src/meta/column_meta.cpp |  274 ++
 .../platforms/cpp/odbc/src/meta/table_meta.cpp  |   50 +
 modules/platforms/cpp/odbc/src/odbc.cpp         | 1364 +++++++
 .../odbc/src/query/column_metadata_query.cpp    |  318 ++
 .../platforms/cpp/odbc/src/query/data_query.cpp |  278 ++
 .../cpp/odbc/src/query/foreign_keys_query.cpp   |  131 +
 .../cpp/odbc/src/query/primary_keys_query.cpp   |  210 ++
 .../odbc/src/query/special_columns_query.cpp    |  121 +
 .../cpp/odbc/src/query/table_metadata_query.cpp |  244 ++
 .../cpp/odbc/src/query/type_info_query.cpp      |  394 ++
 modules/platforms/cpp/odbc/src/result_page.cpp  |   58 +
 modules/platforms/cpp/odbc/src/row.cpp          |  120 +
 modules/platforms/cpp/odbc/src/statement.cpp    |  524 +++
 modules/platforms/cpp/odbc/src/type_traits.cpp  |  669 ++++
 modules/platforms/cpp/odbc/src/utility.cpp      |  130 +
 modules/platforms/cpp/project/vs/ignite.sln     |   69 +-
 modules/platforms/cpp/project/vs/ignite.slnrel  |   49 +-
 .../platforms/cpp/project/vs/ignite_x86.slnrel  |   49 +-
 .../Apache.Ignite.AspNet.csproj                 |   72 +
 .../Apache.Ignite.AspNet.nuspec                 |   57 +
 .../Apache.Ignite.AspNet.ruleset                |    9 +
 .../Apache.Ignite.AspNet.snk                    |  Bin 0 -> 596 bytes
 .../IgniteOutputCacheProvider.cs                |  220 ++
 .../Apache.Ignite.AspNet/IgniteWebUtils.cs      |   44 +
 .../Properties/AssemblyInfo.cs                  |   39 +
 .../Apache.Ignite.Benchmarks.csproj             |   36 +-
 .../Properties/AssemblyInfo.cs                  |    8 +-
 .../Apache.Ignite.Core.Tests.NuGet.csproj       |   57 +-
 .../Apache.Ignite.Core.Tests.NuGet.sln          |    6 +
 .../AspNetTest.cs                               |   73 +
 .../Apache.Ignite.Core.Tests.NuGet/CacheTest.cs |   37 +-
 .../Apache.Ignite.Core.Tests.NuGet/NuGet.config |    5 +-
 .../Properties/AssemblyInfo.cs                  |    8 +-
 .../SchemaTest.cs                               |   62 +
 .../install-package.cmd                         |    3 -
 .../install-package.ps1                         |   34 +
 .../packages.config                             |   26 +
 .../Apache.Ignite.Core.Tests.TestDll.csproj     |   32 +-
 .../Properties/AssemblyInfo.cs                  |    8 +-
 .../Apache.Ignite.Core.Tests.csproj             |  142 +-
 .../AspNet/IgniteOutputCacheProviderTest.cs     |  172 +
 .../Binary/BinaryBuilderSelfTest.cs             |   87 +-
 .../Binary/BinaryBuilderSelfTestFullFooter.cs   |   31 +
 .../Binary/BinaryCompactFooterInteropTest.cs    |  128 +
 .../Binary/BinarySelfTest.cs                    |  300 +-
 .../Binary/BinarySelfTestFullFooter.cs          |   35 +
 .../Binary/BinaryStringTest.cs                  |  120 +
 .../Cache/Affinity/AffinityFieldTest.cs         |  199 +
 .../Cache/Affinity/AffinityFunctionTest.cs      |  282 ++
 .../Cache/Affinity/AffinityTest.cs              |  138 +
 .../Cache/CacheAbstractTest.cs                  |   18 +
 .../Cache/CacheAffinityTest.cs                  |  139 -
 .../Cache/CacheConfigurationTest.cs             |  207 +-
 .../Cache/CacheNearTest.cs                      |  188 +
 .../Cache/CacheTestAsyncWrapper.cs              |   12 +
 .../Cache/Query/CacheLinqTest.cs                | 1270 +++++++
 .../Query/CacheQueriesCodeConfigurationTest.cs  |   16 +-
 .../Cache/Query/CacheQueriesTest.cs             |   13 +-
 .../Continuous/ContinuousQueryAbstractTest.cs   |   43 +-
 .../Continuous/ContinuousQueryJavaFilterTest.cs |  322 ++
 .../Cache/Store/CacheStoreTest.cs               |   46 +-
 .../Cache/Store/CacheStoreTestCodeConfig.cs     |  106 +
 .../Cache/Store/CacheTestStore.cs               |    2 +-
 .../Compute/AbstractTaskTest.cs                 |    9 +
 .../Compute/BinarizableTaskTest.cs              |   13 +-
 .../Compute/ComputeApiTest.cs                   |  131 +-
 .../Compute/ComputeApiTestFullFooter.cs         |   65 +
 .../Compute/FailoverTaskSelfTest.cs             |    2 +-
 .../Compute/IgniteExceptionTaskSelfTest.cs      |   18 +-
 .../Compute/MixedClusterTest.cs                 |  123 +-
 .../Compute/ResourceTaskTest.cs                 |    8 +-
 .../Compute/TaskAdapterTest.cs                  |   16 +-
 .../Compute/TaskResultTest.cs                   |   10 +-
 .../Config/Apache.Ignite.exe.config.test2       |   58 +
 .../Config/Apache.Ignite.exe.config.test3       |   34 +
 .../Config/Cache/Store/cache-store-session.xml  |    3 +-
 .../Config/Compute/compute-grid1.xml            |   23 +-
 .../Config/Compute/compute-grid2.xml            |    5 +-
 .../Config/Compute/compute-grid3.xml            |    7 +-
 .../Config/Compute/compute-standalone.xml       |    4 +-
 .../Config/Dynamic/dynamic-client.xml           |    3 +-
 .../Config/Dynamic/dynamic-data-no-cfg.xml      |    3 +-
 .../Config/Dynamic/dynamic-data.xml             |    3 +-
 .../Config/Lifecycle/lifecycle-beans.xml        |    3 +-
 .../Config/Lifecycle/lifecycle-no-beans.xml     |    3 +-
 .../Apache.Ignite.Core.Tests/Config/binary.xml  |   56 -
 .../Config/cache-binarizables.xml               |    3 +-
 .../Config/cache-local-node.xml                 |   66 +
 .../Config/cache-query-continuous.xml           |    4 +-
 .../Config/cache-query.xml                      |    5 +-
 .../Config/ignite-dotnet-cfg.xml                |   52 +
 .../Config/marshaller-default.xml               |    3 +-
 .../Config/marshaller-explicit.xml              |    3 +-
 .../Config/marshaller-invalid.xml               |    3 +-
 .../native-client-test-cache-affinity.xml       |    5 +-
 .../native-client-test-cache-parallel-store.xml |    3 +-
 .../Config/native-client-test-cache-store.xml   |    3 +-
 .../Config/native-client-test-cache.xml         |    3 +-
 .../Config/reconnect-test.xml                   |   43 +
 .../Config/spring-test.xml                      |   46 +
 .../Config/start-test-grid1.xml                 |    3 +-
 .../Config/start-test-grid2.xml                 |    3 +-
 .../Config/start-test-grid3.xml                 |    3 +-
 .../Dataload/DataStreamerTestTopologyChange.cs  |  104 +
 .../Apache.Ignite.Core.Tests/DeploymentTest.cs  |  179 +
 .../Apache.Ignite.Core.Tests/EventsTest.cs      |    8 +-
 .../Examples/ExamplesTest.cs                    |    3 +-
 .../Examples/ProjectFilesTest.cs                |    2 +-
 .../Apache.Ignite.Core.Tests/ExceptionsTest.cs  |    5 +
 .../Apache.Ignite.Core.Tests/ExecutableTest.cs  |   88 +-
 .../IgniteConfigurationSerializerTest.cs        |  160 +-
 .../IgniteConfigurationTest.cs                  |  144 +-
 .../IgniteStartStopTest.cs                      |    1 -
 .../Apache.Ignite.Core.Tests/JavaHomeTest.cs    |   69 +
 .../Apache.Ignite.Core.Tests/LifecycleTest.cs   |    9 +
 .../Process/IgniteProcess.cs                    |   15 +-
 .../ProjectFilesTest.cs                         |    8 +-
 .../Properties/AssemblyInfo.cs                  |    8 +-
 .../Apache.Ignite.Core.Tests/ReconnectTest.cs   |   15 +-
 .../Services/ServiceProxyTest.cs                |    6 +-
 .../Services/ServicesTest.cs                    |  292 +-
 .../Services/ServicesTestFullFooter.cs          |   33 +
 .../Apache.Ignite.Core.Tests/TestRunner.cs      |   26 +-
 .../Apache.Ignite.Core.Tests/TestUtils.cs       |   18 +-
 .../WindowsServiceTest.cs                       |  124 +
 .../dotnet/Apache.Ignite.Core.Tests/app.config  |   10 +-
 .../Apache.Ignite.Core.Schema.nuspec            |   53 +
 .../Apache.Ignite.Core.csproj                   |  108 +-
 .../Apache.Ignite.Core.nuspec                   |   17 +-
 .../Binary/BinaryConfiguration.cs               |   44 +-
 .../Binary/BinaryReflectiveSerializer.cs        |  193 +-
 .../Binary/UserSerializerProxy.cs               |   68 +
 .../Cache/Affinity/AffinityFunctionBase.cs      |  190 +
 .../Cache/Affinity/AffinityFunctionContext.cs   |  116 +
 .../Cache/Affinity/AffinityKey.cs               |  162 +
 .../Affinity/AffinityKeyMappedAttribute.cs      |   46 +
 .../Cache/Affinity/AffinityTopologyVersion.cs   |  138 +
 .../Cache/Affinity/Fair/FairAffinityFunction.cs |   28 +
 .../Cache/Affinity/IAffinityFunction.cs         |   82 +
 .../Rendezvous/RendezvousAffinityFunction.cs    |   27 +
 .../Cache/Configuration/CacheConfiguration.cs   |   79 +-
 .../Configuration/NearCacheConfiguration.cs     |   75 +
 .../Cache/Configuration/QueryEntity.cs          |   13 +-
 .../Cache/Configuration/QueryField.cs           |    2 +-
 .../Cache/Eviction/EvictionPolicyBase.cs        |  126 +
 .../Cache/Eviction/FifoEvictionPolicy.cs        |   39 +
 .../Cache/Eviction/IEvictionPolicy.cs           |   32 +
 .../Cache/Eviction/LruEvictionPolicy.cs         |   39 +
 .../dotnet/Apache.Ignite.Core/Cache/ICache.cs   |   26 +
 .../Continuous/ContinuousQueryExtensions.cs     |   42 +
 .../Apache.Ignite.Core/Cluster/IClusterGroup.cs |    6 +
 .../Communication/ICommunicationSpi.cs          |   37 +
 .../Communication/Tcp/TcpCommunicationSpi.cs    |  283 ++
 .../Configuration/AtomicConfiguration.cs        |   67 +
 .../Discovery/Tcp/TcpDiscoverySpi.cs            |  161 +
 .../Apache.Ignite.Core/Events/CacheEvent.cs     |    9 +-
 .../Apache.Ignite.Core/Events/EventBase.cs      |    2 +-
 .../Apache.Ignite.Core/Events/EventReader.cs    |    8 +-
 .../dotnet/Apache.Ignite.Core/IIgnite.cs        |   75 +
 .../Apache.Ignite.Core/IgniteConfiguration.cs   |  352 +-
 .../IgniteConfigurationSection.xsd              |  102 +-
 .../dotnet/Apache.Ignite.Core/Ignition.cs       |   28 +-
 .../Impl/Binary/BinarizableSerializer.cs        |   22 +-
 .../Apache.Ignite.Core/Impl/Binary/Binary.cs    |    8 +-
 .../Impl/Binary/BinaryFullTypeDescriptor.cs     |    8 +-
 .../Impl/Binary/BinaryHandleDictionary.cs       |   32 +-
 .../Impl/Binary/BinaryObject.cs                 |    9 +-
 .../Impl/Binary/BinaryObjectBuilder.cs          |    9 +-
 .../Impl/Binary/BinaryObjectHeader.cs           |  176 +-
 .../Impl/Binary/BinaryObjectSchema.cs           |   20 +
 .../Impl/Binary/BinaryObjectSchemaHolder.cs     |   18 +-
 .../Impl/Binary/BinaryObjectSchemaSerializer.cs |  262 ++
 .../Impl/Binary/BinaryReader.cs                 |  145 +-
 .../Impl/Binary/BinaryReaderExtensions.cs       |   24 +
 .../Impl/Binary/BinaryReaderHandleDictionary.cs |    2 +-
 .../Impl/Binary/BinaryReflectiveActions.cs      |   43 +
 .../BinaryReflectiveSerializerInternal.cs       |  169 +
 .../Binary/BinarySurrogateTypeDescriptor.cs     |    4 +-
 .../Impl/Binary/BinarySystemHandlers.cs         |  147 +-
 .../Impl/Binary/BinarySystemTypeSerializer.cs   |   20 +-
 .../Impl/Binary/BinaryUtils.cs                  |  192 +-
 .../Impl/Binary/BinaryWriter.cs                 |   46 +-
 .../Impl/Binary/BinaryWriterExtensions.cs       |   78 +
 .../Impl/Binary/DateTimeSerializer.cs           |   48 +
 .../Impl/Binary/IBinarySerializerInternal.cs    |   42 +
 .../Impl/Binary/IBinarySystemTypeSerializer.cs  |   34 -
 .../Impl/Binary/IBinaryTypeDescriptor.cs        |    2 +-
 .../Impl/Binary/Io/BinaryHeapStream.cs          |    2 +-
 .../Impl/Binary/Io/BinaryStreamBase.cs          |   14 -
 .../Apache.Ignite.Core/Impl/Binary/JavaTypes.cs |   29 +-
 .../Impl/Binary/Marshaller.cs                   |  112 +-
 .../Impl/Binary/Metadata/BinaryType.cs          |   28 +-
 .../Impl/Binary/ReferenceEqualityComparer.cs    |   45 +
 .../Impl/Binary/SerializableSerializer.cs       |   48 +
 .../Apache.Ignite.Core/Impl/Cache/CacheEntry.cs |    2 +-
 .../Apache.Ignite.Core/Impl/Cache/CacheImpl.cs  |   54 +-
 .../Apache.Ignite.Core/Impl/Cache/CacheOp.cs    |    3 +-
 .../Cache/Event/JavaCacheEntryEventFilter.cs    |   49 +
 .../Impl/Cache/ICacheInternal.cs                |   40 +
 .../Continuous/ContinuousQueryHandleImpl.cs     |   17 +-
 .../Impl/Cache/Query/FieldsQueryCursor.cs       |   26 +-
 .../Impl/Cluster/ClusterGroupImpl.cs            |   21 +
 .../Impl/Cluster/ClusterNodeImpl.cs             |    2 +-
 .../Apache.Ignite.Core/Impl/Common/Classpath.cs |   18 +-
 .../Impl/Common/DelegateConverter.cs            |  175 +-
 .../Common/IgniteConfigurationXmlSerializer.cs  |   67 +-
 .../Impl/Common/IgniteHome.cs                   |    2 +-
 .../Apache.Ignite.Core/Impl/Common/Logger.cs    |   37 +
 .../Impl/Common/ObjectStringConverter.cs        |  104 +
 .../Apache.Ignite.Core/Impl/Common/Platform.cs  |   35 +
 .../Common/PlatformJavaObjectFactoryProxy.cs    |  106 +
 .../Impl/Common/TypeCaster.cs                   |   12 +
 .../Impl/Datastream/DataStreamerImpl.cs         |    9 +-
 .../Apache.Ignite.Core/Impl/ExceptionUtils.cs   |    2 +-
 .../dotnet/Apache.Ignite.Core/Impl/Ignite.cs    |  152 +-
 .../Apache.Ignite.Core/Impl/IgniteManager.cs    |   19 +-
 .../Apache.Ignite.Core/Impl/IgniteProxy.cs      |   75 +-
 .../Apache.Ignite.Core/Impl/IgniteUtils.cs      |   69 +-
 .../Impl/LifecycleBeanHolder.cs                 |    2 +-
 .../Impl/Memory/PlatformMemoryStream.cs         |    3 +-
 .../Apache.Ignite.Core/Impl/NativeMethods.cs    |    6 +
 .../Apache.Ignite.Core/Impl/PlatformTarget.cs   |   47 +-
 .../Impl/Services/ServiceDescriptor.cs          |    7 +-
 .../Impl/Services/ServiceProxyInvoker.cs        |   33 +-
 .../Impl/Services/ServiceProxySerializer.cs     |   63 +-
 .../Impl/Services/Services.cs                   |   13 +-
 .../Impl/Unmanaged/IgniteJniNativeMethods.cs    |   12 +
 .../Impl/Unmanaged/UnmanagedCallbackHandlers.cs |    6 +
 .../Impl/Unmanaged/UnmanagedCallbacks.cs        |  126 +-
 .../Impl/Unmanaged/UnmanagedUtils.cs            |   50 +-
 .../Apache.Ignite.Core/Interop/JavaObject.cs    |   80 +
 .../Lifecycle/ClientReconnectEventArgs.cs       |   47 +
 .../NuGet/LINQPad/ComputeExample.linq           |    8 +-
 .../NuGet/LINQPad/PutGetExample.linq            |    8 +-
 .../NuGet/LINQPad/QueryExample.linq             |    8 +-
 .../Properties/AssemblyInfo.cs                  |   10 +-
 .../Transactions/ITransaction.cs                |    3 +-
 .../Transactions/TransactionConfiguration.cs    |   88 +
 .../dotnet/Apache.Ignite.Core/build-common.ps1  |   77 +
 .../powershell.exe.activation_config            |   29 +
 modules/platforms/dotnet/Apache.Ignite.FxCop    |    4 +-
 .../Apache.Ignite.Linq.csproj                   |   93 +
 .../Apache.Ignite.Linq.nuspec                   |   64 +
 .../Apache.Ignite.Linq/Apache.Ignite.Linq.snk   |  Bin 0 -> 596 bytes
 .../Apache.Ignite.Linq/CacheExtensions.cs       |   98 +
 .../dotnet/Apache.Ignite.Linq/CompiledQuery.cs  |  208 ++
 .../Apache.Ignite.Linq/ICacheQueryable.cs       |   53 +
 .../Apache.Ignite.Linq/Impl/AliasDictionary.cs  |  102 +
 .../Impl/CacheFieldsQueryExecutor.cs            |  223 ++
 .../Impl/CacheFieldsQueryProvider.cs            |  239 ++
 .../Impl/CacheFieldsQueryable.cs                |   40 +
 .../Impl/CacheQueryExpressionVisitor.cs         |  506 +++
 .../Impl/CacheQueryModelVisitor.cs              |  509 +++
 .../Apache.Ignite.Linq/Impl/CacheQueryParser.cs |   56 +
 .../Apache.Ignite.Linq/Impl/CacheQueryable.cs   |   43 +
 .../Impl/CacheQueryableBase.cs                  |  122 +
 .../Apache.Ignite.Linq/Impl/ExpressionWalker.cs |  172 +
 .../Apache.Ignite.Linq/Impl/ICacheQueryProxy.cs |   40 +
 .../Impl/ICacheQueryableInternal.cs             |   54 +
 .../Apache.Ignite.Linq/Impl/MethodVisitor.cs    |  250 ++
 .../dotnet/Apache.Ignite.Linq/Impl/QueryData.cs |   92 +
 .../dotnet/Apache.Ignite.Linq/Impl/SqlTypes.cs  |   63 +
 .../NuGet/LINQPad/QueryExample.linq             |  111 +
 .../Properties/AssemblyInfo.cs                  |   40 +
 .../dotnet/Apache.Ignite.Linq/packages.config   |   22 +
 modules/platforms/dotnet/Apache.Ignite.sln      |  176 +-
 .../dotnet/Apache.Ignite.sln.DotSettings        |    7 +-
 .../dotnet/Apache.Ignite/Apache.Ignite.csproj   |   40 +-
 .../Config/AppSettingsConfigurator.cs           |   97 +-
 .../Apache.Ignite/Config/ArgsConfigurator.cs    |  145 +-
 .../dotnet/Apache.Ignite/Config/Configurator.cs |  173 +
 .../Apache.Ignite/Config/IConfigurator.cs       |   34 -
 .../dotnet/Apache.Ignite/IgniteRunner.cs        |   24 +-
 .../Apache.Ignite/Properties/AssemblyInfo.cs    |    8 +-
 .../Apache.Ignite/Service/IgniteService.cs      |  113 +-
 .../Service/IgniteServiceInstaller.cs           |   64 +
 .../Apache.Ignite/Service/NativeMethods.cs      |   57 -
 modules/platforms/dotnet/DEVNOTES.txt           |    7 +-
 modules/platforms/dotnet/build.bat              |   94 -
 .../dotnet/examples/Apache.Ignite.Examples.sln  |   24 +-
 .../Apache.Ignite.Examples.csproj               |   49 +-
 .../Compute/ClosureExample.cs                   |   10 +-
 .../Compute/TaskExample.cs                      |   13 +-
 .../Datagrid/ContinuousQueryExample.cs          |   15 +-
 .../Datagrid/DataStreamerExample.cs             |   16 +-
 .../Datagrid/LinqExample.cs                     |  247 ++
 .../Datagrid/PutGetExample.cs                   |   15 +-
 .../Datagrid/QueryExample.cs                    |   29 +-
 .../Datagrid/StoreExample.cs                    |   25 +-
 .../Datagrid/TransactionExample.cs              |   24 +-
 .../Events/EventsExample.cs                     |   14 +-
 .../Messaging/MessagingExample.cs               |   11 +-
 .../Misc/LifecycleExample.cs                    |    3 +-
 .../Properties/AssemblyInfo.cs                  |    8 +-
 .../Services/ServicesExample.cs                 |   11 +-
 .../Apache.Ignite.ExamplesDll.csproj            |   43 +-
 .../Apache.Ignite.ExamplesDll/Binary/Account.cs |    1 -
 .../Apache.Ignite.ExamplesDll/Binary/Address.cs |    5 +-
 .../Binary/Employee.cs                          |    4 +
 .../Binary/EmployeeKey.cs                       |    6 +-
 .../Binary/Organization.cs                      |   11 +-
 .../Binary/OrganizationType.cs                  |    3 -
 .../Datagrid/EmployeeStoreFactory.cs            |   38 +
 .../Properties/AssemblyInfo.cs                  |    8 +-
 .../examples/Config/example-cache-query.xml     |  118 -
 .../examples/Config/example-cache-store.xml     |   59 -
 .../dotnet/examples/Config/example-cache.xml    |   87 -
 .../dotnet/examples/Config/example-compute.xml  |   70 -
 .../dotnet/examples/Config/examples-config.xml  |   98 +
 modules/rest-http/pom.xml                       |   27 +-
 .../http/jetty/GridJettyJsonConfig.java         |  195 -
 .../http/jetty/GridJettyObjectMapper.java       |  274 ++
 .../http/jetty/GridJettyRestHandler.java        |  127 +-
 .../http/jetty/GridJettyRestProtocol.java       |    6 +-
 modules/scalar-2.10/pom.xml                     |    2 +-
 modules/scalar/pom.xml                          |    2 +-
 .../scalar/pimps/ScalarProjectionPimp.scala     |    4 +-
 .../scalar/pimps/ScalarTaskThreadContext.scala  |    4 +-
 modules/schedule/pom.xml                        |    2 +-
 modules/schema-import-db/README.txt             |    4 +
 modules/schema-import-db/pom.xml                |   43 +
 .../apache/ignite/schema/parser/DbColumn.java   |   76 +
 .../ignite/schema/parser/DbMetadataReader.java  |  147 +
 .../apache/ignite/schema/parser/DbTable.java    |   82 +
 .../parser/dialect/DB2MetadataDialect.java      |   33 +
 .../parser/dialect/DatabaseMetadataDialect.java |   75 +
 .../parser/dialect/JdbcMetadataDialect.java     |  197 +
 .../parser/dialect/MySQLMetadataDialect.java    |   62 +
 .../parser/dialect/OracleMetadataDialect.java   |  364 ++
 modules/schema-import/README.txt                |   12 +-
 modules/schema-import/pom.xml                   |    8 +-
 .../ignite/schema/generator/CodeGenerator.java  |  134 +-
 .../ignite/schema/generator/GeneratorUtils.java |   70 +
 .../ignite/schema/generator/XmlGenerator.java   |  107 +-
 .../schema/parser/DatabaseMetadataParser.java   |   50 +-
 .../apache/ignite/schema/parser/DbColumn.java   |   76 -
 .../apache/ignite/schema/parser/DbTable.java    |   82 -
 .../parser/dialect/DB2MetadataDialect.java      |   33 -
 .../parser/dialect/DatabaseMetadataDialect.java |   75 -
 .../parser/dialect/JdbcMetadataDialect.java     |  197 -
 .../parser/dialect/MySQLMetadataDialect.java    |   61 -
 .../parser/dialect/OracleMetadataDialect.java   |  364 --
 .../ignite/schema/ui/SchemaImportApp.java       |  548 ++-
 .../schema/test/AbstractSchemaImportTest.java   |   10 +-
 .../schema/test/generator/XmlGeneratorTest.java |    4 +-
 .../apache/ignite/schema/test/model/Objects.txt |   31 +-
 .../ignite/schema/test/model/Primitives.txt     |   31 +-
 .../org/apache/ignite/schema/test/model/Tst.txt |   31 +-
 .../schema/test/model/ignite-type-metadata.xml  |   86 +-
 .../test/parser/DbMetadataParserTest.java       |    2 +-
 modules/slf4j/pom.xml                           |    2 +-
 modules/spark-2.10/pom.xml                      |    2 +-
 modules/spark/pom.xml                           |    2 +-
 .../org/apache/ignite/spark/IgniteContext.scala |   77 +-
 .../org/apache/ignite/spark/IgniteRDD.scala     |  125 +-
 .../apache/ignite/spark/JavaIgniteContext.scala |   18 +-
 .../org/apache/ignite/spark/JavaIgniteRDD.scala |   17 +-
 .../ignite/spark/impl/IgniteAbstractRDD.scala   |   15 +-
 .../apache/ignite/spark/impl/IgniteSqlRDD.scala |    5 +-
 .../spark/impl/JavaIgniteAbstractRDD.scala      |   34 -
 .../spark/JavaEmbeddedIgniteRDDSelfTest.java    |  344 ++
 .../ignite/spark/JavaIgniteRDDSelfTest.java     |  302 --
 .../spark/JavaStandaloneIgniteRDDSelfTest.java  |  365 ++
 .../ignite/testsuites/IgniteRDDTestSuite.java   |   40 +
 .../ignite/spark/EntityTestAllTypeFields.scala  |   60 +
 .../org/apache/ignite/spark/IgniteRDDSpec.scala |  165 +-
 modules/spring/pom.xml                          |    2 +-
 .../org/apache/ignite/IgniteSpringBean.java     |  152 +-
 .../GridResourceSpringBeanInjector.java         |   39 +-
 .../src/test/config/jdbc-pojo-store-builtin.xml |  194 +
 .../src/test/config/jdbc-pojo-store-obj.xml     |  194 +
 .../store/jdbc/CachePojoStoreXmlSelfTest.java   |   51 +
 .../ignite/internal/GridFactorySelfTest.java    |  112 +-
 .../ignite/internal/IgniteSpringBeanTest.java   |   55 +
 .../GridSpringResourceInjectionSelfTest.java    |  311 +-
 .../spring-resource-with-duplicate-beans.xml    |   30 +
 .../processors/resource/spring-resource.xml     |    2 +-
 .../GridServiceInjectionSpringResourceTest.java |  245 ++
 .../spring/injection/spring-resource.tmpl.xml   |   66 +
 .../testsuites/IgniteSpringTestSuite.java       |    5 +
 modules/ssh/pom.xml                             |    2 +-
 modules/storm/pom.xml                           |    2 +-
 modules/tools/pom.xml                           |    2 +-
 modules/twitter/pom.xml                         |    2 +-
 modules/urideploy/pom.xml                       |    2 +-
 .../uri/GridUriDeploymentFileProcessor.java     |    2 +-
 modules/visor-console-2.10/pom.xml              |    2 +-
 modules/visor-console/pom.xml                   |    2 +-
 .../commands/alert/VisorAlertCommand.scala      |  359 +-
 .../commands/cache/VisorCacheCommand.scala      |   12 +-
 .../commands/disco/VisorDiscoveryCommand.scala  |    7 +-
 .../commands/events/VisorEventsCommand.scala    |    7 +-
 .../commands/tasks/VisorTasksCommand.scala      |    7 +-
 .../commands/top/VisorTopologyCommand.scala     |    2 +-
 .../scala/org/apache/ignite/visor/visor.scala   |   34 +-
 .../commands/alert/VisorAlertCommandSpec.scala  |    2 +-
 modules/visor-plugins/pom.xml                   |    2 +-
 modules/web-agent/.gitignore                    |    2 +
 modules/web-agent/README.txt                    |   88 +
 .../web-agent/assembly/release-web-agent.xml    |   72 +
 modules/web-agent/bin/ignite-web-agent.bat      |   70 +
 modules/web-agent/bin/ignite-web-agent.sh       |   87 +
 modules/web-agent/demo/README.txt               |    4 +
 modules/web-agent/demo/db-init.sql              |  102 +
 modules/web-agent/jdbc-drivers/README.txt       |   10 +
 modules/web-agent/logs/README.txt               |    5 +
 modules/web-agent/pom.xml                       |  189 +
 .../console/agent/AgentConfiguration.java       |  268 ++
 .../ignite/console/agent/AgentLauncher.java     |  344 ++
 .../apache/ignite/console/agent/AgentUtils.java |  111 +
 .../console/agent/handlers/AbstractHandler.java |  110 +
 .../console/agent/handlers/DatabaseHandler.java |  298 ++
 .../console/agent/handlers/RestHandler.java     |  276 ++
 .../ignite/console/demo/AgentClusterDemo.java   |  638 ++++
 .../ignite/console/demo/AgentMetadataDemo.java  |   92 +
 .../apache/ignite/console/demo/model/Car.java   |  152 +
 .../ignite/console/demo/model/Country.java      |  152 +
 .../ignite/console/demo/model/Department.java   |  152 +
 .../ignite/console/demo/model/Employee.java     |  356 ++
 .../ignite/console/demo/model/Parking.java      |  152 +
 .../src/main/resources/log4j.properties         |   53 +
 modules/web-console/DEVNOTES.txt                |   27 +
 modules/web-console/README.txt                  |   36 +
 modules/web-console/licenses/apache-2.0.txt     |  202 ++
 modules/web-console/pom.xml                     |   69 +
 modules/web-console/src/main/js/.babelrc        |    3 +
 modules/web-console/src/main/js/.eslintrc       |  202 ++
 modules/web-console/src/main/js/.gitignore      |   11 +
 .../src/main/js/app/data/colors.json            |   22 +
 .../src/main/js/app/data/countries.json         |   94 +
 .../src/main/js/app/data/demo-info.json         |   14 +
 .../src/main/js/app/data/event-types.json       |  169 +
 .../src/main/js/app/data/getting-started.json   |  109 +
 .../src/main/js/app/data/java-classes.json      |   18 +
 .../src/main/js/app/data/java-keywords.json     |   55 +
 .../src/main/js/app/data/java-primitives.json   |    9 +
 .../src/main/js/app/data/pom-dependencies.json  |   20 +
 .../src/main/js/app/decorator/select.js         |   77 +
 .../src/main/js/app/decorator/tooltip.js        |   56 +
 .../app/directives/bs-affix-update.directive.js |   34 +
 .../js/app/directives/centered/centered.css     |   37 +
 .../directives/centered/centered.directive.js   |   26 +
 .../hide-on-state-change.directive.js           |   31 +
 .../information/information.directive.js        |   30 +
 .../app/directives/information/information.jade |   20 +
 .../app/directives/information/information.scss |   56 +
 .../ui-ace-docker/ui-ace-docker.controller.js   |   33 +
 .../ui-ace-docker/ui-ace-docker.directive.js    |   46 +
 .../directives/ui-ace-docker/ui-ace-docker.jade |   31 +
 .../ui-ace-java/ui-ace-java.controller.js       |   32 +
 .../ui-ace-java/ui-ace-java.directive.js        |  133 +
 .../app/directives/ui-ace-java/ui-ace-java.jade |   22 +
 .../ui-ace-pojos/ui-ace-pojos.controller.js     |   95 +
 .../ui-ace-pojos/ui-ace-pojos.directive.js      |   46 +
 .../directives/ui-ace-pojos/ui-ace-pojos.jade   |   40 +
 .../ui-ace-pom/ui-ace-pom.controller.js         |   33 +
 .../ui-ace-pom/ui-ace-pom.directive.js          |   41 +
 .../app/directives/ui-ace-pom/ui-ace-pom.jade   |   17 +
 .../js/app/directives/ui-ace-tabs.directive.js  |   23 +
 .../ui-ace-xml/ui-ace-xml.controller.js         |   27 +
 .../ui-ace-xml/ui-ace-xml.directive.js          |  133 +
 .../app/directives/ui-ace-xml/ui-ace-xml.jade   |   17 +
 .../src/main/js/app/filters/byName.filter.js    |   23 +
 .../src/main/js/app/filters/hasPojo.filter.js   |   18 +
 .../src/main/js/app/helpers/jade/mixins.jade    |  588 +++
 modules/web-console/src/main/js/app/index.js    |  241 ++
 .../src/main/js/app/modules/Demo/Demo.module.js |  167 +
 .../js/app/modules/Version/Version.provider.js  |   32 +
 .../src/main/js/app/modules/ace.module.js       |  269 ++
 .../main/js/app/modules/agent/agent.module.js   |  323 ++
 .../js/app/modules/branding/branding.module.js  |   46 +
 .../app/modules/branding/branding.provider.js   |  111 +
 .../app/modules/branding/features.directive.js  |   35 +
 .../js/app/modules/branding/footer.directive.js |   34 +
 .../modules/branding/header-logo.directive.js   |   34 +
 .../js/app/modules/branding/header-logo.jade    |   18 +
 .../modules/branding/header-title.directive.js  |   35 +
 .../branding/powered-by-apache.directive.js     |   35 +
 .../app/modules/branding/powered-by-apache.jade |   18 +
 .../js/app/modules/branding/terms.directive.js  |   30 +
 .../configuration/EventGroups.provider.js       |   30 +
 .../modules/configuration/Sidebar.provider.js   |   39 +
 .../configuration/configuration.module.js       |   41 +
 .../configuration/generator/Docker.service.js   |   78 +
 .../configuration/generator/Java.service.js     |   21 +
 .../configuration/generator/Pom.service.js      |  210 ++
 .../configuration/generator/Xml.service.js      |   21 +
 .../modules/configuration/sidebar.directive.js  |   30 +
 .../modules/dialog/dialog-content.directive.js  |   31 +
 .../modules/dialog/dialog-title.directive.js    |   31 +
 .../js/app/modules/dialog/dialog.controller.js  |   40 +
 .../js/app/modules/dialog/dialog.directive.js   |   32 +
 .../js/app/modules/dialog/dialog.factory.js     |   32 +
 .../src/main/js/app/modules/dialog/dialog.jade  |   26 +
 .../main/js/app/modules/dialog/dialog.module.js |   32 +
 .../field/bs-select-placeholder.directive.js    |   46 +
 .../js/app/modules/form/field/down.directive.js |   43 +
 .../modules/form/field/dropdown.directive.js    |   84 +
 .../js/app/modules/form/field/dropdown.jade     |   61 +
 .../main/js/app/modules/form/field/field.css    |   23 +
 .../app/modules/form/field/field.directive.js   |   44 +
 .../main/js/app/modules/form/field/field.jade   |   27 +
 .../field/form-control-feedback.directive.js    |   40 +
 .../form/field/input/autofocus.directive.js     |   30 +
 .../form/field/input/checkbox.directive.js      |   67 +
 .../app/modules/form/field/input/checkbox.jade  |   30 +
 .../form/field/input/datalist.directive.js      |  123 +
 .../app/modules/form/field/input/datalist.jade  |   51 +
 .../form/field/input/number.directive.js        |   77 +
 .../js/app/modules/form/field/input/number.jade |   50 +
 .../js/app/modules/form/field/input/text.css    |   41 +
 .../modules/form/field/input/text.directive.js  |  127 +
 .../js/app/modules/form/field/input/text.jade   |   48 +
 .../app/modules/form/field/label.directive.js   |   47 +
 .../app/modules/form/field/tooltip.directive.js |   49 +
 .../js/app/modules/form/field/up.directive.js   |   44 +
 .../src/main/js/app/modules/form/form.module.js |  101 +
 .../js/app/modules/form/group/add.directive.js  |   40 +
 .../app/modules/form/group/group.directive.js   |   81 +
 .../main/js/app/modules/form/group/group.jade   |   21 +
 .../app/modules/form/group/table.directive.js   |   29 +
 .../main/js/app/modules/form/group/table.jade   |   17 +
 .../app/modules/form/group/tooltip.directive.js |   40 +
 .../app/modules/form/panel/chevron.directive.js |   53 +
 .../app/modules/form/panel/panel.directive.js   |   37 +
 .../app/modules/form/panel/revert.directive.js  |   53 +
 .../form/validator/ipaddress.directive.js       |   86 +
 .../validator/java-built-in-class.directive.js  |   31 +
 .../form/validator/java-identifier.directive.js |   31 +
 .../form/validator/java-keywords.directive.js   |   42 +
 .../validator/java-package-name.directive.js    |   31 +
 .../java-package-specified.directive.js         |   34 +
 .../form/validator/property-unique.directive.js |   47 +
 .../property-value-specified.directive.js       |   31 +
 .../modules/form/validator/unique.directive.js  |   49 +
 .../getting-started/GettingStarted.provider.js  |  112 +
 .../src/main/js/app/modules/loading/loading.css |   73 +
 .../js/app/modules/loading/loading.directive.js |   51 +
 .../main/js/app/modules/loading/loading.jade    |   23 +
 .../js/app/modules/loading/loading.module.js    |   26 +
 .../js/app/modules/loading/loading.service.js   |   48 +
 .../js/app/modules/navbar/Navbar.provider.js    |   28 +
 .../js/app/modules/navbar/Userbar.provider.js   |   28 +
 .../js/app/modules/navbar/navbar.directive.js   |   30 +
 .../main/js/app/modules/navbar/navbar.module.js |   33 +
 .../js/app/modules/navbar/userbar.directive.js  |   48 +
 .../query-notebooks/query-notebooks.module.js   |  115 +
 .../src/main/js/app/modules/socket.module.js    |   41 +
 .../main/js/app/modules/states/admin.state.js   |   34 +
 .../app/modules/states/configuration.state.js   |  226 ++
 .../caches/concurrency.directive.js             |   27 +
 .../configuration/caches/concurrency.jade       |   65 +
 .../configuration/caches/general.directive.js   |   27 +
 .../states/configuration/caches/general.jade    |   65 +
 .../configuration/caches/memory.directive.js    |   27 +
 .../states/configuration/caches/memory.jade     |   88 +
 .../configuration/caches/query.directive.js     |   27 +
 .../states/configuration/caches/query.jade      |   93 +
 .../configuration/caches/rebalance.directive.js |   27 +
 .../states/configuration/caches/rebalance.jade  |   65 +
 .../caches/server-near-cache.directive.js       |   27 +
 .../configuration/caches/server-near-cache.jade |   45 +
 .../caches/statistics.directive.js              |   27 +
 .../states/configuration/caches/statistics.jade |   37 +
 .../configuration/caches/store.directive.js     |   27 +
 .../states/configuration/caches/store.jade      |  271 ++
 .../configuration/clusters/atomic.directive.js  |   27 +
 .../states/configuration/clusters/atomic.jade   |   53 +
 .../clusters/attributes.directive.js            |   27 +
 .../configuration/clusters/attributes.jade      |   58 +
 .../configuration/clusters/binary.directive.js  |   27 +
 .../states/configuration/clusters/binary.jade   |  100 +
 .../clusters/collision.directive.js             |   27 +
 .../configuration/clusters/collision.jade       |   60 +
 .../clusters/collision/custom.directive.js      |   27 +
 .../clusters/collision/custom.jade              |   24 +
 .../clusters/collision/fifo-queue.directive.js  |   27 +
 .../clusters/collision/fifo-queue.jade          |   28 +
 .../collision/job-stealing.directive.js         |   27 +
 .../clusters/collision/job-stealing.jade        |   64 +
 .../collision/priority-queue.directive.js       |   27 +
 .../clusters/collision/priority-queue.jade      |   43 +
 .../clusters/communication.directive.js         |   27 +
 .../configuration/clusters/communication.jade   |   96 +
 .../clusters/connector.directive.js             |   27 +
 .../configuration/clusters/connector.jade       |  103 +
 .../clusters/deployment.directive.js            |   27 +
 .../configuration/clusters/deployment.jade      |  119 +
 .../clusters/discovery.directive.js             |   27 +
 .../configuration/clusters/discovery.jade       |   83 +
 .../configuration/clusters/events.directive.js  |   27 +
 .../states/configuration/clusters/events.jade   |   37 +
 .../clusters/failover.directive.js              |   27 +
 .../states/configuration/clusters/failover.jade |   82 +
 .../configuration/clusters/general.directive.js |   27 +
 .../states/configuration/clusters/general.jade  |   68 +
 .../general/discovery/cloud.directive.js        |   27 +
 .../clusters/general/discovery/cloud.jade       |  127 +
 .../general/discovery/google.directive.js       |   27 +
 .../clusters/general/discovery/google.jade      |   38 +
 .../general/discovery/jdbc.directive.js         |   27 +
 .../clusters/general/discovery/jdbc.jade        |   24 +
 .../general/discovery/multicast.directive.js    |   27 +
 .../clusters/general/discovery/multicast.jade   |  109 +
 .../clusters/general/discovery/s3.directive.js  |   27 +
 .../clusters/general/discovery/s3.jade          |   27 +
 .../general/discovery/shared.directive.js       |   27 +
 .../clusters/general/discovery/shared.jade      |   23 +
 .../clusters/general/discovery/vm.directive.js  |   27 +
 .../clusters/general/discovery/vm.jade          |   90 +
 .../general/discovery/zookeeper.directive.js    |   27 +
 .../clusters/general/discovery/zookeeper.jade   |   74 +
 .../bounded-exponential-backoff.directive.js    |   27 +
 .../bounded-exponential-backoff.jade            |   27 +
 .../zookeeper/retrypolicy/custom.directive.js   |   27 +
 .../discovery/zookeeper/retrypolicy/custom.jade |   24 +
 .../exponential-backoff.directive.js            |   27 +
 .../retrypolicy/exponential-backoff.jade        |   27 +
 .../zookeeper/retrypolicy/forever.directive.js  |   27 +
 .../zookeeper/retrypolicy/forever.jade          |   22 +
 .../zookeeper/retrypolicy/n-times.directive.js  |   27 +
 .../zookeeper/retrypolicy/n-times.jade          |   25 +
 .../zookeeper/retrypolicy/one-time.directive.js |   27 +
 .../zookeeper/retrypolicy/one-time.jade         |   23 +
 .../retrypolicy/until-elapsed.directive.js      |   27 +
 .../zookeeper/retrypolicy/until-elapsed.jade    |   25 +
 .../configuration/clusters/igfs.directive.js    |   27 +
 .../states/configuration/clusters/igfs.jade     |   37 +
 .../configuration/clusters/logger.directive.js  |   27 +
 .../states/configuration/clusters/logger.jade   |   65 +
 .../clusters/logger/custom.directive.js         |   27 +
 .../configuration/clusters/logger/custom.jade   |   24 +
 .../clusters/logger/log4j.directive.js          |   27 +
 .../configuration/clusters/logger/log4j.jade    |   49 +
 .../clusters/logger/log4j2.directive.js         |   27 +
 .../configuration/clusters/logger/log4j2.jade   |   38 +
 .../clusters/marshaller.directive.js            |   27 +
 .../configuration/clusters/marshaller.jade      |   69 +
 .../configuration/clusters/metrics.directive.js |   27 +
 .../states/configuration/clusters/metrics.jade  |   50 +
 .../configuration/clusters/ssl.directive.js     |   27 +
 .../states/configuration/clusters/ssl.jade      |  108 +
 .../configuration/clusters/swap.directive.js    |   27 +
 .../states/configuration/clusters/swap.jade     |   67 +
 .../configuration/clusters/thread.directive.js  |   27 +
 .../states/configuration/clusters/thread.jade   |   48 +
 .../configuration/clusters/time.directive.js    |   27 +
 .../states/configuration/clusters/time.jade     |   47 +
 .../clusters/transactions.directive.js          |   27 +
 .../configuration/clusters/transactions.jade    |   59 +
 .../configuration/domains/general.directive.js  |   27 +
 .../states/configuration/domains/general.jade   |   46 +
 .../configuration/domains/query.directive.js    |   27 +
 .../states/configuration/domains/query.jade     |  169 +
 .../configuration/domains/store.directive.js    |   27 +
 .../states/configuration/domains/store.jade     |  126 +
 .../states/configuration/igfs/dual.directive.js |   27 +
 .../modules/states/configuration/igfs/dual.jade |   42 +
 .../igfs/fragmentizer.directive.js              |   27 +
 .../states/configuration/igfs/fragmentizer.jade |   43 +
 .../configuration/igfs/general.directive.js     |   27 +
 .../states/configuration/igfs/general.jade      |   53 +
 .../states/configuration/igfs/ipc.directive.js  |   27 +
 .../modules/states/configuration/igfs/ipc.jade  |   57 +
 .../states/configuration/igfs/misc.directive.js |   27 +
 .../modules/states/configuration/igfs/misc.jade |  108 +
 .../configuration/igfs/secondary.directive.js   |   27 +
 .../states/configuration/igfs/secondary.jade    |   44 +
 .../configuration/preview-panel.directive.js    |  239 ++
 .../summary/summary-tabs.directive.js           |   50 +
 .../configuration/summary/summary.controller.js |  360 ++
 .../configuration/summary/summary.resource.js   |   40 +
 .../main/js/app/modules/states/logout.state.js  |   36 +
 .../js/app/modules/states/password.state.js     |   46 +
 .../main/js/app/modules/states/profile.state.js |   34 +
 .../main/js/app/modules/states/signin.state.js  |   52 +
 .../src/main/js/app/modules/states/sql.state.js |   46 +
 .../main/js/app/modules/user/Auth.service.js    |   76 +
 .../main/js/app/modules/user/User.service.js    |   65 +
 .../src/main/js/app/modules/user/user.module.js |   28 +
 .../main/js/app/services/ChartColors.service.js |   22 +
 .../main/js/app/services/Countries.service.js   |   31 +
 .../main/js/app/services/InetAddress.service.js |   53 +
 .../main/js/app/services/JavaTypes.service.js   |   84 +
 .../src/main/js/app/services/cleanup.service.js |   46 +
 .../src/main/js/app/services/confirm.service.js |   70 +
 .../src/main/js/build/system.config.js          |  424 +++
 .../src/main/js/controllers/admin-controller.js |   92 +
 .../main/js/controllers/caches-controller.js    |  477 +++
 .../main/js/controllers/clusters-controller.js  |  634 ++++
 .../src/main/js/controllers/common-module.js    | 1741 +++++++++
 .../main/js/controllers/domains-controller.js   | 1761 +++++++++
 .../src/main/js/controllers/igfs-controller.js  |  413 +++
 .../main/js/controllers/profile-controller.js   |   92 +
 .../src/main/js/controllers/sql-controller.js   | 1595 ++++++++
 .../src/main/js/generator/generator-common.js   |  611 ++++
 .../src/main/js/generator/generator-java.js     | 3403 ++++++++++++++++++
 .../src/main/js/generator/generator-optional.js |   25 +
 .../main/js/generator/generator-properties.js   |  150 +
 .../src/main/js/generator/generator-readme.js   |   85 +
 .../src/main/js/generator/generator-xml.js      | 1979 ++++++++++
 .../src/main/js/gulpfile.babel.js/index.js      |   26 +
 .../src/main/js/gulpfile.babel.js/paths.js      |  101 +
 .../main/js/gulpfile.babel.js/tasks/build.js    |   21 +
 .../main/js/gulpfile.babel.js/tasks/bundle.js   |   76 +
 .../main/js/gulpfile.babel.js/tasks/clean.js    |   35 +
 .../main/js/gulpfile.babel.js/tasks/connect.js  |   47 +
 .../src/main/js/gulpfile.babel.js/tasks/copy.js |   57 +
 .../main/js/gulpfile.babel.js/tasks/eslint.js   |   46 +
 .../gulpfile.babel.js/tasks/ignite-modules.js   |   56 +
 .../src/main/js/gulpfile.babel.js/tasks/jade.js |   40 +
 .../src/main/js/gulpfile.babel.js/tasks/sass.js |   25 +
 .../main/js/gulpfile.babel.js/tasks/watch.js    |   39 +
 .../src/main/js/ignite_modules/README.txt       |    6 +
 .../src/main/js/ignite_modules/index.js         |   27 +
 modules/web-console/src/main/js/package.json    |  271 ++
 .../web-console/src/main/js/public/favicon.ico  |  Bin 0 -> 1150 bytes
 .../src/main/js/public/images/cache.png         |  Bin 0 -> 23700 bytes
 .../src/main/js/public/images/cluster.png       |  Bin 0 -> 29376 bytes
 .../src/main/js/public/images/docker.png        |  Bin 0 -> 521 bytes
 .../src/main/js/public/images/domains.png       |  Bin 0 -> 23828 bytes
 .../src/main/js/public/images/igfs.png          |  Bin 0 -> 14307 bytes
 .../src/main/js/public/images/ignite-logo.png   |  Bin 0 -> 1982 bytes
 .../main/js/public/images/ignite-logo@2x.png    |  Bin 0 -> 3325 bytes
 .../src/main/js/public/images/ignite-puzzle.png |  Bin 0 -> 71974 bytes
 .../src/main/js/public/images/java.png          |  Bin 0 -> 170 bytes
 .../src/main/js/public/images/pb-ignite.png     |  Bin 0 -> 3493 bytes
 .../src/main/js/public/images/pb-ignite@2x.png  |  Bin 0 -> 8558 bytes
 .../src/main/js/public/images/query-chart.png   |  Bin 0 -> 16637 bytes
 .../main/js/public/images/query-metadata.png    |  Bin 0 -> 32298 bytes
 .../src/main/js/public/images/query-table.png   |  Bin 0 -> 29189 bytes
 .../src/main/js/public/images/summary.png       |  Bin 0 -> 31997 bytes
 .../src/main/js/public/images/xml.png           |  Bin 0 -> 232 bytes
 .../public/stylesheets/_bootstrap-custom.scss   |   65 +
 .../stylesheets/_bootstrap-variables.scss       |  891 +++++
 .../stylesheets/_font-awesome-custom.scss       |   31 +
 .../src/main/js/public/stylesheets/style.scss   | 2156 +++++++++++
 .../main/js/public/stylesheets/variables.scss   |   28 +
 modules/web-console/src/main/js/serve.js        |  116 +
 modules/web-console/src/main/js/serve/agent.js  |  713 ++++
 .../src/main/js/serve/agent_dists/README.txt    |    7 +
 modules/web-console/src/main/js/serve/app.js    |   42 +
 .../web-console/src/main/js/serve/browser.js    |  378 ++
 .../main/js/serve/config/settings.json.sample   |   26 +
 .../web-console/src/main/js/serve/configure.js  |   84 +
 .../web-console/src/main/js/serve/keys/test.crt |   13 +
 .../web-console/src/main/js/serve/keys/test.key |   18 +
 modules/web-console/src/main/js/serve/mail.js   |   75 +
 modules/web-console/src/main/js/serve/mongo.js  |  676 ++++
 .../src/main/js/serve/routes/admin.js           |  126 +
 .../src/main/js/serve/routes/agent.js           |   81 +
 .../src/main/js/serve/routes/caches.js          |  132 +
 .../src/main/js/serve/routes/clusters.js        |  146 +
 .../src/main/js/serve/routes/demo.js            |  135 +
 .../src/main/js/serve/routes/demo/caches.json   |   87 +
 .../src/main/js/serve/routes/demo/clusters.json |   50 +
 .../src/main/js/serve/routes/demo/domains.json  |  307 ++
 .../src/main/js/serve/routes/demo/igfss.json    |   10 +
 .../src/main/js/serve/routes/domains.js         |  195 +
 .../src/main/js/serve/routes/igfs.js            |  122 +
 .../src/main/js/serve/routes/notebooks.js       |  121 +
 .../src/main/js/serve/routes/profile.js         |  102 +
 .../src/main/js/serve/routes/public.js          |  235 ++
 .../src/main/js/serve/routes/routes.js          |  103 +
 .../web-console/src/main/js/serve/settings.js   |   84 +
 modules/web-console/src/main/js/views/base.jade |   22 +
 .../src/main/js/views/configuration/caches.jade |   52 +
 .../main/js/views/configuration/clusters.jade   |   64 +
 .../js/views/configuration/domains-import.jade  |  211 ++
 .../main/js/views/configuration/domains.jade    |   66 +
 .../src/main/js/views/configuration/igfs.jade   |   51 +
 .../main/js/views/configuration/sidebar.jade    |   29 +
 .../summary-project-structure.jade              |   27 +
 .../js/views/configuration/summary-tabs.jade    |   25 +
 .../main/js/views/configuration/summary.jade    |  152 +
 .../src/main/js/views/includes/footer.jade      |   23 +
 .../src/main/js/views/includes/header.jade      |   48 +
 .../web-console/src/main/js/views/index.jade    |   66 +
 .../web-console/src/main/js/views/reset.jade    |   48 +
 .../src/main/js/views/settings/admin.jade       |   76 +
 .../src/main/js/views/settings/profile.jade     |   76 +
 .../web-console/src/main/js/views/signin.jade   |  163 +
 .../src/main/js/views/sql/cache-metadata.jade   |   40 +
 .../src/main/js/views/sql/chart-settings.jade   |   40 +
 .../src/main/js/views/sql/notebook-new.jade     |   31 +
 .../src/main/js/views/sql/paragraph-rate.jade   |   31 +
 .../web-console/src/main/js/views/sql/sql.jade  |  201 ++
 .../main/js/views/templates/agent-download.jade |   48 +
 .../src/main/js/views/templates/alert.jade      |   21 +
 .../main/js/views/templates/batch-confirm.jade  |   32 +
 .../src/main/js/views/templates/clone.jade      |   31 +
 .../src/main/js/views/templates/confirm.jade    |   31 +
 .../src/main/js/views/templates/demo-info.jade  |   45 +
 .../src/main/js/views/templates/dropdown.jade   |   21 +
 .../js/views/templates/getting-started.jade     |   32 +
 .../src/main/js/views/templates/message.jade    |   26 +
 .../src/main/js/views/templates/pagination.jade |   32 +
 .../src/main/js/views/templates/select.jade     |   26 +
 .../js/views/templates/validation-error.jade    |   25 +
 modules/web-console/src/test/js/routes/agent.js |   94 +
 modules/web/ignite-appserver-test/pom.xml       |   75 +
 .../webapp/META-INF/config/default-config.xml   |   37 +
 .../src/main/webapp/WEB-INF/web.xml             |   52 +
 .../src/main/webapp/index.jsp                   |   36 +
 modules/web/ignite-websphere-test/pom.xml       |   69 +
 .../apache/ignite/webtest/TestJtaTxServlet.java |  106 +
 .../webapp/META-INF/config/default-config.xml   |   70 +
 .../src/main/webapp/WEB-INF/web.xml             |   62 +
 .../src/main/webapp/index.jsp                   |   36 +
 modules/web/pom.xml                             |    2 +-
 .../ignite/cache/websession/WebSession.java     |  105 +-
 .../cache/websession/WebSessionFilter.java      |  746 +++-
 .../cache/websession/WebSessionListener.java    |  133 +-
 .../ignite/cache/websession/WebSessionV2.java   |  403 +++
 .../IgniteWebSessionSelfTestSuite.java          |   45 +
 .../internal/websession/WebSessionSelfTest.java |  940 ++++-
 .../webapp2/META-INF/ignite-webapp-config.xml   |  279 ++
 modules/web/src/test/webapp2/WEB-INF/web.xml    |   45 +
 .../config/benchmark-cache-load-win.properties  |   60 +
 .../config/benchmark-cache-load.properties      |   92 +
 .../yardstick/config/benchmark-full.properties  |  116 +
 .../config/ignite-base-load-config.xml          |  255 ++
 .../config/ignite-cache-load-config.xml         |   71 +
 modules/yardstick/config/queries.sql            |    2 +
 modules/yardstick/pom.xml                       |    2 +-
 .../yardstick/IgniteBenchmarkArguments.java     |   39 +-
 .../cache/CacheEntryEventAsyncProbe.java        |   61 +
 .../yardstick/cache/CacheEntryEventProbe.java   |   33 +-
 .../cache/IgniteCacheAbstractBenchmark.java     |    5 +
 .../IgniteCacheRandomOperationBenchmark.java    | 1160 ++++++
 .../yardstick/cache/load/model/ModelUtil.java   |  181 +
 .../cache/load/model/key/Identifier.java        |  113 +
 .../yardstick/cache/load/model/key/Mark.java    |  115 +
 .../yardstick/cache/load/model/value/Car.java   |  126 +
 .../yardstick/cache/load/model/value/Color.java |   50 +
 .../yardstick/cache/load/model/value/Truck.java |   69 +
 .../ignite/yardstick/cache/model/Account.java   |    6 +
 .../ignite/yardstick/cache/model/Person1.java   |    2 +-
 .../ignite/yardstick/cache/model/Person2.java   |    2 +-
 .../ignite/yardstick/cache/model/SampleKey.java |    2 +-
 .../yardstick/cache/model/SampleValue.java      |    2 +-
 modules/yarn/pom.xml                            |    2 +-
 modules/zookeeper/pom.xml                       |    5 +-
 .../zk/TcpDiscoveryZookeeperIpFinder.java       |   84 +-
 .../tcp/ipfinder/zk/ZookeeperIpFinderTest.java  |   16 +-
 parent/pom.xml                                  |   27 +-
 pom.xml                                         |   50 +-
 2377 files changed, 223596 insertions(+), 44888 deletions(-)
----------------------------------------------------------------------



[45/50] [abbrv] ignite git commit: Merge branch 'gridgain-7.6.1' of https://github.com/gridgain/apache-ignite

Posted by sb...@apache.org.
Merge branch 'gridgain-7.6.1' of https://github.com/gridgain/apache-ignite


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/6e5061d1
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/6e5061d1
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/6e5061d1

Branch: refs/heads/ignite-1232
Commit: 6e5061d169ad80bfad6d26d3f0337b0d634afde8
Parents: 8f28382 541e17d
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Mon Jun 27 10:20:03 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Jun 27 10:20:03 2016 +0700

----------------------------------------------------------------------
 .../configuration/HadoopConfiguration.java      |   35 +
 .../org/apache/ignite/internal/IgnitionEx.java  |    3 +
 .../processors/cache/GridCacheAdapter.java      |   16 +-
 .../distributed/near/GridNearGetFuture.java     |    8 +-
 .../transactions/IgniteTxLocalAdapter.java      |   12 +-
 .../cache/transactions/IgniteTxManager.java     |   20 +-
 .../processors/hadoop/HadoopJobInfo.java        |    3 +-
 .../processors/igfs/IgfsDataManager.java        |   14 +-
 .../processors/igfs/IgfsOutputStreamImpl.java   |   10 +-
 .../internal/processors/igfs/IgfsProcessor.java |   24 -
 .../ignite/internal/util/IgniteUtils.java       |   45 +-
 .../visor/compute/VisorGatewayTask.java         |    3 +-
 .../ignite/spi/discovery/tcp/ServerImpl.java    |    7 +-
 .../spi/discovery/tcp/TcpDiscoveryImpl.java     |    3 +-
 .../IgniteCacheTxIteratorSelfTest.java          |  241 ++
 .../cluster/GridAddressResolverSelfTest.java    |   97 +
 .../igfs/IgfsDataManagerSelfTest.java           |    6 +-
 .../igfs/IgfsProcessorValidationSelfTest.java   |   26 -
 .../vm/TcpDiscoveryVmIpFinderSelfTest.java      |   75 +
 .../testsuites/IgniteCacheTestSuite5.java       |    2 +
 .../testsuites/IgniteKernalSelfTestSuite.java   |    2 +
 .../processors/hadoop/HadoopClassLoader.java    |   26 +-
 .../processors/hadoop/HadoopDefaultJobInfo.java |    8 +-
 .../hadoop/jobtracker/HadoopJobTracker.java     |   14 +-
 .../child/HadoopChildProcessRunner.java         |    2 +-
 .../processors/hadoop/v2/HadoopV2Job.java       |   14 +-
 .../hadoop/HadoopClassLoaderTest.java           |    2 +-
 .../processors/hadoop/HadoopSnappyTest.java     |    2 +-
 .../processors/hadoop/HadoopTasksV1Test.java    |    2 +-
 .../processors/hadoop/HadoopTasksV2Test.java    |    2 +-
 .../processors/hadoop/HadoopV2JobSelfTest.java  |    2 +-
 .../collections/HadoopAbstractMapTest.java      |    6 +-
 .../include/ignite/binary/binary_containers.h   |  191 +-
 .../include/ignite/binary/binary_raw_reader.h   |   25 +-
 .../include/ignite/binary/binary_raw_writer.h   |   13 +
 .../include/ignite/binary/binary_reader.h       |   13 +
 .../include/ignite/binary/binary_writer.h       |   13 +
 .../platforms/cpp/common/include/ignite/date.h  |    2 +-
 .../cpp/common/include/ignite/ignite_error.h    |   19 +-
 .../cpp/common/include/ignite/timestamp.h       |    2 +-
 .../platforms/cpp/common/src/ignite_error.cpp   |   12 +-
 .../cpp/core/include/ignite/cache/cache.h       |  186 +-
 .../cpp/core/include/ignite/cache/cache_entry.h |   14 +-
 .../include/ignite/cache/query/query_argument.h |   33 +-
 .../include/ignite/cache/query/query_cursor.h   |   17 +-
 .../ignite/cache/query/query_fields_cursor.h    |   11 +-
 .../ignite/cache/query/query_fields_row.h       |   22 +-
 .../include/ignite/cache/query/query_scan.h     |   10 +-
 .../core/include/ignite/cache/query/query_sql.h |   15 +-
 .../ignite/cache/query/query_sql_fields.h       |   15 +-
 .../platforms/cpp/core/include/ignite/ignite.h  |   21 +-
 .../core/include/ignite/ignite_configuration.h  |    4 +-
 .../cpp/core/include/ignite/ignition.h          |    2 +-
 .../include/ignite/transactions/transaction.h   |   68 +-
 .../ignite/transactions/transaction_consts.h    |   84 +-
 .../ignite/transactions/transaction_metrics.h   |   13 +-
 .../include/ignite/transactions/transactions.h  |   36 +-
 modules/platforms/cpp/core/namespaces.dox       |    2 +-
 modules/platforms/cpp/cpp.dxg                   |    4 +-
 modules/schema-import/README.txt                |   12 +-
 modules/web-agent/README.txt                    |   25 +-
 .../web-agent/assembly/release-web-agent.xml    |    2 -
 modules/web-agent/bin/ignite-web-agent.bat      |    2 +-
 modules/web-agent/bin/ignite-web-agent.sh       |    2 +-
 modules/web-agent/pom.xml                       |   22 +-
 .../console/agent/AgentConfiguration.java       |   53 +-
 .../ignite/console/agent/AgentLauncher.java     |   21 +-
 .../ignite/console/demo/AgentClusterDemo.java   |   82 +-
 modules/web-console/README.txt                  |    4 +-
 modules/web-console/src/main/js/.eslintrc       |    7 +-
 .../src/main/js/app/data/getting-started.json   |    2 +-
 .../src/main/js/app/data/pom-dependencies.json  |   20 +
 .../directives/ui-ace-docker/ui-ace-docker.jade |    4 +-
 .../ui-ace-java/ui-ace-java.directive.js        |    4 +-
 .../directives/ui-ace-pojos/ui-ace-pojos.jade   |    4 +-
 .../ui-ace-xml/ui-ace-xml.directive.js          |    4 +-
 .../src/main/js/app/helpers/jade/mixins.jade    |   17 +-
 modules/web-console/src/main/js/app/index.js    |   18 +-
 .../src/main/js/app/modules/Demo/Demo.module.js |   14 +-
 .../QueryNotebooks/QueryNotebooks.provider.js   |  115 -
 .../main/js/app/modules/agent/agent.module.js   |  323 +++
 .../configuration/generator/Pom.service.js      |   46 +-
 .../form/field/input/datalist.directive.js      |    6 +-
 .../modules/form/field/input/text.directive.js  |    9 +-
 .../js/app/modules/form/field/input/text.jade   |    2 +-
 .../app/modules/form/group/group.directive.js   |    6 +-
 .../form/validator/java-keywords.directive.js   |    9 +-
 .../src/main/js/app/modules/loading/loading.css |    2 +-
 .../query-notebooks/query-notebooks.module.js   |  115 +
 .../app/modules/states/configuration.state.js   |   32 +-
 .../states/configuration/caches/general.jade    |    2 +-
 .../states/configuration/caches/store.jade      |   37 +-
 .../clusters/attributes.directive.js            |   27 +
 .../configuration/clusters/attributes.jade      |   58 +
 .../states/configuration/clusters/binary.jade   |   12 +-
 .../clusters/collision.directive.js             |   27 +
 .../configuration/clusters/collision.jade       |   60 +
 .../clusters/collision/custom.directive.js      |   27 +
 .../clusters/collision/custom.jade              |   24 +
 .../clusters/collision/fifo-queue.directive.js  |   27 +
 .../clusters/collision/fifo-queue.jade          |   28 +
 .../collision/job-stealing.directive.js         |   27 +
 .../clusters/collision/job-stealing.jade        |   64 +
 .../collision/priority-queue.directive.js       |   27 +
 .../clusters/collision/priority-queue.jade      |   43 +
 .../configuration/clusters/communication.jade   |   30 +-
 .../configuration/clusters/deployment.jade      |   31 +-
 .../configuration/clusters/discovery.jade       |    4 +-
 .../clusters/failover.directive.js              |   27 +
 .../states/configuration/clusters/failover.jade |   82 +
 .../states/configuration/clusters/general.jade  |   20 +-
 .../clusters/general/discovery/cloud.jade       |    6 +-
 .../clusters/general/discovery/google.jade      |   11 +-
 .../clusters/general/discovery/s3.jade          |    4 +-
 .../clusters/general/discovery/zookeeper.jade   |   21 +-
 .../bounded-exponential-backoff.jade            |    6 +-
 .../discovery/zookeeper/retrypolicy/custom.jade |    6 +-
 .../retrypolicy/exponential-backoff.jade        |    6 +-
 .../zookeeper/retrypolicy/forever.jade          |    2 +-
 .../zookeeper/retrypolicy/n-times.jade          |    2 +-
 .../zookeeper/retrypolicy/one-time.jade         |    2 +-
 .../zookeeper/retrypolicy/until-elapsed.jade    |    4 +-
 .../states/configuration/clusters/igfs.jade     |    4 +-
 .../configuration/clusters/logger.directive.js  |   27 +
 .../states/configuration/clusters/logger.jade   |   65 +
 .../clusters/logger/custom.directive.js         |   27 +
 .../configuration/clusters/logger/custom.jade   |   24 +
 .../clusters/logger/log4j.directive.js          |   27 +
 .../configuration/clusters/logger/log4j.jade    |   49 +
 .../clusters/logger/log4j2.directive.js         |   27 +
 .../configuration/clusters/logger/log4j2.jade   |   38 +
 .../states/configuration/domains/query.jade     |    4 +-
 .../states/configuration/domains/store.jade     |    2 +-
 .../modules/states/configuration/igfs/misc.jade |    2 +-
 .../main/js/app/modules/user/Auth.service.js    |   19 +-
 .../js/app/services/AgentMonitor.service.js     |  337 ---
 .../src/main/js/app/services/cleanup.service.js |    4 +-
 .../src/main/js/build/system.config.js          |   55 +-
 .../src/main/js/controllers/admin-controller.js |   14 +-
 .../main/js/controllers/caches-controller.js    |  336 ++-
 .../main/js/controllers/clusters-controller.js  |  537 +++--
 .../src/main/js/controllers/common-module.js    | 1052 +++++----
 .../main/js/controllers/domains-controller.js   |  847 ++++---
 .../src/main/js/controllers/igfs-controller.js  |  212 +-
 .../main/js/controllers/profile-controller.js   |   60 +-
 .../src/main/js/controllers/sql-controller.js   | 2173 +++++++++---------
 .../src/main/js/generator/generator-common.js   |  151 +-
 .../src/main/js/generator/generator-java.js     |  998 ++++----
 .../src/main/js/generator/generator-optional.js |    2 +-
 .../main/js/generator/generator-properties.js   |   25 +-
 .../src/main/js/generator/generator-readme.js   |    6 +-
 .../src/main/js/generator/generator-xml.js      |  430 +++-
 .../main/js/gulpfile.babel.js/tasks/eslint.js   |    3 +
 .../src/main/js/public/images/cluster.png       |  Bin 29670 -> 29376 bytes
 .../src/main/js/public/images/query-table.png   |  Bin 42253 -> 29189 bytes
 .../src/main/js/public/stylesheets/style.scss   |   28 +
 modules/web-console/src/main/js/serve/agent.js  |  222 +-
 .../web-console/src/main/js/serve/browser.js    |  120 +-
 .../web-console/src/main/js/serve/configure.js  |    1 +
 modules/web-console/src/main/js/serve/mongo.js  |   58 +-
 .../src/main/js/serve/routes/agent.js           |    3 +-
 .../src/main/js/serve/routes/caches.js          |    4 +-
 .../src/main/js/serve/routes/clusters.js        |    8 +-
 .../src/main/js/serve/routes/igfs.js            |    2 +-
 .../src/main/js/serve/routes/profile.js         |   11 +-
 .../src/main/js/serve/routes/public.js          |   35 +-
 .../main/js/views/configuration/clusters.jade   |    4 +
 .../js/views/configuration/domains-import.jade  |  325 +--
 .../src/main/js/views/settings/profile.jade     |   14 +-
 .../web-console/src/main/js/views/signin.jade   |   26 +-
 .../src/main/js/views/sql/cache-metadata.jade   |    2 +-
 .../web-console/src/main/js/views/sql/sql.jade  |  205 +-
 172 files changed, 7375 insertions(+), 4567 deletions(-)
----------------------------------------------------------------------



[47/50] [abbrv] ignite git commit: IGNITE-3140: CPP: Added tests for string format validity.

Posted by sb...@apache.org.
IGNITE-3140: CPP: Added tests for string format validity.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/cbb77c9a
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/cbb77c9a
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/cbb77c9a

Branch: refs/heads/ignite-1232
Commit: cbb77c9ad860bc8675077b09410e6e344f36bbb4
Parents: 34fc31e
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Tue Jun 28 12:36:56 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Tue Jun 28 12:36:56 2016 +0300

----------------------------------------------------------------------
 modules/platforms/cpp/core-test/Makefile.am     |   1 +
 .../cpp/core-test/project/vs/core-test.vcxproj  |   1 +
 .../project/vs/core-test.vcxproj.filters        |   3 +
 .../cpp/core-test/src/interop_test.cpp          | 148 +++++++++++++++++++
 4 files changed, 153 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/cbb77c9a/modules/platforms/cpp/core-test/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/Makefile.am b/modules/platforms/cpp/core-test/Makefile.am
index d1f4ca5..759be13 100644
--- a/modules/platforms/cpp/core-test/Makefile.am
+++ b/modules/platforms/cpp/core-test/Makefile.am
@@ -52,6 +52,7 @@ ignite_tests_SOURCES = \
     src/concurrent_test.cpp \
     src/ignition_test.cpp \
     src/interop_memory_test.cpp \
+    src/interop_test.cpp \
     src/handle_registry_test.cpp \
 	src/ignite_error_test.cpp \
     src/binary_test_defs.cpp \

http://git-wip-us.apache.org/repos/asf/ignite/blob/cbb77c9a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
index edf87ba..a7ffad8 100644
--- a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
+++ b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
@@ -45,6 +45,7 @@
     <ClCompile Include="..\..\src\binary_test_defs.cpp" />
     <ClCompile Include="..\..\src\cache_query_test.cpp" />
     <ClCompile Include="..\..\src\interop_memory_test.cpp" />
+    <ClCompile Include="..\..\src\interop_test.cpp" />
     <ClCompile Include="..\..\src\teamcity_boost.cpp" />
     <ClCompile Include="..\..\src\teamcity_messages.cpp" />
     <ClCompile Include="..\..\src\transactions_test.cpp" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/cbb77c9a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
index 2259f4c..39e2aee 100644
--- a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
+++ b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
@@ -43,6 +43,9 @@
     <ClCompile Include="..\..\src\transactions_test.cpp">
       <Filter>Code</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\interop_test.cpp">
+      <Filter>Code</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\teamcity_messages.h">

http://git-wip-us.apache.org/repos/asf/ignite/blob/cbb77c9a/modules/platforms/cpp/core-test/src/interop_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/interop_test.cpp b/modules/platforms/cpp/core-test/src/interop_test.cpp
new file mode 100644
index 0000000..4b079d9
--- /dev/null
+++ b/modules/platforms/cpp/core-test/src/interop_test.cpp
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+#ifndef _MSC_VER
+#   define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include "ignite/ignition.h"
+
+using namespace ignite;
+using namespace cache;
+using namespace boost::unit_test;
+
+void InitConfig(IgniteConfiguration& cfg)
+{
+    cfg.jvmOpts.push_back("-Xdebug");
+    cfg.jvmOpts.push_back("-Xnoagent");
+    cfg.jvmOpts.push_back("-Djava.compiler=NONE");
+    cfg.jvmOpts.push_back("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005");
+    cfg.jvmOpts.push_back("-XX:+HeapDumpOnOutOfMemoryError");
+
+#ifdef IGNITE_TESTS_32
+    cfg.jvmInitMem = 256;
+    cfg.jvmMaxMem = 768;
+#else
+    cfg.jvmInitMem = 1024;
+    cfg.jvmMaxMem = 4096;
+#endif
+
+    char* cfgPath = getenv("IGNITE_NATIVE_TEST_CPP_CONFIG_PATH");
+
+    cfg.springCfgPath = std::string(cfgPath).append("/").append("cache-test.xml");
+}
+
+BOOST_AUTO_TEST_SUITE(InteropTestSuite)
+
+#ifdef ENABLE_STRING_SERIALIZATION_VER_2_TESTS
+
+BOOST_AUTO_TEST_CASE(StringUtfInvalidSequence)
+{
+    IgniteConfiguration cfg;
+
+    InitConfig(cfg);
+
+    Ignite ignite = Ignition::Start(cfg);
+
+    Cache<std::string, std::string> cache = ignite.CreateCache<std::string, std::string>("Test");
+
+    std::string initialValue;
+
+    initialValue.push_back(static_cast<unsigned char>(0xD8));
+    initialValue.push_back(static_cast<unsigned char>(0x00));
+
+    try
+    {
+        cache.Put("key", initialValue);
+
+        std::string cachedValue = cache.Get("key");
+
+        BOOST_ERROR("Exception is expected due to invalid format.");
+    }
+    catch (const IgniteError&)
+    {
+        // Expected in this mode.
+    }
+
+    Ignition::StopAll(false);
+}
+
+BOOST_AUTO_TEST_CASE(StringUtfInvalidCodePoint)
+{
+    IgniteConfiguration cfg;
+
+    InitConfig(cfg);
+
+    putenv("IGNITE_BINARY_MARSHALLER_USE_STRING_SERIALIZATION_VER_2=true");
+
+    Ignite ignite = Ignition::Start(cfg);
+
+    Cache<std::string, std::string> cache = ignite.CreateCache<std::string, std::string>("Test");
+
+    std::string initialValue;
+
+    //    1110xxxx 10xxxxxx 10xxxxxx |
+    // <=          11011000 00000000 | U+D8
+    //  = 11101101 10100000 10000000 | ED A0 80
+    initialValue.push_back(static_cast<unsigned char>(0xED));
+    initialValue.push_back(static_cast<unsigned char>(0xA0));
+    initialValue.push_back(static_cast<unsigned char>(0x80));
+
+    cache.Put("key", initialValue);
+    std::string cachedValue = cache.Get("key");
+
+    // This is a valid case. Invalid code points are supported in this mode.
+    BOOST_CHECK_EQUAL(initialValue, cachedValue);
+
+    Ignition::StopAll(false);
+}
+
+#endif
+
+BOOST_AUTO_TEST_CASE(StringUtfValid4ByteCodePoint)
+{
+    IgniteConfiguration cfg;
+
+    InitConfig(cfg);
+
+    Ignite ignite = Ignition::Start(cfg);
+
+    Cache<std::string, std::string> cache = ignite.CreateCache<std::string, std::string>("Test");
+
+    std::string initialValue;
+
+    //    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
+    // <=             00001 00000001 01001011 | U+1014B
+    // <=      000   010000   000101   001011 | U+1014B
+    //  = 11110000 10010000 10000101 10001011 | F0 90 85 8B
+    initialValue.push_back(static_cast<unsigned char>(0xF0));
+    initialValue.push_back(static_cast<unsigned char>(0x90));
+    initialValue.push_back(static_cast<unsigned char>(0x85));
+    initialValue.push_back(static_cast<unsigned char>(0x8B));
+
+    cache.Put("key", initialValue);
+    std::string cachedValue = cache.Get("key");
+
+    // This is a valid UTF-8 code point. Should be supported in default mode.
+    BOOST_CHECK_EQUAL(initialValue, cachedValue);
+
+    Ignition::StopAll(false);
+}
+
+BOOST_AUTO_TEST_SUITE_END()


[46/50] [abbrv] ignite git commit: Merge remote-tracking branch 'origin/master'

Posted by sb...@apache.org.
Merge remote-tracking branch 'origin/master'


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/34fc31e8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/34fc31e8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/34fc31e8

Branch: refs/heads/ignite-1232
Commit: 34fc31e87b3e5f5c31f68421d7200c8848bb6e20
Parents: 6e5061d 8ec6db5
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Mon Jun 27 10:22:16 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Jun 27 10:22:16 2016 +0700

----------------------------------------------------------------------
 .../GridAffinityFunctionContextImpl.java        |   9 +
 .../platform/PlatformProcessorImpl.java         |  35 +--
 .../affinity/PlatformAffinityFunction.java      | 242 +++++++++++++++
 .../callback/PlatformCallbackGateway.java       |  90 +++++-
 .../callback/PlatformCallbackUtils.java         |  46 +++
 .../dotnet/PlatformDotNetCacheStore.java        |  27 +-
 .../utils/PlatformConfigurationUtils.java       |  13 +-
 .../apache/ignite/resources/SpringResource.java |  15 +-
 .../platforms/cpp/jni/include/ignite/jni/java.h |  19 +-
 modules/platforms/cpp/jni/src/java.cpp          |  35 ++-
 .../Apache.Ignite.Core.Tests.csproj             |   5 +-
 .../Binary/BinarySelfTest.cs                    | 138 +++++---
 .../Cache/Affinity/AffinityFieldTest.cs         | 199 ++++++++++++
 .../Cache/Affinity/AffinityFunctionTest.cs      | 282 +++++++++++++++++
 .../Cache/Affinity/AffinityTest.cs              | 138 ++++++++
 .../Cache/CacheAffinityFieldTest.cs             | 199 ------------
 .../Cache/CacheAffinityTest.cs                  | 139 ---------
 .../Cache/CacheConfigurationTest.cs             |   6 +-
 .../Cache/Store/CacheStoreTest.cs               |  11 +-
 .../native-client-test-cache-affinity.xml       |   2 +-
 .../IgniteConfigurationSerializerTest.cs        |  14 +-
 .../Apache.Ignite.Core.Tests/LifecycleTest.cs   |   9 +
 .../Apache.Ignite.Core.Tests/ReconnectTest.cs   |   9 +
 .../Apache.Ignite.Core.Tests/TestRunner.cs      |   6 +-
 .../Apache.Ignite.Core.Tests/TestUtils.cs       |   4 +-
 .../Apache.Ignite.Core.csproj                   |   3 +
 .../Cache/Affinity/AffinityFunctionBase.cs      | 102 +++++-
 .../Cache/Affinity/AffinityFunctionContext.cs   | 116 +++++++
 .../Cache/Affinity/AffinityTopologyVersion.cs   | 138 ++++++++
 .../Cache/Affinity/IAffinityFunction.cs         |  55 +++-
 .../Cache/Configuration/CacheConfiguration.cs   |   9 +-
 .../Apache.Ignite.Core/Events/EventBase.cs      |   2 +-
 .../Apache.Ignite.Core/Events/EventReader.cs    |   8 +-
 .../dotnet/Apache.Ignite.Core/IIgnite.cs        |  25 ++
 .../IgniteConfigurationSection.xsd              |   4 +-
 .../dotnet/Apache.Ignite.Core/Ignition.cs       |  25 +-
 .../Impl/Binary/BinaryReflectiveActions.cs      |  10 +-
 .../dotnet/Apache.Ignite.Core/Impl/Ignite.cs    |  38 ++-
 .../Apache.Ignite.Core/Impl/IgniteProxy.cs      |  37 ++-
 .../Impl/LifecycleBeanHolder.cs                 |   2 +-
 .../Impl/Unmanaged/UnmanagedCallbackHandlers.cs |   6 +
 .../Impl/Unmanaged/UnmanagedCallbacks.cs        | 120 ++++++-
 .../Lifecycle/ClientReconnectEventArgs.cs       |  47 +++
 .../dotnet/Apache.Ignite.sln.DotSettings        |   7 +-
 .../GridResourceSpringBeanInjector.java         |  39 ++-
 .../GridSpringResourceInjectionSelfTest.java    | 311 ++++++++++++++++---
 .../spring-resource-with-duplicate-beans.xml    |  30 ++
 .../processors/resource/spring-resource.xml     |   2 +-
 48 files changed, 2299 insertions(+), 529 deletions(-)
----------------------------------------------------------------------



[07/50] [abbrv] ignite git commit: Merge branch 'gridgain-7.6.1' of https://github.com/gridgain/apache-ignite

Posted by sb...@apache.org.
Merge branch 'gridgain-7.6.1' of https://github.com/gridgain/apache-ignite


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/848b027d
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/848b027d
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/848b027d

Branch: refs/heads/ignite-1232
Commit: 848b027db6ef4c45ac0602651f050d2b9f69adf9
Parents: f238b76 f177d43
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Tue Jun 21 14:31:20 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Tue Jun 21 14:31:20 2016 +0700

----------------------------------------------------------------------
 .../client/ClientDefaultCacheSelfTest.java      | 119 ++-
 .../ignite/internal/client/ClientHttpTask.java  |  33 +-
 .../ignite/internal/client/ClientTcpTask.java   |  10 +-
 .../integration/ClientAbstractSelfTest.java     |  92 +-
 .../JettyRestProcessorAbstractSelfTest.java     | 985 ++++++++-----------
 .../internal/processors/rest/SimplePerson.java  |  74 ++
 modules/core/pom.xml                            |  15 +-
 .../apache/ignite/internal/LessNamingBean.java  |  28 +
 .../cache/query/GridCacheSqlIndexMetadata.java  |   3 +-
 .../cache/query/GridCacheSqlMetadata.java       |   3 +-
 .../internal/util/IgniteExceptionRegistry.java  |   5 +-
 .../ignite/internal/visor/cache/VisorCache.java |   4 +-
 .../cache/VisorCacheAffinityConfiguration.java  |   5 +-
 .../cache/VisorCacheAggregatedMetrics.java      |   3 +-
 .../visor/cache/VisorCacheConfiguration.java    |   3 +-
 .../cache/VisorCacheDefaultConfiguration.java   |   5 +-
 .../cache/VisorCacheEvictionConfiguration.java  |   5 +-
 .../internal/visor/cache/VisorCacheMetrics.java |   3 +-
 .../cache/VisorCacheNearConfiguration.java      |   5 +-
 .../visor/cache/VisorCachePartition.java        |   3 +-
 .../visor/cache/VisorCachePartitions.java       |   3 +-
 .../cache/VisorCacheQueryConfiguration.java     |   3 +-
 .../visor/cache/VisorCacheQueryMetrics.java     |   5 +-
 .../cache/VisorCacheRebalanceConfiguration.java |   5 +-
 .../cache/VisorCacheStoreConfiguration.java     |   3 +-
 .../cache/VisorCacheTypeFieldMetadata.java      |   3 +-
 .../visor/cache/VisorCacheTypeMetadata.java     |   3 +-
 .../internal/visor/cache/VisorCacheV4.java      | 124 +++
 .../internal/visor/debug/VisorThreadInfo.java   |   5 +-
 .../visor/debug/VisorThreadLockInfo.java        |   5 +-
 .../internal/visor/event/VisorGridEvent.java    |   5 +-
 .../internal/visor/file/VisorFileBlock.java     |   5 +-
 .../ignite/internal/visor/igfs/VisorIgfs.java   |   5 +-
 .../internal/visor/igfs/VisorIgfsEndpoint.java  |   5 +-
 .../internal/visor/igfs/VisorIgfsMetrics.java   |   5 +-
 .../visor/igfs/VisorIgfsProfilerEntry.java      |   5 +-
 .../VisorIgfsProfilerUniformityCounters.java    |   5 +-
 .../visor/log/VisorLogSearchResult.java         |   5 +-
 .../visor/node/VisorAtomicConfiguration.java    |   5 +-
 .../visor/node/VisorBasicConfiguration.java     |   5 +-
 .../node/VisorExecutorServiceConfiguration.java |   5 +-
 .../visor/node/VisorGridConfiguration.java      |   5 +-
 .../visor/node/VisorIgfsConfiguration.java      |   3 +-
 .../visor/node/VisorLifecycleConfiguration.java |   5 +-
 .../visor/node/VisorMetricsConfiguration.java   |   5 +-
 .../visor/node/VisorNodeDataCollectorJob.java   |  26 +-
 .../node/VisorNodeDataCollectorTaskResult.java  |   5 +-
 .../node/VisorPeerToPeerConfiguration.java      |   5 +-
 .../visor/node/VisorRestConfiguration.java      |   5 +-
 .../node/VisorSegmentationConfiguration.java    |   5 +-
 .../visor/node/VisorSpisConfiguration.java      |   5 +-
 .../node/VisorTransactionConfiguration.java     |   5 +-
 .../internal/visor/query/VisorQueryField.java   |   5 +-
 .../internal/visor/query/VisorQueryResult.java  |   5 +-
 .../plugin/security/SecurityPermissionSet.java  |   5 +-
 .../ignite/plugin/security/SecuritySubject.java |   5 +-
 modules/rest-http/pom.xml                       |  25 +-
 .../http/jetty/GridJettyJsonConfig.java         | 317 ------
 .../http/jetty/GridJettyObjectMapper.java       | 259 +++++
 .../http/jetty/GridJettyRestHandler.java        | 127 ++-
 parent/pom.xml                                  |   1 +
 61 files changed, 1277 insertions(+), 1163 deletions(-)
----------------------------------------------------------------------



[28/50] [abbrv] ignite git commit: IGNITE-3364 .NET: Fix BinaryReflectiveSerializer raw mode for DateTime members marked with QuerySqlField

Posted by sb...@apache.org.
IGNITE-3364 .NET: Fix BinaryReflectiveSerializer raw mode for DateTime members marked with QuerySqlField

This closes #830


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/6cfd991e
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/6cfd991e
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/6cfd991e

Branch: refs/heads/ignite-1232
Commit: 6cfd991ecc7c27d2cd7d01a492ba41280689c285
Parents: cb0deb1
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri Jun 24 17:01:39 2016 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Jun 24 17:01:39 2016 +0300

----------------------------------------------------------------------
 .../Binary/BinarySelfTest.cs                    | 138 +++++++++++++------
 .../Impl/Binary/BinaryReflectiveActions.cs      |  10 +-
 2 files changed, 106 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/6cfd991e/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
index 9cc64c1..b32b0a2 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
@@ -31,6 +31,7 @@ namespace Apache.Ignite.Core.Tests.Binary
     using System.Linq;
     using System.Reflection;
     using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Cache.Configuration;
     using Apache.Ignite.Core.Common;
     using Apache.Ignite.Core.Impl.Binary;
     using Apache.Ignite.Core.Impl.Binary.IO;
@@ -780,7 +781,12 @@ namespace Apache.Ignite.Core.Tests.Binary
                 }
             });
 
-            PrimitiveFieldType obj = new PrimitiveFieldType();
+            // Use utc date fields because reflective serializer writes [QuerySqlField] fields as timestamp
+            var obj = new PrimitiveFieldType
+            {
+                PDate = DateTime.UtcNow,
+                PnDate = DateTime.UtcNow
+            };
 
             CheckPrimitiveFields(marsh, obj);
         }
@@ -932,23 +938,6 @@ namespace Apache.Ignite.Core.Tests.Binary
 
         private void CheckPrimitiveFields(Marshaller marsh, PrimitiveFieldType obj)
         {
-            obj.PBool = true;
-            obj.PByte = 2;
-            obj.PSbyte = 3;
-            obj.PShort = 4;
-            obj.PUshort = 5;
-            obj.PInt = 6;
-            obj.PUint = 7;
-            obj.PLong = 8;
-            obj.PUlong = 9;
-            obj.PChar = 'a';
-            obj.PFloat = 10;
-            obj.PDouble = 11;
-            obj.PString = "abc";
-            obj.PGuid = Guid.NewGuid();
-            obj.PnGuid = Guid.NewGuid();
-            obj.IgniteGuid = new IgniteGuid(Guid.NewGuid(), 123);
-            
             CheckPrimitiveFieldsSerialization(marsh, obj);
         }
 
@@ -1845,36 +1834,81 @@ namespace Apache.Ignite.Core.Tests.Binary
         [Serializable]
         public class PrimitiveFieldType 
         {
+            public PrimitiveFieldType()
+            {
+                PBool = true;
+                PByte = 2;
+                PSbyte = 3;
+                PShort = 4;
+                PUshort = 5;
+                PInt = 6;
+                PUint = 7;
+                PLong = 8;
+                PUlong = 9;
+                PChar = 'a';
+                PFloat = 10;
+                PDouble = 11;
+                PString = "abc";
+                PGuid = Guid.NewGuid();
+                PnGuid = Guid.NewGuid();
+                PDate = DateTime.Now;
+                PnDate = DateTime.Now;
+                IgniteGuid = new IgniteGuid(Guid.NewGuid(), 123);
+            }
+
+            // Mark all fields with QuerySqlField because reflective serializer takes it into account
+            [QuerySqlField]
             public bool PBool { get; set; }
 
+            [QuerySqlField]
             public sbyte PSbyte { get; set; }
 
+            [QuerySqlField]
             public byte PByte { get; set; }
 
+            [QuerySqlField]
             public short PShort { get; set; }
 
+            [QuerySqlField]
             public ushort PUshort { get; set; }
 
+            [QuerySqlField]
             public char PChar { get; set; }
 
+            [QuerySqlField]
             public int PInt { get; set; }
 
+            [QuerySqlField]
             public uint PUint { get; set; }
 
+            [QuerySqlField]
             public long PLong { get; set; }
 
+            [QuerySqlField]
             public ulong PUlong { get; set; }
 
+            [QuerySqlField]
             public float PFloat { get; set; }
 
+            [QuerySqlField]
             public double PDouble { get; set; }
 
+            [QuerySqlField]
             public string PString { get; set; }
 
+            [QuerySqlField]
             public Guid PGuid { get; set; }
 
+            [QuerySqlField]
             public Guid? PnGuid { get; set; }
 
+            [QuerySqlField]
+            public DateTime PDate { get; set; }
+
+            [QuerySqlField]
+            public DateTime? PnDate { get; set; }
+
+            [QuerySqlField]
             public IgniteGuid IgniteGuid { get; set; }
 
             /** <inheritdoc /> */
@@ -1883,28 +1917,28 @@ namespace Apache.Ignite.Core.Tests.Binary
                 if (this == obj)
                     return true;
 
-                if (obj != null && obj is PrimitiveFieldType)
-                {
-                    PrimitiveFieldType that = (PrimitiveFieldType)obj;
-
-                    return PBool == that.PBool &&
-                        PByte == that.PByte &&
-                        PSbyte == that.PSbyte &&
-                        PShort == that.PShort &&
-                        PUshort == that.PUshort &&
-                        PInt == that.PInt &&
-                        PUint == that.PUint &&
-                        PLong == that.PLong &&
-                        PUlong == that.PUlong &&
-                        PChar == that.PChar &&
-                        PFloat == that.PFloat &&
-                        PDouble == that.PDouble &&
-                        (string.Equals(PString, that.PString)) &&
-                        PGuid.Equals(that.PGuid) &&
-                        IgniteGuid.Equals(that.IgniteGuid) &&
-                        (PnGuid == null && that.PnGuid == null || PnGuid != null && PnGuid.Equals(that.PnGuid));
-                }
-                return false;
+                var that = obj as PrimitiveFieldType;
+                if (that == null)
+                    return false;
+
+                return PBool == that.PBool &&
+                       PByte == that.PByte &&
+                       PSbyte == that.PSbyte &&
+                       PShort == that.PShort &&
+                       PUshort == that.PUshort &&
+                       PInt == that.PInt &&
+                       PUint == that.PUint &&
+                       PLong == that.PLong &&
+                       PUlong == that.PUlong &&
+                       PChar == that.PChar &&
+                       PFloat == that.PFloat &&
+                       PDouble == that.PDouble &&
+                       PString == that.PString &&
+                       PGuid == that.PGuid &&
+                       PnGuid == that.PnGuid &&
+                       IgniteGuid == that.IgniteGuid &&
+                       PDate == that.PDate &&
+                       PnDate == that.PnDate;
             }
 
             /** <inheritdoc /> */
@@ -1941,6 +1975,9 @@ namespace Apache.Ignite.Core.Tests.Binary
                 writer.WriteGuid("guid", PGuid);
                 writer.WriteGuid("nguid", PnGuid);
 
+                writer.WriteObject("date", PDate);
+                writer.WriteObject("ndate", PnDate);
+
                 writer.WriteObject("iguid", IgniteGuid);
             }
 
@@ -1970,6 +2007,9 @@ namespace Apache.Ignite.Core.Tests.Binary
                 PGuid = reader.ReadObject<Guid>("guid");
                 PnGuid = reader.ReadGuid("nguid");
 
+                PDate = reader.ReadObject<DateTime>("date");
+                PnDate = reader.ReadObject<DateTime?>("ndate");
+
                 IgniteGuid = reader.ReadObject<IgniteGuid>("iguid");
             }
         }
@@ -2003,6 +2043,9 @@ namespace Apache.Ignite.Core.Tests.Binary
                 rawWriter.WriteGuid(PGuid);
                 rawWriter.WriteGuid(PnGuid);
 
+                rawWriter.WriteObject(PDate);
+                rawWriter.WriteObject(PnDate);
+
                 rawWriter.WriteObject(IgniteGuid);
             }
 
@@ -2034,6 +2077,9 @@ namespace Apache.Ignite.Core.Tests.Binary
                 PGuid = rawReader.ReadGuid().Value;
                 PnGuid = rawReader.ReadGuid();
 
+                PDate = rawReader.ReadObject<DateTime>();
+                PnDate = rawReader.ReadObject<DateTime?>();
+
                 IgniteGuid = rawReader.ReadObject<IgniteGuid>();
             }
         }
@@ -2067,6 +2113,9 @@ namespace Apache.Ignite.Core.Tests.Binary
                 writer.WriteGuid("guid", obj0.PGuid);
                 writer.WriteGuid("nguid", obj0.PnGuid);
 
+                writer.WriteObject("date", obj0.PDate);
+                writer.WriteObject("ndate", obj0.PnDate);
+
                 writer.WriteObject("iguid", obj0.IgniteGuid);
             }
 
@@ -2098,6 +2147,9 @@ namespace Apache.Ignite.Core.Tests.Binary
                 obj0.PGuid = reader.ReadObject<Guid>("guid");
                 obj0.PnGuid = reader.ReadGuid("nguid");
 
+                obj0.PDate = reader.ReadObject<DateTime>("date");
+                obj0.PnDate = reader.ReadObject<DateTime?>("ndate");
+
                 obj0.IgniteGuid = reader.ReadObject<IgniteGuid>("iguid");
             }
         }
@@ -2133,6 +2185,9 @@ namespace Apache.Ignite.Core.Tests.Binary
                 rawWriter.WriteGuid(obj0.PGuid);
                 rawWriter.WriteGuid(obj0.PnGuid);
 
+                rawWriter.WriteObject(obj0.PDate);
+                rawWriter.WriteObject(obj0.PnDate);
+
                 rawWriter.WriteObject(obj0.IgniteGuid);
             }
 
@@ -2165,6 +2220,9 @@ namespace Apache.Ignite.Core.Tests.Binary
                 obj0.PGuid = rawReader.ReadGuid().Value;
                 obj0.PnGuid = rawReader.ReadGuid();
 
+                obj0.PDate = rawReader.ReadObject<DateTime>();
+                obj0.PnDate = rawReader.ReadObject<DateTime?>();
+
                 obj0.IgniteGuid = rawReader.ReadObject<IgniteGuid>();
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/6cfd991e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs
index 07cf08f..795f8ac 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReflectiveActions.cs
@@ -503,12 +503,18 @@ namespace Apache.Ignite.Core.Impl.Binary
                     ? GetRawReader(field, r => r.ReadCollection())
                     : GetReader(field, (f, r) => r.ReadCollection(f));
             }
-            else if (type == typeof (DateTime) && IsQueryField(field))
+            else if (type == typeof (DateTime) && IsQueryField(field) && !raw)
             {
+                // Special case for DateTime and query fields.
+                // If a field is marked with [QuerySqlField], write it as TimeStamp so that queries work.
+                // This is not needed in raw mode (queries do not work anyway).
+                // It may cause issues when field has attribute, but is used in a cache without queries, and user
+                // may expect non-UTC dates to work. However, such cases are rare, and there are workarounds.
+
                 writeAction = GetWriter<DateTime>(field, (f, w, o) => w.WriteTimestamp(f, o));
                 readAction = GetReader(field, (f, r) => r.ReadObject<DateTime>(f));
             }
-            else if (nullableType == typeof (DateTime) && IsQueryField(field))
+            else if (nullableType == typeof (DateTime) && IsQueryField(field) && !raw)
             {
                 writeAction = GetWriter<DateTime?>(field, (f, w, o) => w.WriteTimestamp(f, o));
                 readAction = GetReader(field, (f, r) => r.ReadTimestamp(f));


[27/50] [abbrv] ignite git commit: IGNITE-3340 .NET: Fix cache store release on DestroyCache

Posted by sb...@apache.org.
IGNITE-3340 .NET: Fix cache store release on DestroyCache


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/cb0deb11
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/cb0deb11
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/cb0deb11

Branch: refs/heads/ignite-1232
Commit: cb0deb11eed2cb1d574f23d8668cdf1309b66070
Parents: d59e5f5
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Thu Jun 23 19:37:20 2016 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Thu Jun 23 19:37:20 2016 +0300

----------------------------------------------------------------------
 .../platform/PlatformProcessorImpl.java         | 35 ++------------------
 .../callback/PlatformCallbackGateway.java       |  3 +-
 .../dotnet/PlatformDotNetCacheStore.java        | 27 ++++++++-------
 .../Cache/Store/CacheStoreTest.cs               | 11 ++++--
 4 files changed, 27 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/cb0deb11/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
index 5830d37..8c9e205 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java
@@ -75,10 +75,6 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
     private final Collection<StoreInfo> pendingStores =
         Collections.newSetFromMap(new ConcurrentHashMap<StoreInfo, Boolean>());
 
-    /** Started stores. */
-    private final Collection<PlatformCacheStore> stores =
-        Collections.newSetFromMap(new ConcurrentHashMap<PlatformCacheStore, Boolean>());
-
     /** Lock for store lifecycle operations. */
     private final ReadWriteLock storeLock = new ReentrantReadWriteLock();
 
@@ -95,7 +91,7 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
     private boolean started;
 
     /** Whether processor if stopped (or stopping). */
-    private boolean stopped;
+    private volatile boolean stopped;
 
     /**
      * Constructor.
@@ -165,34 +161,7 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf
     /** {@inheritDoc} */
     @Override public void stop(boolean cancel) throws IgniteCheckedException {
         if (platformCtx != null) {
-            // Destroy cache stores.
-            storeLock.writeLock().lock();
-
-            try {
-                for (PlatformCacheStore store : stores) {
-                    if (store != null) {
-                        if (store instanceof PlatformDotNetCacheStore) {
-                            PlatformDotNetCacheStore store0 = (PlatformDotNetCacheStore)store;
-
-                            try {
-                                store0.destroy(platformCtx.kernalContext());
-                            }
-                            catch (Exception e) {
-                                U.error(log, "Failed to destroy .Net cache store [store=" + store0 +
-                                    ", err=" + e.getMessage() + ']');
-                            }
-                        }
-                        else
-                            assert false : "Invalid interop cache store type: " + store;
-                    }
-                }
-            }
-            finally {
-                stopped = true;
-
-                storeLock.writeLock().unlock();
-            }
-
+            stopped = true;
             platformCtx.gateway().onStop();
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/cb0deb11/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackGateway.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackGateway.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackGateway.java
index 5093773..3439f38 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackGateway.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackGateway.java
@@ -88,7 +88,8 @@ public class PlatformCallbackGateway {
      * @param objPtr Object pointer.
      */
     public void cacheStoreDestroy(long objPtr) {
-        enter();
+        if (!lock.enterBusy())
+            return;  // no need to destroy stores on grid stop
 
         try {
             PlatformCallbackUtils.cacheStoreDestroy(envPtr, objPtr);

http://git-wip-us.apache.org/repos/asf/ignite/blob/cb0deb11/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetCacheStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetCacheStore.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetCacheStore.java
index 45d9208..1c60a42 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetCacheStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/dotnet/PlatformDotNetCacheStore.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.processors.platform.dotnet;
 
 import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
 import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.cache.store.CacheStoreSession;
 import org.apache.ignite.internal.GridKernalContext;
@@ -34,6 +35,7 @@ import org.apache.ignite.internal.util.lang.IgniteInClosureX;
 import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiInClosure;
+import org.apache.ignite.lifecycle.LifecycleAware;
 import org.apache.ignite.resources.CacheStoreSessionResource;
 import org.jetbrains.annotations.Nullable;
 
@@ -57,7 +59,7 @@ import java.util.Map;
  * method in .NET during node startup. Refer to its documentation for
  * details.
  */
-public class PlatformDotNetCacheStore<K, V> implements CacheStore<K, V>, PlatformCacheStore {
+public class PlatformDotNetCacheStore<K, V> implements CacheStore<K, V>, PlatformCacheStore, LifecycleAware {
     /** Load cache operation code. */
     private static final byte OP_LOAD_CACHE = (byte)0;
 
@@ -309,6 +311,18 @@ public class PlatformDotNetCacheStore<K, V> implements CacheStore<K, V>, Platfor
         }
     }
 
+    /** {@inheritDoc} */
+    @Override public void start() throws IgniteException {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void stop() throws IgniteException {
+        assert platformCtx != null;
+
+        platformCtx.gateway().cacheStoreDestroy(ptr);
+    }
+
     /**
      * Initialize the store.
      *
@@ -394,17 +408,6 @@ public class PlatformDotNetCacheStore<K, V> implements CacheStore<K, V>, Platfor
     }
 
     /**
-     * Destroys interop-aware component.
-     *
-     * @param ctx Context.
-     */
-    public void destroy(GridKernalContext ctx) {
-        assert ctx != null;
-
-        platformCtx.gateway().cacheStoreDestroy(ptr);
-    }
-
-    /**
      * Load callback.
      */
     private static class LoadCallback<V> extends PlatformCacheStoreCallback {

http://git-wip-us.apache.org/repos/asf/ignite/blob/cb0deb11/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs
index d6a7f60..8061e9f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs
@@ -24,6 +24,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Store
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cache;
     using Apache.Ignite.Core.Cache.Store;
+    using Apache.Ignite.Core.Impl;
     using NUnit.Framework;
 
     /// <summary>
@@ -463,15 +464,19 @@ namespace Apache.Ignite.Core.Tests.Cache.Store
         [Test]
         public void TestDynamicStoreStart()
         {
-            var cache = GetTemplateStoreCache();
+            var grid = Ignition.GetIgnite(GridName);
+            var reg = ((Ignite) grid).HandleRegistry;
+            var handleCount = reg.Count;
 
+            var cache = GetTemplateStoreCache();
             Assert.IsNotNull(cache);
 
             cache.Put(1, cache.Name);
-
             Assert.AreEqual(cache.Name, CacheTestStore.Map[1]);
 
-            _storeCount++;
+            Assert.AreEqual(handleCount + 1, reg.Count);
+            grid.DestroyCache(cache.Name);
+            Assert.AreEqual(handleCount, reg.Count);
         }
 
         [Test]


[26/50] [abbrv] ignite git commit: Merge remote-tracking branch 'upstream/gridgain-7.6.1' into gridgain-7.6.1

Posted by sb...@apache.org.
Merge remote-tracking branch 'upstream/gridgain-7.6.1' into gridgain-7.6.1


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e7ebe0a3
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e7ebe0a3
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e7ebe0a3

Branch: refs/heads/ignite-1232
Commit: e7ebe0a30da8b2f5995d51c1e59e10900b84e2b2
Parents: 9344560 a70ff4c
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Thu Jun 23 15:49:59 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Thu Jun 23 15:49:59 2016 +0300

----------------------------------------------------------------------
 .../internal/processors/cache/transactions/IgniteTxManager.java  | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------



[48/50] [abbrv] ignite git commit: Merge remote-tracking branch 'remotes/origin/master' into ignite-1232

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
index b6c460c,4bc2eea..6b25649
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
@@@ -87,8 -88,7 +88,9 @@@ import static org.apache.ignite.events.
  import static org.apache.ignite.events.EventType.EVT_NODE_LEFT;
  import static org.apache.ignite.internal.GridTopic.TOPIC_COMM_USER;
  import static org.apache.ignite.internal.managers.communication.GridIoPolicy.AFFINITY_POOL;
 +import static org.apache.ignite.internal.managers.communication.GridIoPolicy.IDX_POOL;
 +import static org.apache.ignite.internal.managers.communication.GridIoPolicy.IGFS_POOL;
+ import static org.apache.ignite.internal.managers.communication.GridIoPolicy.IGFS_POOL;
  import static org.apache.ignite.internal.managers.communication.GridIoPolicy.MANAGEMENT_POOL;
  import static org.apache.ignite.internal.managers.communication.GridIoPolicy.MARSH_CACHE_POOL;
  import static org.apache.ignite.internal.managers.communication.GridIoPolicy.P2P_POOL;
@@@ -648,7 -651,7 +663,8 @@@ public class GridIoManager extends Grid
                  case AFFINITY_POOL:
                  case UTILITY_CACHE_POOL:
                  case MARSH_CACHE_POOL:
 +                case IDX_POOL:
+                 case IGFS_POOL:
                  {
                      if (msg.isOrdered())
                          processOrderedMessage(nodeId, msg, plc, msgC);

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/core/src/main/java/org/apache/ignite/internal/processors/closure/GridClosureProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsIpcHandler.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsIpcHandler.java
index e5c2e2c,a888aff..c2ecd98
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsIpcHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsIpcHandler.java
@@@ -36,9 -32,8 +32,9 @@@ import org.apache.ignite.internal.igfs.
  import org.apache.ignite.internal.igfs.common.IgfsMessage;
  import org.apache.ignite.internal.igfs.common.IgfsPathControlRequest;
  import org.apache.ignite.internal.igfs.common.IgfsStreamControlRequest;
 +import org.apache.ignite.internal.managers.communication.GridIoPolicy;
  import org.apache.ignite.internal.util.future.GridFinishedFuture;
- import org.apache.ignite.internal.util.lang.GridPlainCallable;
+ import org.apache.ignite.internal.util.future.GridFutureAdapter;
  import org.apache.ignite.internal.util.typedef.F;
  import org.apache.ignite.internal.util.typedef.X;
  import org.apache.ignite.internal.util.typedef.internal.U;

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index 5cbd02b,0b0fe85..ed47d70
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@@ -1778,8 -1629,9 +1816,11 @@@ public class IgniteH2Indexing implement
              U.error(log, "Failed to shutdown database.", e);
          }
  
+         if (stmtCacheCleanupTask != null)
+             stmtCacheCleanupTask.close();
+ 
 +        GridH2QueryContext.clearLocalNodeStop(nodeId);
 +
          if (log.isDebugEnabled())
              log.debug("Cache query index stopped.");
      }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2AbstractKeyValueRow.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2AbstractKeyValueRow.java
index a15b569,fe6851d..284f8c5
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2AbstractKeyValueRow.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2AbstractKeyValueRow.java
@@@ -510,13 -467,7 +506,18 @@@ public abstract class GridH2AbstractKey
      }
  
      /** {@inheritDoc} */
 +    @Override public void setValue(int idx, Value v) {
 +        if (idx == VAL_COL)
 +            val = v;
 +        else {
 +            assert idx == KEY_COL : idx + " " + v;
 +
 +            key = v;
 +        }
 +    }
++
++    /** {@inheritDoc} */
+     @Override public final int hashCode() {
+         throw new IllegalStateException();
+     }
  }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
index dc54702,fbf7c7c..962946a
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
@@@ -195,30 -149,16 +195,26 @@@ public abstract class GridH2IndexBase e
       * Filters rows from expired ones and using predicate.
       *
       * @param iter Iterator over rows.
 +     * @param filter Optional filter.
       * @return Filtered iterator.
       */
 -    protected Iterator<GridH2Row> filter(Iterator<GridH2Row> iter) {
 +    protected Iterator<GridH2Row> filter(Iterator<GridH2Row> iter, IndexingQueryFilter filter) {
          IgniteBiPredicate<Object, Object> p = null;
  
-         if (filter != null) {
-             String spaceName = getTable().spaceName();
+         IndexingQueryFilter f = filters.get();
  
-             p = filter.forSpace(spaceName);
-         }
- 
-         return new FilteringIterator(iter, U.currentTimeMillis(), p);
+         return new FilteringIterator(iter, U.currentTimeMillis(), f);
      }
  
 +    /**
 +     * @return Filter for currently running query or {@code null} if none.
 +     */
 +    protected static IndexingQueryFilter threadLocalFilter() {
 +        GridH2QueryContext qctx = GridH2QueryContext.get();
 +
 +        return qctx == null ? null : qctx.filter();
 +    }
 +
      /** {@inheritDoc} */
      @Override public long getDiskSpaceUsed() {
          return 0;
@@@ -290,11 -242,11 +298,11 @@@
              if (fltr == null)
                  return true;
  
 -            Object key = row.getValue(keyCol).getObject();
 -            Object val = isValRequired ? row.getValue(valCol).getObject() : null;
 +            Object key = row.getValue(KEY_COL).getObject();
-             Object val = row.getValue(VAL_COL).getObject();
++            Object val = isValRequired ? row.getValue(VAL_COL).getObject() : null;
  
              assert key != null;
-             assert val != null;
+             assert !isValRequired || val != null;
  
              return fltr.apply(key, val);
          }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuerySplitter.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuerySplitter.java
index a6781bd,4d34ce8..25640a5
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuerySplitter.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuerySplitter.java
@@@ -23,16 -23,10 +23,17 @@@ import java.util.LinkedHashMap
  import java.util.List;
  import java.util.Set;
  import org.apache.ignite.IgniteException;
 +import org.apache.ignite.internal.processors.cache.GridCacheContext;
  import org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery;
  import org.apache.ignite.internal.processors.cache.query.GridCacheTwoStepQuery;
 +import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table;
 +import org.apache.ignite.internal.util.typedef.F;
 +import org.apache.ignite.lang.IgnitePredicate;
 +import org.h2.command.Prepared;
+ import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
  import org.h2.jdbc.JdbcPreparedStatement;
 +import org.h2.table.Column;
 +import org.h2.table.IndexColumn;
  import org.h2.util.IntArray;
  import org.jetbrains.annotations.Nullable;
  
@@@ -285,11 -155,12 +286,12 @@@ public class GridSqlQuerySplitter 
  
          mapQry.explain(false);
  
 -        GridSqlSelect rdcQry = new GridSqlSelect().from(table(0));
 +        GridSqlSelect rdcQry = new GridSqlSelect().from(table(splitIdx));
  
          // Split all select expressions into map-reduce parts.
-         List<GridSqlElement> mapExps = F.addAll(new ArrayList<GridSqlElement>(mapQry.allColumns()),
-             mapQry.columns(false));
+         List<GridSqlElement> mapExps = new ArrayList<>(mapQry.allColumns());
+ 
+         mapExps.addAll(mapQry.columns(false));
  
          final int visibleCols = mapQry.visibleColumns();
          final int havingCol = mapQry.havingColumn();

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlSelect.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlSplitterSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --cc modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index f2ac261,1b1908d..2c3cb01
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@@ -18,32 -18,22 +18,23 @@@
  package org.apache.ignite.testsuites;
  
  import junit.framework.TestSuite;
- import org.apache.ignite.internal.processors.cache.CacheLocalQueryMetricsSelfTest;
- import org.apache.ignite.internal.processors.cache.CachePartitionedQueryMetricsDistributedSelfTest;
- import org.apache.ignite.internal.processors.cache.CachePartitionedQueryMetricsLocalSelfTest;
- import org.apache.ignite.internal.processors.cache.CacheQueryNewClientSelfTest;
- import org.apache.ignite.internal.processors.cache.CacheQueryOffheapEvictDataLostTest;
- import org.apache.ignite.internal.processors.cache.CacheReplicatedQueryMetricsDistributedSelfTest;
- import org.apache.ignite.internal.processors.cache.CacheReplicatedQueryMetricsLocalSelfTest;
- import org.apache.ignite.internal.processors.cache.CacheScanPartitionQueryFallbackSelfTest;
  import org.apache.ignite.internal.processors.cache.GridCacheCrossCacheQuerySelfTest;
  import org.apache.ignite.internal.processors.cache.GridCacheQueryIndexDisabledSelfTest;
- import org.apache.ignite.internal.processors.cache.GridCacheQueryIndexingDisabledSelfTest;
  import org.apache.ignite.internal.processors.cache.GridCacheQueryInternalKeysSelfTest;
  import org.apache.ignite.internal.processors.cache.GridCacheQuerySerializationSelfTest;
 -import org.apache.ignite.internal.processors.cache.GridCacheReduceQueryMultithreadedSelfTest;
  import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectFieldsQuerySelfTest;
  import org.apache.ignite.internal.processors.cache.IgniteBinaryWrappedObjectFieldsQuerySelfTest;
  import org.apache.ignite.internal.processors.cache.IgniteCacheCollocatedQuerySelfTest;
  import org.apache.ignite.internal.processors.cache.IgniteCacheDuplicateEntityConfigurationSelfTest;
 +import org.apache.ignite.internal.processors.cache.IgniteCacheFieldsQueryNoDataSelfTest;
 +import org.apache.ignite.internal.processors.cache.IgniteCacheJoinQueryTest;
  import org.apache.ignite.internal.processors.cache.IgniteCacheLargeResultSelfTest;
- import org.apache.ignite.internal.processors.cache.IgniteCacheNoClassQuerySelfTest;
  import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapEvictQueryTest;
+ import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapIndexScanTest;
  import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapTieredMultithreadedSelfTest;
- import org.apache.ignite.internal.processors.cache.IgniteCacheP2pUnmarshallingQueryErrorTest;
  import org.apache.ignite.internal.processors.cache.IgniteCachePartitionedQueryMultiThreadedSelfTest;
  import org.apache.ignite.internal.processors.cache.IgniteCacheQueryEvictsMultiThreadedSelfTest;
+ import org.apache.ignite.internal.processors.cache.IgniteCacheQueryH2IndexingLeakTest;
  import org.apache.ignite.internal.processors.cache.IgniteCacheQueryIndexSelfTest;
  import org.apache.ignite.internal.processors.cache.IgniteCacheQueryLoadSelfTest;
  import org.apache.ignite.internal.processors.cache.IgniteCacheQueryMultiThreadedOffHeapTieredSelfTest;
@@@ -61,66 -47,17 +52,61 @@@ import org.apache.ignite.internal.proce
  import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCachePartitionedQueryP2PDisabledSelfTest;
  import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCachePartitionedQuerySelfTest;
  import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCachePartitionedSnapshotEnabledQuerySelfTest;
+ import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNoRebalanceSelfTest;
  import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeFailTest;
 +import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeRestartDistributedJoinSelfTest;
  import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeRestartSelfTest;
  import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeRestartSelfTest2;
- import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedFieldsQueryP2PEnabledSelfTest;
- import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedFieldsQuerySelfTest;
  import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQueryP2PDisabledSelfTest;
  import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQuerySelfTest;
  import org.apache.ignite.internal.processors.cache.local.IgniteCacheLocalAtomicQuerySelfTest;
- import org.apache.ignite.internal.processors.cache.local.IgniteCacheLocalFieldsQuerySelfTest;
  import org.apache.ignite.internal.processors.cache.local.IgniteCacheLocalQuerySelfTest;
 +import org.apache.ignite.internal.processors.cache.query.GridCacheSwapScanQuerySelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryCounterPartitionedAtomicTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryCounterPartitionedTxTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryCounterReplicatedAtomicTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryCounterReplicatedTxTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousBatchAckTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousBatchForceServerModeAckTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFactoryFilterTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverAtomicPrimaryWriteOrderOffheapTieredTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverAtomicPrimaryWriteOrderSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverAtomicReplicatedSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverTxOffheapTieredTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverTxReplicatedSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryFailoverTxSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryOperationP2PTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryRandomOperationsTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicNearEnabledSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicOffheapTieredTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicOffheapValuesTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicP2PDisabledSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryAtomicSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryLocalAtomicSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryLocalSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryPartitionAtomicOneNodeTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryPartitionTxOneNodeTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryPartitionedOnlySelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryPartitionedP2PDisabledSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryPartitionedSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedAtomicOneNodeTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedAtomicSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedTxOneNodeTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedP2PDisabledSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryReplicatedSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryTxOffheapTieredTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryTxOffheapValuesTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.GridCacheContinuousQueryTxSelfTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.IgniteCacheContinuousQueryClientReconnectTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.IgniteCacheContinuousQueryClientTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.IgniteCacheContinuousQueryClientTxReconnectTest;
 +import org.apache.ignite.internal.processors.cache.query.continuous.IgniteCacheContinuousQueryReconnectTest;
  import org.apache.ignite.internal.processors.query.IgniteSqlSchemaIndexingTest;
  import org.apache.ignite.internal.processors.query.IgniteSqlSplitterSelfTest;
- import org.apache.ignite.internal.processors.query.h2.sql.BaseH2CompareQueryTest;
  import org.apache.ignite.internal.processors.query.h2.sql.GridQueryParsingTest;
 +import org.apache.ignite.internal.processors.query.h2.sql.H2CompareBigQueryDistributedJoinsTest;
 +import org.apache.ignite.internal.processors.query.h2.sql.H2CompareBigQueryTest;
 +import org.apache.ignite.spi.communication.tcp.GridOrderedMessageCancelSelfTest;
  
  /**
   * Test suite for cache queries.

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/modules/spring/pom.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/bc1902b8/parent/pom.xml
----------------------------------------------------------------------


[40/50] [abbrv] ignite git commit: Ignite Web Console beta2.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/controllers/common-module.js b/modules/web-console/src/main/js/controllers/common-module.js
index 930fbc8..ba6ec62 100644
--- a/modules/web-console/src/main/js/controllers/common-module.js
+++ b/modules/web-console/src/main/js/controllers/common-module.js
@@ -35,22 +35,23 @@ import alertTemplate from '../views/templates/alert.jade!';
 
 consoleModule.run(['$rootScope', '$http', '$state', '$common', 'Auth', 'User', 'gettingStarted',
     ($root, $http, $state, $common, Auth, User, gettingStarted) => {
-    $root.gettingStarted = gettingStarted;
-
-    $root.revertIdentity = function () {
-        $http
-            .get('/api/v1/admin/revert/identity')
-            .then(User.read)
-            .then(function (user) {
-                $root.$broadcast('user', user);
-
-                $state.go('settings.admin');
-            })
-            .catch(function (errMsg) {
-                $common.showError($common.errorMessage(errMsg));
-            });
-    };
-}]);
+        $root.gettingStarted = gettingStarted;
+
+        $root.revertIdentity = function() {
+            $http
+                .get('/api/v1/admin/revert/identity')
+                .then(User.read)
+                .then(function(user) {
+                    $root.$broadcast('user', user);
+
+                    $state.go('settings.admin');
+                })
+                .catch(function(errMsg) {
+                    $common.showError($common.errorMessage(errMsg));
+                });
+        };
+    }
+]);
 
 // Modal popup configuration.
 consoleModule.config(['$modalProvider', ($modalProvider) => {
@@ -124,7 +125,7 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
         $anchorScroll.yOffset = 55;
 
         function isDefined(v) {
-            return !(v === undefined || v === null);
+            return !_.isNil(v);
         }
 
         function isEmptyString(s) {
@@ -134,7 +135,7 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             return true;
         }
 
-        var msgModal;
+        let msgModal;
 
         function errorMessage(errMsg) {
             if (errMsg) {
@@ -155,7 +156,7 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
                 title: errorMessage(msg),
                 placement: placement ? placement : 'top-right',
                 container: container ? container : 'body',
-                duration: persistent ? false : 5
+                duration: persistent ? false : 10
             });
 
             msgModal.$scope.icon = icon ? icon : 'fa-exclamation-triangle';
@@ -163,16 +164,16 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             return false;
         }
 
-        var javaBuiltInClasses = [
+        const javaBuiltInClasses = [
             'BigDecimal', 'Boolean', 'Byte', 'Date', 'Double', 'Float', 'Integer', 'Long', 'Object', 'Short', 'String', 'Time', 'Timestamp', 'UUID'
         ];
 
-        var javaBuiltInTypes = [
+        const javaBuiltInTypes = [
             'BigDecimal', 'boolean', 'Boolean', 'byte', 'Byte', 'Date', 'double', 'Double', 'float', 'Float',
             'int', 'Integer', 'long', 'Long', 'Object', 'short', 'Short', 'String', 'Time', 'Timestamp', 'UUID'
         ];
 
-        var javaBuiltInFullNameClasses = [
+        const javaBuiltInFullNameClasses = [
             'java.math.BigDecimal', 'java.lang.Boolean', 'java.lang.Byte', 'java.sql.Date', 'java.lang.Double',
             'java.lang.Float', 'java.lang.Integer', 'java.lang.Long', 'java.lang.Object', 'java.lang.Short',
             'java.lang.String', 'java.sql.Time', 'java.sql.Timestamp', 'java.util.UUID'
@@ -189,7 +190,7 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             return _.includes(javaBuiltInClasses, clsName) || _.includes(javaBuiltInFullNameClasses, clsName);
         }
 
-        var SUPPORTED_JDBC_TYPES = [
+        const SUPPORTED_JDBC_TYPES = [
             'BIGINT',
             'BIT',
             'BOOLEAN',
@@ -214,10 +215,10 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             'VARCHAR'
         ];
 
-        var ALL_JDBC_TYPES = [
+        const ALL_JDBC_TYPES = [
             {dbName: 'BIT', dbType: -7, javaType: 'Boolean', primitiveType: 'boolean'},
             {dbName: 'TINYINT', dbType: -6, javaType: 'Byte', primitiveType: 'byte'},
-            {dbName: 'SMALLINT', dbType:  5, javaType: 'Short', primitiveType: 'short'},
+            {dbName: 'SMALLINT', dbType: 5, javaType: 'Short', primitiveType: 'short'},
             {dbName: 'INTEGER', dbType: 4, javaType: 'Integer', primitiveType: 'int'},
             {dbName: 'BIGINT', dbType: -5, javaType: 'Long', primitiveType: 'long'},
             {dbName: 'FLOAT', dbType: 6, javaType: 'Float', primitiveType: 'float'},
@@ -253,7 +254,8 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             {dbName: 'SQLXML', dbType: 2009, javaType: 'Object'}
         ];
 
-        var JAVA_KEYWORDS = [
+        /*eslint-disable */
+        const JAVA_KEYWORDS = [
             'abstract',     'assert',        'boolean',      'break',           'byte',
             'case',         'catch',         'char',         'class',           'const',
             'continue',     'default',       'do',           'double',          'else',
@@ -266,8 +268,99 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             'throw',        'throws',        'transient',    'true',            'try',
             'void',         'volatile',      'while'
         ];
+        /*eslint-enable */
+
+        const VALID_JAVA_IDENTIFIER = new RegExp('^[a-zA-Z_$][a-zA-Z\\d_$]*$');
+
+        let popover = null;
+
+        function isElementInViewport(el) {
+            const rect = el.getBoundingClientRect();
+
+            return (
+                rect.top >= 0 &&
+                rect.left >= 0 &&
+                rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
+                rect.right <= (window.innerWidth || document.documentElement.clientWidth)
+            );
+        }
+
+        const _showPopoverMessage = (id, message, showTime) => {
+            const body = $('body');
+
+            let el = body.find('#' + id);
+
+            if (!el || el.length === 0)
+                el = body.find('[name="' + id + '"]');
+
+            if (el && el.length > 0) {
+                if (!isElementInViewport(el[0])) {
+                    $location.hash(el[0].id);
+
+                    $anchorScroll();
+                }
 
-        var VALID_JAVA_IDENTIFIER = new RegExp('^[a-zA-Z_$][a-zA-Z\\d_$]*$');
+                const newPopover = $popover(el, {content: message});
+
+                popover = newPopover;
+
+                $timeout(() => newPopover.$promise.then(newPopover.show), 400);
+                $timeout(() => newPopover.hide(), showTime || 5000);
+            }
+        };
+
+        function ensureActivePanel(ui, pnl, focusId) {
+            if (ui) {
+                const collapses = $('div.panel-collapse');
+
+                ui.loadPanel(pnl);
+
+                const idx = _.findIndex(collapses, function(collapse) {
+                    return collapse.id === pnl;
+                });
+
+                if (idx >= 0) {
+                    const activePanels = ui.activePanels;
+
+                    if (!_.includes(ui.topPanels, idx)) {
+                        ui.expanded = true;
+
+                        const customExpanded = ui[pnl];
+
+                        if (customExpanded)
+                            ui[customExpanded] = true;
+                    }
+
+                    if (!activePanels || activePanels.length < 1)
+                        ui.activePanels = [idx];
+                    else if (!_.includes(activePanels, idx)) {
+                        const newActivePanels = angular.copy(activePanels);
+
+                        newActivePanels.push(idx);
+
+                        ui.activePanels = newActivePanels;
+                    }
+                }
+
+                if (isDefined(focusId))
+                    $focus(focusId);
+            }
+        }
+
+        function showPopoverMessage(ui, panelId, id, message, showTime) {
+            if (popover)
+                popover.hide();
+
+            if (ui) {
+                ensureActivePanel(ui, panelId);
+
+                $timeout(() => _showPopoverMessage(id, message, showTime), ui.isPanelLoaded(panelId) ? 200 : 500);
+            }
+            else
+                _showPopoverMessage(id, message, showTime);
+
+            return false;
+        }
 
         function isValidJavaIdentifier(msg, ident, elemId, panels, panelId) {
             if (isEmptyString(ident))
@@ -282,7 +375,7 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             return true;
         }
 
-        var context = null;
+        let context = null;
 
         /**
          * Calculate width of specified text in body's font.
@@ -292,11 +385,11 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
          */
         function measureText(text) {
             if (!context) {
-                var canvas = document.createElement('canvas');
+                const canvas = document.createElement('canvas');
 
                 context = canvas.getContext('2d');
 
-                var style = window.getComputedStyle(document.getElementsByTagName('body')[0]);
+                const style = window.getComputedStyle(document.getElementsByTagName('body')[0]);
 
                 context.font = style.fontSize + ' ' + style.fontFamily;
             }
@@ -312,17 +405,17 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
          * @returns {*} Array of compacted class names.
          */
         function compactByMaxCharts(names, nameLength) {
-            for (var nameIx = 0; nameIx < names.length; nameIx ++) {
-                var s = names[nameIx];
+            for (let nameIx = 0; nameIx < names.length; nameIx++) {
+                const s = names[nameIx];
 
                 if (s.length > nameLength) {
-                    var totalLength = s.length;
+                    let totalLength = s.length;
 
-                    var packages = s.split('.');
+                    const packages = s.split('.');
 
-                    var packageCnt = packages.length - 1;
+                    const packageCnt = packages.length - 1;
 
-                    for (var i = 0; i < packageCnt && totalLength > nameLength; i++) {
+                    for (let i = 0; i < packageCnt && totalLength > nameLength; i++) {
                         if (packages[i].length > 0) {
                             totalLength -= packages[i].length - 1;
 
@@ -331,11 +424,11 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
                     }
 
                     if (totalLength > nameLength) {
-                        var className = packages[packageCnt];
+                        const className = packages[packageCnt];
 
-                        var classNameLen = className.length;
+                        const classNameLen = className.length;
 
-                        var remains = Math.min(nameLength - totalLength + classNameLen, classNameLen);
+                        let remains = Math.min(nameLength - totalLength + classNameLen, classNameLen);
 
                         if (remains < 3)
                             remains = Math.min(3, classNameLen);
@@ -343,9 +436,9 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
                         packages[packageCnt] = className.substring(0, remains) + '...';
                     }
 
-                    var result = packages[0];
+                    let result = packages[0];
 
-                    for (i = 1; i < packages.length; i++)
+                    for (let i = 1; i < packages.length; i++)
                         result += '.' + packages[i];
 
                     names[nameIx] = result;
@@ -367,27 +460,27 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             if (nameWidth <= 0)
                 return names;
 
-            var fitted = [];
+            const fitted = [];
 
-            var widthByName = [];
+            const widthByName = [];
 
-            var len = names.length;
+            const len = names.length;
 
-            var divideTo = len;
+            let divideTo = len;
 
-            for (var nameIx = 0; nameIx < len; nameIx ++) {
+            for (let nameIx = 0; nameIx < len; nameIx++) {
                 fitted[nameIx] = false;
 
                 widthByName[nameIx] = nameWidth;
             }
 
             // Try to distribute space from short class names to long class names.
-            do {
-                var remains = 0;
+            let remains = 0;
 
-                for (nameIx = 0; nameIx < len; nameIx++) {
+            do {
+                for (let nameIx = 0; nameIx < len; nameIx++) {
                     if (!fitted[nameIx]) {
-                        var curNameWidth = measureText(names[nameIx]);
+                        const curNameWidth = measureText(names[nameIx]);
 
                         if (widthByName[nameIx] > curNameWidth) {
                             fitted[nameIx] = true;
@@ -401,29 +494,28 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
                     }
                 }
 
-                var remainsByName = remains / divideTo;
+                const remainsByName = remains / divideTo;
 
-                for (nameIx = 0; nameIx < len; nameIx++) {
-                    if (!fitted[nameIx]) {
+                for (let nameIx = 0; nameIx < len; nameIx++) {
+                    if (!fitted[nameIx])
                         widthByName[nameIx] += remainsByName;
-                    }
                 }
             }
-            while(remains > 0);
+            while (remains > 0);
 
             // Compact class names to available for each space.
-            for (nameIx = 0; nameIx < len; nameIx ++) {
-                var s = names[nameIx];
+            for (let nameIx = 0; nameIx < len; nameIx++) {
+                const s = names[nameIx];
 
                 if (s.length > (nameLength / 2 | 0)) {
-                    var totalWidth = measureText(s);
+                    let totalWidth = measureText(s);
 
                     if (totalWidth > widthByName[nameIx]) {
-                        var packages = s.split('.');
+                        const packages = s.split('.');
 
-                        var packageCnt = packages.length - 1;
+                        const packageCnt = packages.length - 1;
 
-                        for (var i = 0; i < packageCnt && totalWidth > widthByName[nameIx]; i++) {
+                        for (let i = 0; i < packageCnt && totalWidth > widthByName[nameIx]; i++) {
                             if (packages[i].length > 1) {
                                 totalWidth -= measureText(packages[i].substring(1, packages[i].length));
 
@@ -431,39 +523,31 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
                             }
                         }
 
-                        var shortPackage = '';
+                        let shortPackage = '';
 
-                        for (i = 0; i < packageCnt; i++)
+                        for (let i = 0; i < packageCnt; i++)
                             shortPackage += packages[i] + '.';
 
-                        var className = packages[packageCnt];
+                        const className = packages[packageCnt];
 
-                        var classLen = className.length;
+                        const classLen = className.length;
 
-                        var minLen = Math.min(classLen, 3);
+                        let minLen = Math.min(classLen, 3);
 
                         totalWidth = measureText(shortPackage + className);
 
                         // Compact class name if shorten package path is very long.
                         if (totalWidth > widthByName[nameIx]) {
-                            var maxLen = classLen;
-
-                            var middleLen = (minLen + (maxLen - minLen) / 2 ) | 0;
-
-                            var minLenPx = measureText(shortPackage + className.substr(0, minLen) + '...');
-                            var maxLenPx = totalWidth;
+                            let maxLen = classLen;
+                            let middleLen = (minLen + (maxLen - minLen) / 2 ) | 0;
 
                             while (middleLen !== minLen && middleLen !== maxLen) {
-                                var middleLenPx = measureText(shortPackage + className.substr(0, middleLen) + '...');
+                                const middleLenPx = measureText(shortPackage + className.substr(0, middleLen) + '...');
 
-                                if (middleLenPx > widthByName[nameIx]) {
+                                if (middleLenPx > widthByName[nameIx])
                                     maxLen = middleLen;
-                                    maxLenPx = middleLenPx;
-                                }
-                                else {
+                                else
                                     minLen = middleLen;
-                                    minLenPx = middleLenPx;
-                                }
 
                                 middleLen = (minLen + (maxLen - minLen) / 2 ) | 0;
                             }
@@ -490,29 +574,20 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             if (nameWidth <= 0)
                 return label;
 
-            var totalWidth = measureText(label);
+            const totalWidth = measureText(label);
 
             if (totalWidth > nameWidth) {
-                var maxLen = label.length;
-
-                var minLen = Math.min(maxLen, 3);
-
-                var middleLen = (minLen + (maxLen - minLen) / 2 ) | 0;
-
-                var minLenPx = measureText(label.substr(0, minLen) + '...');
-                var maxLenPx = totalWidth;
+                let maxLen = label.length;
+                let minLen = Math.min(maxLen, 3);
+                let middleLen = (minLen + (maxLen - minLen) / 2 ) | 0;
 
                 while (middleLen !== minLen && middleLen !== maxLen) {
-                    var middleLenPx = measureText(label.substr(0, middleLen) + '...');
+                    const middleLenPx = measureText(label.substr(0, middleLen) + '...');
 
-                    if (middleLenPx > nameWidth) {
+                    if (middleLenPx > nameWidth)
                         maxLen = middleLen;
-                        maxLenPx = middleLenPx;
-                    }
-                    else {
+                    else
                         minLen = middleLen;
-                        minLenPx = middleLenPx;
-                    }
 
                     middleLen = (minLen + (maxLen - minLen) / 2 ) | 0;
                 }
@@ -531,19 +606,19 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
          * @returns {*[]} First element is length of class for single value, second element is length for pair vlaue.
          */
         function availableWidth(index, id) {
-            var idElem = $('#' + id);
+            const idElem = $('#' + id);
 
-            var width = 0;
+            let width = 0;
 
-            switch (idElem.prop("tagName")) {
+            switch (idElem.prop('tagName')) {
                 // Detection of available width in presentation table row.
                 case 'TABLE':
-                    var cont = $(idElem.find('tr')[index - 1]).find('td')[0];
+                    const cont = $(idElem.find('tr')[index - 1]).find('td')[0];
 
                     width = cont.clientWidth;
 
                     if (width > 0) {
-                        var children = $(cont).children(':not("a")');
+                        const children = $(cont).children(':not("a")');
 
                         _.forEach(children, function(child) {
                             if ('offsetWidth' in child)
@@ -563,104 +638,15 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
                     });
 
                     break;
-            }
-
-            return width | 0;
-        }
-
-        var popover = null;
-
-        function ensureActivePanel(ui, pnl, focusId) {
-            if (ui) {
-                var collapses = $('div.panel-collapse');
-
-                ui.loadPanel(pnl);
-
-                var idx = _.findIndex(collapses, function(collapse) {
-                    return collapse.id === pnl;
-                });
-
-                if (idx >= 0) {
-                    var activePanels = ui.activePanels;
-
-                    if (!_.includes(ui.topPanels, idx)) {
-                        ui.expanded = true;
-
-                        var customExpanded = ui[pnl];
-
-                        if (customExpanded)
-                            ui[customExpanded] = true;
-                    }
-
-                    if (!activePanels || activePanels.length < 1)
-                        ui.activePanels = [idx];
-                    else if (!_.includes(activePanels, idx)) {
-                        var newActivePanels = angular.copy(activePanels);
-
-                        newActivePanels.push(idx);
-
-                        ui.activePanels = newActivePanels;
-                    }
-                }
-
-                if (isDefined(focusId))
-                    $focus(focusId);
-            }
-        }
-
-        function isElementInViewport(el) {
-            var rect = el.getBoundingClientRect();
-
-            return (
-                rect.top >= 0 &&
-                rect.left >= 0 &&
-                rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
-                rect.right <= (window.innerWidth || document.documentElement.clientWidth)
-            );
-        }
-
-        const _showPopoverMessage = (id, message, showTime) => {
-            var body = $('body');
-
-            var el = body.find('#' + id);
-
-            if (!el || el.length === 0)
-                el = body.find('[name="' + id + '"]');
-
-            if (el && el.length > 0) {
-                if (!isElementInViewport(el[0])) {
-                    $location.hash(el[0].id);
-
-                    $anchorScroll();
-                }
-
-                var newPopover = $popover(el, {content: message});
-
-                popover = newPopover;
-
-                $timeout(function () { newPopover.$promise.then(newPopover.show); }, 400);
-
-                $timeout(function () { newPopover.hide(); }, showTime || 5000);
-            }
-        };
-
-        function showPopoverMessage(ui, panelId, id, message, showTime) {
-            if (popover)
-                popover.hide();
 
-            if (ui) {
-                ensureActivePanel(ui, panelId);
-
-                $timeout(() => _showPopoverMessage(id, message, showTime), ui.isPanelLoaded(panelId) ? 200 : 500);
+                default:
             }
-            else
-                _showPopoverMessage(id, message, showTime);
 
-            return false;
+            return width | 0;
         }
 
         function getModel(obj, field) {
-            var path = field.path;
+            let path = field.path;
 
             if (!isDefined(path) || !isDefined(obj))
                 return obj;
@@ -668,11 +654,11 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
             path = path.replace(/^\./, '');           // strip a leading dot
 
-            var segs = path.split('.');
-            var root = obj;
+            const segs = path.split('.');
+            let root = obj;
 
             while (segs.length > 0) {
-                var pathStep = segs.shift();
+                const pathStep = segs.shift();
 
                 if (typeof root[pathStep] === 'undefined')
                     root[pathStep] = {};
@@ -683,52 +669,9 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             return root;
         }
 
-        function checkGroupDirty(group, curItem, srcItem) {
-            function _compareField(field) {
-                var curModel = getModel(curItem, field);
-                var srcModel = getModel(srcItem, field);
-
-                if (field.model) {
-                    if (field.model === 'kind' && isDefined(curModel.kind)) {
-                        if (curModel.kind !== srcModel.kind)
-                            return true;
-
-                        if (_compareFields(field.details[curModel.kind].fields))
-                            return true;
-                    }
-
-                    var curValue = curModel[field.model];
-                    var srcValue = srcModel[field.model];
-
-                    if ((_.isArray(curValue) || _.isString(curValue)) && (curValue.length === 0) && (srcValue === undefined))
-                        curValue = undefined;
-
-                    if (_.isBoolean(curValue) && !curValue && srcValue === undefined)
-                        curValue = undefined;
-
-                    var isCur = isDefined(curValue);
-                    var isSrc = isDefined(srcValue);
-
-                    return !!((isCur && !isSrc) || (!isCur && isSrc) || (isCur && isSrc && !angular.equals(curValue, srcValue)));
-                }
-                else if (field.type === 'panel-details' &&  _compareFields(field.details))
-                    return true;
-
-                return false;
-            }
-
-            function _compareFields(fields) {
-                return _.findIndex(fields, _compareField) >= 0;
-            }
-
-            group.dirty = _compareFields(group.fields);
-
-            return group.dirty;
-        }
-
         function extractDataSource(cache) {
             if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) {
-                var storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind];
+                const storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind];
 
                 if (storeFactory.dialect || (storeFactory.connectVia === 'DataSource'))
                     return storeFactory;
@@ -737,7 +680,7 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             return null;
         }
 
-        var cacheStoreJdbcDialects = [
+        const cacheStoreJdbcDialects = [
             {value: 'Generic', label: 'Generic JDBC'},
             {value: 'Oracle', label: 'Oracle'},
             {value: 'DB2', label: 'IBM DB2'},
@@ -748,7 +691,7 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
         ];
 
         function domainForStoreConfigured(domain) {
-            var isEmpty = !isDefined(domain) || (isEmptyString(domain.databaseSchema) &&
+            const isEmpty = !isDefined(domain) || (isEmptyString(domain.databaseSchema) &&
                 isEmptyString(domain.databaseTable) &&
                 _.isEmpty(domain.keyFields) &&
                 _.isEmpty(domain.valueFields));
@@ -756,46 +699,49 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
             return !isEmpty;
         }
 
-        var DS_CHECK_SUCCESS = { checked: true };
+        const DS_CHECK_SUCCESS = { checked: true };
 
         function compareDataSources(firstCache, secondCache) {
-            var firstDs = extractDataSource(firstCache);
-            var secondDs = extractDataSource(secondCache);
+            const firstDs = extractDataSource(firstCache);
+            const secondDs = extractDataSource(secondCache);
 
             if (firstDs && secondDs) {
-                var firstDB = firstDs.dialect;
-                var secondDB = secondDs.dialect;
+                const firstDB = firstDs.dialect;
+                const secondDB = secondDs.dialect;
 
-                if (firstDs.dataSourceBean === secondDs.dataSourceBean && firstDB !== secondDB) {
-                    return {
-                        checked: false,
-                        firstCache: firstCache,
-                        firstDB: firstDB,
-                        secondCache: secondCache,
-                        secondDB: secondDB
-                    };
-                }
+                if (firstDs.dataSourceBean === secondDs.dataSourceBean && firstDB !== secondDB)
+                    return {checked: false, firstCache, firstDB, secondCache, secondDB};
             }
 
             return DS_CHECK_SUCCESS;
         }
 
+        function compareSQLSchemaNames(firstCache, secondCache) {
+            const firstName = firstCache.sqlSchema;
+            const secondName = secondCache.sqlSchema;
+
+            if (firstName && secondName && (firstName === secondName))
+                return {checked: false, firstCache, secondCache};
+
+            return DS_CHECK_SUCCESS;
+        }
+
         function toJavaName(prefix, name) {
-            var javaName = name ? name.replace(/[^A-Za-z_0-9]+/g, '_') : 'dflt';
+            const javaName = name ? name.replace(/[^A-Za-z_0-9]+/g, '_') : 'dflt';
 
             return prefix + javaName.charAt(0).toLocaleUpperCase() + javaName.slice(1);
         }
 
         return {
-            getModel: getModel,
-            mkOptions: function (options) {
-                return _.map(options, function (option) {
+            getModel,
+            mkOptions(options) {
+                return _.map(options, (option) => {
                     return {value: option, label: isDefined(option) ? option : 'Not set'};
                 });
             },
-            isDefined: isDefined,
-            hasProperty: function (obj, props) {
-                for (var propName in props) {
+            isDefined,
+            hasProperty(obj, props) {
+                for (const propName in props) {
                     if (props.hasOwnProperty(propName)) {
                         if (obj[propName])
                             return true;
@@ -804,14 +750,14 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
 
                 return false;
             },
-            isEmptyString: isEmptyString,
-            errorMessage: errorMessage,
-            hideAlert: function () {
+            isEmptyString,
+            errorMessage,
+            hideAlert() {
                 if (msgModal)
                     msgModal.hide();
             },
-            showError: showError,
-            showInfo: function (msg) {
+            showError,
+            showInfo(msg) {
                 if (msgModal)
                     msgModal.hide();
 
@@ -823,25 +769,25 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
 
                 msgModal.$scope.icon = 'fa-check-circle-o';
             },
-            SUPPORTED_JDBC_TYPES: SUPPORTED_JDBC_TYPES,
-            findJdbcType: function (jdbcType) {
-                var res =  _.find(ALL_JDBC_TYPES, function (item) {
+            SUPPORTED_JDBC_TYPES,
+            findJdbcType(jdbcType) {
+                const res = _.find(ALL_JDBC_TYPES, function(item) {
                     return item.dbType === jdbcType;
                 });
 
                 return res ? res : {dbName: 'Unknown', javaType: 'Unknown'};
             },
-            javaBuiltInClasses: javaBuiltInClasses,
-            javaBuiltInTypes: javaBuiltInTypes,
-            isJavaBuiltInClass: isJavaBuiltInClass,
-            isValidJavaIdentifier: isValidJavaIdentifier,
-            isValidJavaClass: function (msg, ident, allowBuiltInClass, elemId, packageOnly, panels, panelId) {
+            javaBuiltInClasses,
+            javaBuiltInTypes,
+            isJavaBuiltInClass,
+            isValidJavaIdentifier,
+            isValidJavaClass(msg, ident, allowBuiltInClass, elemId, packageOnly, panels, panelId) {
                 if (isEmptyString(ident))
                     return showPopoverMessage(panels, panelId, elemId, msg + ' could not be empty!');
 
-                var parts = ident.split('.');
+                const parts = ident.split('.');
 
-                var len = parts.length;
+                const len = parts.length;
 
                 if (!allowBuiltInClass && isJavaBuiltInClass(ident))
                     return showPopoverMessage(panels, panelId, elemId, msg + ' should not be the Java build-in class!');
@@ -849,8 +795,8 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
                 if (len < 2 && !isJavaBuiltInClass(ident) && !packageOnly)
                     return showPopoverMessage(panels, panelId, elemId, msg + ' does not have package specified!');
 
-                for (var i = 0; i < parts.length; i++) {
-                    var part = parts[i];
+                for (let i = 0; i < parts.length; i++) {
+                    const part = parts[i];
 
                     if (!isValidJavaIdentifier(msg, part, elemId, panels, panelId))
                         return false;
@@ -858,14 +804,14 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
 
                 return true;
             },
-            domainForQueryConfigured: function (domain) {
-                var isEmpty = !isDefined(domain) || (_.isEmpty(domain.fields) &&
+            domainForQueryConfigured(domain) {
+                const isEmpty = !isDefined(domain) || (_.isEmpty(domain.fields) &&
                     _.isEmpty(domain.aliases) &&
                     _.isEmpty(domain.indexes));
 
                 return !isEmpty;
             },
-            domainForStoreConfigured: domainForStoreConfigured,
+            domainForStoreConfigured,
             /**
              * Cut class name by width in pixel or width in symbol count.
              *
@@ -876,17 +822,17 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
              * @param divider String to visualy divide items.
              * @returns {*} Array of compacted class names.
              */
-            compactJavaName: function (id, index, maxLength, names, divider) {
+            compactJavaName(id, index, maxLength, names, divider) {
                 divider = ' ' + divider + ' ';
 
-                var prefix = index + ') ';
+                const prefix = index + ') ';
 
-                var nameCnt = names.length;
+                const nameCnt = names.length;
 
-                var nameLength = ((maxLength - 3 * (nameCnt - 1)) / nameCnt) | 0;
+                const nameLength = ((maxLength - 3 * (nameCnt - 1)) / nameCnt) | 0;
 
                 try {
-                    var nameWidth = (availableWidth(index, id) - measureText(prefix) - (nameCnt - 1) * measureText(divider)) /
+                    const nameWidth = (availableWidth(index, id) - measureText(prefix) - (nameCnt - 1) * measureText(divider)) /
                         nameCnt | 0;
 
                     // HTML5 calculation of showed message width.
@@ -896,9 +842,9 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
                     names = compactByMaxCharts(names, nameLength);
                 }
 
-                var result = prefix + names[0];
+                let result = prefix + names[0];
 
-                for (var nameIx = 1; nameIx < names.length; nameIx ++)
+                for (let nameIx = 1; nameIx < names.length; nameIx++)
                     result += divider + names[nameIx];
 
                 return result;
@@ -912,28 +858,28 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
              * @param label Text to compact.
              * @returns Compacted label text.
              */
-            compactTableLabel: function (id, index, maxLength, label) {
+            compactTableLabel(id, index, maxLength, label) {
                 label = index + ') ' + label;
 
                 try {
-                    var nameWidth = availableWidth(index, id) | 0;
+                    const nameWidth = availableWidth(index, id) | 0;
 
                     // HTML5 calculation of showed message width.
                     label = compactLabelByPixels(label, nameWidth);
                 }
                 catch (err) {
-                    var nameLength = maxLength - 3 | 0;
+                    const nameLength = maxLength - 3 | 0;
 
                     label = label.length > maxLength ? label.substr(0, nameLength) + '...' : label;
                 }
 
                 return label;
             },
-            widthIsSufficient: function(id, index, text) {
+            widthIsSufficient(id, index, text) {
                 try {
-                    var available = availableWidth(index, id);
+                    const available = availableWidth(index, id);
 
-                    var required = measureText(text);
+                    const required = measureText(text);
 
                     return !available || available >= Math.floor(required);
                 }
@@ -941,15 +887,15 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
                     return true;
                 }
             },
-            ensureActivePanel: function (panels, id, focusId) {
+            ensureActivePanel(panels, id, focusId) {
                 ensureActivePanel(panels, id, focusId);
             },
-            showPopoverMessage: showPopoverMessage,
-            hidePopover: function () {
+            showPopoverMessage,
+            hidePopover() {
                 if (popover)
                     popover.hide();
             },
-            confirmUnsavedChanges: function(dirty, selectFunc) {
+            confirmUnsavedChanges(dirty, selectFunc) {
                 if (dirty) {
                     if ($window.confirm('You have unsaved changes.\n\nAre you sure you want to discard them?'))
                         selectFunc();
@@ -957,16 +903,16 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
                 else
                     selectFunc();
             },
-            saveBtnTipText: function (dirty, objectName) {
+            saveBtnTipText(dirty, objectName) {
                 if (dirty)
                     return 'Save ' + objectName;
 
                 return 'Nothing to save';
             },
-            download: function (type, name, data) {
-                var file = document.createElement('a');
+            download(type, name, data) {
+                const file = document.createElement('a');
 
-                file.setAttribute('href', 'data:' + type +';charset=utf-8,' + data);
+                file.setAttribute('href', 'data:' + type + ';charset=utf-8,' + data);
                 file.setAttribute('download', name);
                 file.setAttribute('target', '_self');
 
@@ -978,49 +924,46 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
 
                 document.body.removeChild(file);
             },
-            formUI: function () {
+            formUI() {
                 return {
                     ready: false,
                     expanded: false,
                     loadedPanels: [],
-                    loadPanel: function(pnl) {
+                    loadPanel(pnl) {
                         if (!_.includes(this.loadedPanels, pnl))
                             this.loadedPanels.push(pnl);
                     },
-                    isPanelLoaded: function(pnl) {
+                    isPanelLoaded(pnl) {
                         return _.includes(this.loadedPanels, pnl);
                     }
                 };
             },
-            getQueryVariable: function(name) {
-                var attrs = window.location.search.substring(1).split("&");
-
-                var attr = _.find(attrs, function(attr) {
-                    return attr === name || (attr.indexOf('=') >= 0 && attr.substr(0, attr.indexOf('=')) === name);
-                });
+            getQueryVariable(name) {
+                const attrs = window.location.search.substring(1).split('&');
+                const attr = _.find(attrs, (a) => a === name || (a.indexOf('=') >= 0 && a.substr(0, a.indexOf('=')) === name));
 
                 if (!isDefined(attr))
-                    return undefined;
+                    return null;
 
                 if (attr === name)
                     return true;
 
                 return attr.substr(attr.indexOf('=') + 1);
             },
-            cacheStoreJdbcDialects: cacheStoreJdbcDialects,
-            cacheStoreJdbcDialectsLabel: function (dialect) {
-                var found = _.find(cacheStoreJdbcDialects, function (dialectVal) {
+            cacheStoreJdbcDialects,
+            cacheStoreJdbcDialectsLabel(dialect) {
+                const found = _.find(cacheStoreJdbcDialects, function(dialectVal) {
                     return dialectVal.value === dialect;
                 });
 
-                return found ? found.label : undefined;
+                return found ? found.label : null;
             },
-            checkCachesDataSources: function (caches, checkCacheExt) {
-                var res = DS_CHECK_SUCCESS;
+            checkCachesDataSources(caches, checkCacheExt) {
+                let res = DS_CHECK_SUCCESS;
 
-                _.find(caches, function (curCache, curIx) {
+                _.find(caches, function(curCache, curIx) {
                     if (isDefined(checkCacheExt)) {
-                        if (!isDefined(checkCacheExt._id) || checkCacheExt.id != curCache._id) {
+                        if (checkCacheExt._id !== curCache._id) {
                             res = compareDataSources(checkCacheExt, curCache);
 
                             return !res.checked;
@@ -1028,27 +971,53 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
 
                         return false;
                     }
-                    else {
-                        return _.find(caches, function (checkCache, checkIx) {
-                            if (checkIx < curIx) {
-                                res = compareDataSources(checkCache, curCache);
 
-                                return !res.checked;
-                            }
+                    return _.find(caches, function(checkCache, checkIx) {
+                        if (checkIx < curIx) {
+                            res = compareDataSources(checkCache, curCache);
 
-                            return false;
-                        });
+                            return !res.checked;
+                        }
+
+                        return false;
+                    });
+                });
+
+                return res;
+            },
+            checkCacheSQLSchemas(caches, checkCacheExt) {
+                let res = DS_CHECK_SUCCESS;
+
+                _.find(caches, (curCache, curIx) => {
+                    if (isDefined(checkCacheExt)) {
+                        if (checkCacheExt._id !== curCache._id) {
+                            res = compareSQLSchemaNames(checkCacheExt, curCache);
+
+                            return !res.checked;
+                        }
+
+                        return false;
                     }
+
+                    return _.find(caches, function(checkCache, checkIx) {
+                        if (checkIx < curIx) {
+                            res = compareSQLSchemaNames(checkCache, curCache);
+
+                            return !res.checked;
+                        }
+
+                        return false;
+                    });
                 });
 
                 return res;
             },
-            autoCacheStoreConfiguration: function (cache, domains) {
-                var cacheStoreFactory = isDefined(cache.cacheStoreFactory) &&
+            autoCacheStoreConfiguration(cache, domains) {
+                const cacheStoreFactory = isDefined(cache.cacheStoreFactory) &&
                     isDefined(cache.cacheStoreFactory.kind);
 
                 if (!cacheStoreFactory && _.findIndex(domains, domainForStoreConfigured) >= 0) {
-                    var dflt = !cache.readThrough && !cache.writeThrough;
+                    const dflt = !cache.readThrough && !cache.writeThrough;
 
                     return {
                         cacheStoreFactory: {
@@ -1063,17 +1032,17 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
                     };
                 }
             },
-            autoClusterSwapSpiConfiguration: function (cluster, caches) {
-                var swapConfigured = cluster.swapSpaceSpi && cluster.swapSpaceSpi.kind;
+            autoClusterSwapSpiConfiguration(cluster, caches) {
+                const swapConfigured = cluster.swapSpaceSpi && cluster.swapSpaceSpi.kind;
 
-                if (!swapConfigured && _.find(caches, function (cache) {
+                if (!swapConfigured && _.find(caches, function(cache) {
                     return cache.swapEnabled;
                 }))
                     return {swapSpaceSpi: {kind: 'FileSwapSpaceSpi'}};
 
-                return undefined;
+                return null;
             },
-            randomString: (len) => {
+            randomString(len) {
                 const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
                 const possibleLen = possible.length;
 
@@ -1083,6 +1052,41 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
                     res += possible.charAt(Math.floor(Math.random() * possibleLen));
 
                 return res;
+            },
+            checkFieldValidators(ui) {
+                const form = ui.inputForm;
+                const errors = form.$error;
+                const errKeys = Object.keys(errors);
+
+                if (errKeys && errKeys.length > 0) {
+                    const firstErrorKey = errKeys[0];
+
+                    const firstError = errors[firstErrorKey][0];
+                    const actualError = firstError.$error[firstErrorKey][0];
+
+                    const errNameFull = actualError.$name;
+                    const errNameShort = errNameFull.endsWith('TextInput') ? errNameFull.substring(0, errNameFull.length - 9) : errNameFull;
+
+                    const extractErrorMessage = function(errName) {
+                        try {
+                            return errors[firstErrorKey][0].$errorMessages[errName][firstErrorKey];
+                        }
+                        catch (ignored) {
+                            try {
+                                return form[firstError.$name].$errorMessages[errName][firstErrorKey];
+                            }
+                            catch (ignited) {
+                                return false;
+                            }
+                        }
+                    };
+
+                    const msg = extractErrorMessage(errNameFull) || extractErrorMessage(errNameShort) || 'Invalid value!';
+
+                    return showPopoverMessage(ui, firstError.$name, errNameFull, msg);
+                }
+
+                return true;
             }
         };
     }]);
@@ -1090,25 +1094,24 @@ consoleModule.service('$common', ['$alert', '$popover', '$anchorScroll', '$locat
 // Confirm change location.
 consoleModule.service('$unsavedChangesGuard', ['$rootScope', ($root) => {
     return {
-        install: function ($scope) {
-            $scope.$on("$destroy", function() {
+        install($scope, customDirtyCheck = () => $scope.ui.inputForm.$dirty) {
+            $scope.$on('$destroy', function() {
                 window.onbeforeunload = null;
             });
 
-            var unbind = $root.$on('$stateChangeStart', function(event) {
-                if ($scope.ui && $scope.ui.inputForm && $scope.ui.inputForm.$dirty) {
-                    if (!confirm('You have unsaved changes.\n\nAre you sure you want to discard them?')) {
+            const unbind = $root.$on('$stateChangeStart', function(event) {
+                if ($scope.ui && $scope.ui.inputForm && customDirtyCheck()) {
+                    if (!confirm('You have unsaved changes.\n\nAre you sure you want to discard them?')) // eslint-disable-line no-alert
                         event.preventDefault();
-                    } else {
+                    else
                         unbind();
-                    }
                 }
             });
 
-            window.onbeforeunload = function(){
+            window.onbeforeunload = function() {
                 return $scope.ui && $scope.ui.inputForm && $scope.ui.inputForm.$dirty
                     ? 'You have unsaved changes.\n\nAre you sure you want to discard them?'
-                    : undefined;
+                    : null;
             };
         }
     };
@@ -1116,9 +1119,9 @@ consoleModule.service('$unsavedChangesGuard', ['$rootScope', ($root) => {
 
 // Service for confirm or skip several steps.
 consoleModule.service('$confirmBatch', ['$modal', '$rootScope', '$q', ($modal, $root, $q) => {
-    var scope = $root.$new();
+    const scope = $root.$new();
 
-    scope.confirmModal = $modal({templateUrl: '/templates/batch-confirm.html', scope: scope, placement: 'center', show: false});
+    scope.confirmModal = $modal({templateUrl: '/templates/batch-confirm.html', scope, placement: 'center', show: false});
 
     function _done(cancel) {
         scope.confirmModal.hide();
@@ -1138,43 +1141,43 @@ consoleModule.service('$confirmBatch', ['$modal', '$rootScope', '$q', ($modal, $
             _done();
     }
 
-    scope.cancel = function () {
-            _done(true);
+    scope.cancel = function() {
+        _done(true);
     };
 
-    scope.skip = function (applyToAll) {
+    scope.skip = function(applyToAll) {
         if (applyToAll) {
-            for (var i = scope.curIx; i < scope.items.length; i++)
+            for (let i = scope.curIx; i < scope.items.length; i++)
                 scope.items[i].skip = true;
 
-                _done();
-            }
-            else
-                _nextElement(true);
+            _done();
+        }
+        else
+            _nextElement(true);
     };
 
-    scope.overwrite = function (applyToAll) {
+    scope.overwrite = function(applyToAll) {
         if (applyToAll)
-                _done();
-            else
-                _nextElement(false);
+            _done();
+        else
+            _nextElement(false);
     };
 
     return {
-    /**
-     * Show confirm all dialog.
-     *
-         * @param confirmMessageFn Function to generate a confirm message.
-     * @param itemsToConfirm Array of element to process by confirm.
-     */
-        confirm: function (confirmMessageFn, itemsToConfirm) {
+        /**
+         * Show confirm all dialog.
+         *
+             * @param confirmMessageFn Function to generate a confirm message.
+         * @param itemsToConfirm Array of element to process by confirm.
+         */
+        confirm(confirmMessageFn, itemsToConfirm) {
             scope.deferred = $q.defer();
 
             scope.contentGenerator = confirmMessageFn;
 
             scope.items = itemsToConfirm;
             scope.curIx = 0;
-            scope.content = (scope.items && scope.items.length > 0) ? scope.contentGenerator(scope.items[0]) : undefined;
+            scope.content = (scope.items && scope.items.length > 0) ? scope.contentGenerator(scope.items[0]) : null;
 
             scope.confirmModal.$promise.then(scope.confirmModal.show);
 
@@ -1185,28 +1188,17 @@ consoleModule.service('$confirmBatch', ['$modal', '$rootScope', '$q', ($modal, $
 
 // 'Clone' popup service.
 consoleModule.service('$clone', ['$modal', '$rootScope', '$q', ($modal, $root, $q) => {
-    var scope = $root.$new();
+    const scope = $root.$new();
 
-    var deferred;
-    var _names = [];
-    var _validator;
-
-    scope.ok = function (newName) {
-        if (!_validator || _validator(newName)) {
-            deferred.resolve(_nextAvailableName(newName));
-
-            cloneModal.hide();
-        }
-    };
-
-    var cloneModal = $modal({templateUrl: '/templates/clone.html', scope: scope, placement: 'center', show: false});
+    let _names = [];
+    let deferred;
+    let _validator;
 
     function _nextAvailableName(name) {
-        var num = 1;
-
-        var tmpName = name;
+        let num = 1;
+        let tmpName = name;
 
-        while(_.includes(_names, tmpName)) {
+        while (_.includes(_names, tmpName)) {
             tmpName = name + '_' + num.toString();
 
             num++;
@@ -1215,7 +1207,17 @@ consoleModule.service('$clone', ['$modal', '$rootScope', '$q', ($modal, $root, $
         return tmpName;
     }
 
-    cloneModal.confirm = function (oldName, names, validator) {
+    const cloneModal = $modal({templateUrl: '/templates/clone.html', scope, placement: 'center', show: false});
+
+    scope.ok = function(newName) {
+        if (!_validator || _validator(newName)) {
+            deferred.resolve(_nextAvailableName(newName));
+
+            cloneModal.hide();
+        }
+    };
+
+    cloneModal.confirm = function(oldName, names, validator) {
         _names = names;
 
         scope.newName = _nextAvailableName(oldName);
@@ -1233,15 +1235,15 @@ consoleModule.service('$clone', ['$modal', '$rootScope', '$q', ($modal, $root, $
 }]);
 
 // Tables support service.
-consoleModule.service('$table', ['$common', '$focus', function ($common, $focus) {
+consoleModule.service('$table', ['$common', '$focus', function($common, $focus) {
     function _model(item, field) {
         return $common.getModel(item, field);
     }
 
-    var table = {name: 'none', editIndex: -1};
+    const table = {name: 'none', editIndex: -1};
 
     function _tableReset() {
-        table.field = undefined;
+        delete table.field;
         table.name = 'none';
         table.editIndex = -1;
 
@@ -1249,9 +1251,9 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
     }
 
     function _tableSaveAndReset() {
-        var field = table.field;
+        const field = table.field;
 
-        var save = $common.isDefined(field) && $common.isDefined(field.save);
+        const save = $common.isDefined(field) && $common.isDefined(field.save);
 
         if (!save || !$common.isDefined(field) || field.save(field, table.editIndex, true)) {
             _tableReset();
@@ -1269,7 +1271,7 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
     }
 
     function _tableUI(field) {
-        var ui = field.ui;
+        const ui = field.ui;
 
         return ui ? ui : field.type;
     }
@@ -1285,9 +1287,9 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
     function _tableStartEdit(item, tbl, index, save) {
         _tableState(tbl, index);
 
-        var val = _model(item, tbl)[tbl.model][index];
+        const val = _.get(_model(item, tbl), tbl.model)[index];
 
-        var ui = _tableUI(tbl);
+        const ui = _tableUI(tbl);
 
         tbl.save = save;
 
@@ -1317,7 +1319,7 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
     function _tableNewItem(tbl) {
         _tableState(tbl, -1);
 
-        var ui = _tableUI(tbl);
+        const ui = _tableUI(tbl);
 
         if (ui === 'table-pair') {
             tbl.newKey = null;
@@ -1347,53 +1349,55 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
         tableReset: _tableReset,
         tableSaveAndReset: _tableSaveAndReset,
         tableNewItem: _tableNewItem,
-        tableNewItemActive: function (tbl) {
+        tableNewItemActive(tbl) {
             return table.name === tbl.model && table.editIndex < 0;
         },
-        tableEditing: function (tbl, index) {
+        tableEditing(tbl, index) {
             return table.name === tbl.model && table.editIndex === index;
         },
-        tableEditedRowIndex: function () {
+        tableEditedRowIndex() {
             return table.editIndex;
         },
-        tableField: function () {
+        tableField() {
             return table.field;
         },
         tableStartEdit: _tableStartEdit,
-        tableRemove: function (item, field, index) {
+        tableRemove(item, field, index) {
             _tableReset();
 
-            _model(item, field)[field.model].splice(index, 1);
+            _.get(_model(item, field), field.model).splice(index, 1);
         },
         tablePairValue: _tablePairValue,
-        tablePairSave: function (pairValid, item, field, index, stopEdit) {
-            var valid = pairValid(item, field, index);
+        tablePairSave(pairValid, item, field, index, stopEdit) {
+            const valid = pairValid(item, field, index);
 
             if (valid) {
-                var pairValue = _tablePairValue(field, index);
+                const pairValue = _tablePairValue(field, index);
+
+                let pairModel = {};
 
-                var pairModel = {};
+                const container = _.get(item, field.model);
 
                 if (index < 0) {
                     pairModel[field.keyName] = pairValue.key;
                     pairModel[field.valueName] = pairValue.value;
 
-                    if (item[field.model])
-                        item[field.model].push(pairModel);
+                    if (container)
+                        container.push(pairModel);
                     else
-                        item[field.model] = [pairModel];
+                        _.set(item, field.model, [pairModel]);
 
                     if (!stopEdit)
                         _tableNewItem(field);
                 }
                 else {
-                    pairModel = item[field.model][index];
+                    pairModel = container[index];
 
                     pairModel[field.keyName] = pairValue.key;
                     pairModel[field.valueName] = pairValue.value;
 
                     if (!stopEdit) {
-                        if (index < item[field.model].length - 1)
+                        if (index < container.length - 1)
                             _tableStartEdit(item, field, index + 1);
                         else
                             _tableNewItem(field);
@@ -1403,33 +1407,33 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
 
             return valid;
         },
-        tablePairSaveVisible: function (field, index) {
-            var pairValue = _tablePairValue(field, index);
+        tablePairSaveVisible(field, index) {
+            const pairValue = _tablePairValue(field, index);
 
             return !$common.isEmptyString(pairValue.key) && !$common.isEmptyString(pairValue.value);
         },
-        tableFocusInvalidField: function (index, id) {
+        tableFocusInvalidField(index, id) {
             _tableFocus(id, index);
 
             return false;
         },
-        tableFieldId: function (index, id) {
+        tableFieldId(index, id) {
             return (index < 0 ? 'new' : 'cur') + id + (index >= 0 ? index : '');
         }
     };
 }]);
 
-consoleModule.service('ngCopy', ['$window', '$common', function ($window, $common) {
-    var body = angular.element($window.document.body);
+consoleModule.service('ngCopy', ['$window', '$common', function($window, $common) {
+    const body = angular.element($window.document.body);
 
-    var textArea = angular.element('<textarea/>');
+    const textArea = angular.element('<textarea/>');
 
     textArea.css({
         position: 'fixed',
         opacity: '0'
     });
 
-    return function (toCopy) {
+    return function(toCopy) {
         textArea.val(toCopy);
 
         body.append(textArea);
@@ -1440,18 +1444,18 @@ consoleModule.service('ngCopy', ['$window', '$common', function ($window, $commo
             if (document.execCommand('copy'))
                 $common.showInfo('Value copied to clipboard');
             else
-                window.prompt("Copy to clipboard: Ctrl+C, Enter", toCopy);
+                window.prompt('Copy to clipboard: Ctrl+C, Enter', toCopy);  // eslint-disable-line no-alert
         } catch (err) {
-            window.prompt("Copy to clipboard: Ctrl+C, Enter", toCopy);
+            window.prompt('Copy to clipboard: Ctrl+C, Enter', toCopy);  // eslint-disable-line no-alert
         }
 
         textArea.remove();
     };
-}]).directive('ngClickCopy', ['ngCopy', function (ngCopy) {
+}]).directive('ngClickCopy', ['ngCopy', function(ngCopy) {
     return {
         restrict: 'A',
-        link: function (scope, element, attrs) {
-            element.bind('click', function () {
+        link(scope, element, attrs) {
+            element.bind('click', function() {
                 ngCopy(attrs.ngClickCopy);
             });
 
@@ -1461,36 +1465,16 @@ consoleModule.service('ngCopy', ['$window', '$common', function ($window, $commo
     };
 }]);
 
-consoleModule.filter('tablesSearch', function() {
-    return function(array, query) {
-        if (!angular.isUndefined(array) && !angular.isUndefined(query) && !angular.isUndefined(query.$)) {
-            var filtredArray = [];
-
-            var matchString = query.$.toLowerCase();
-
-            angular.forEach(array, function (row) {
-                var label = (row.schema + '.' + row.tbl).toLowerCase();
-
-                if (label.indexOf(matchString) >= 0)
-                    filtredArray.push(row);
-            });
-
-            return filtredArray;
-        } else
-            return array;
-    };
-});
-
 // Filter domain models with key fields configuration.
-consoleModule.filter('domainsValidation', ['$common', function ($common) {
+consoleModule.filter('domainsValidation', ['$common', function($common) {
     return function(domains, valid, invalid) {
         if (valid && invalid)
             return domains;
 
-        var out = [];
+        const out = [];
 
-        _.forEach(domains, function (domain) {
-            var _valid = !$common.domainForStoreConfigured(domain) || $common.isJavaBuiltInClass(domain.keyType) || !_.isEmpty(domain.keyFields);
+        _.forEach(domains, function(domain) {
+            const _valid = !$common.domainForStoreConfigured(domain) || $common.isJavaBuiltInClass(domain.keyType) || !_.isEmpty(domain.keyFields);
 
             if (valid && _valid || invalid && !_valid)
                 out.push(domain);
@@ -1504,7 +1488,7 @@ consoleModule.filter('domainsValidation', ['$common', function ($common) {
 consoleModule.directive('match', ['$parse', ($parse) => {
     return {
         require: 'ngModel',
-        link: (scope, elem, attrs, ctrl) => {
+        link(scope, elem, attrs, ctrl) {
             scope.$watch(() => $parse(attrs.match)(scope) === ctrl.$modelValue, (currentValue) => ctrl.$setValidity('mismatch', currentValue));
         }
     };
@@ -1512,13 +1496,11 @@ consoleModule.directive('match', ['$parse', ($parse) => {
 
 // Directive to bind ENTER key press with some user action.
 consoleModule.directive('onEnter', ['$timeout', ($timeout) => {
-    return function (scope, elem, attrs) {
-        elem.on('keydown keypress', function (event) {
+    return function(scope, elem, attrs) {
+        elem.on('keydown keypress', function(event) {
             if (event.which === 13) {
-                scope.$apply(function () {
-                    $timeout(function () {
-                        scope.$eval(attrs.onEnter)
-                    });
+                scope.$apply(function() {
+                    $timeout(() => scope.$eval(attrs.onEnter));
                 });
 
                 event.preventDefault();
@@ -1526,7 +1508,7 @@ consoleModule.directive('onEnter', ['$timeout', ($timeout) => {
         });
 
         // Removes bound events in the element itself when the scope is destroyed.
-        scope.$on('$destroy', function () {
+        scope.$on('$destroy', function() {
             elem.off('keydown keypress');
         });
     };
@@ -1534,10 +1516,10 @@ consoleModule.directive('onEnter', ['$timeout', ($timeout) => {
 
 // Directive to bind ESC key press with some user action.
 consoleModule.directive('onEscape', () => {
-    return function (scope, elem, attrs) {
-        elem.on('keydown keypress', function (event) {
+    return function(scope, elem, attrs) {
+        elem.on('keydown keypress', function(event) {
             if (event.which === 27) {
-                scope.$apply(function () {
+                scope.$apply(function() {
                     scope.$eval(attrs.onEscape);
                 });
 
@@ -1546,7 +1528,7 @@ consoleModule.directive('onEscape', () => {
         });
 
         // Removes bound events in the element itself when the scope is destroyed
-        scope.$on('$destroy', function () {
+        scope.$on('$destroy', function() {
             elem.off('keydown keypress');
         });
     };
@@ -1554,35 +1536,35 @@ consoleModule.directive('onEscape', () => {
 
 // Directive to retain selection. To fix angular-strap typeahead bug with setting cursor to the end of text.
 consoleModule.directive('retainSelection', ['$timeout', ($timeout) => {
-    var promise;
+    let promise;
 
-    return function (scope, elem) {
-        elem.on('keydown', function (evt) {
-            var key = evt.which;
-            var ctrlDown = evt.ctrlKey || evt.metaKey;
-            var input = this;
-            var start = input.selectionStart;
+    return function(scope, elem) {
+        elem.on('keydown', function(evt) {
+            const key = evt.which;
+            const ctrlDown = evt.ctrlKey || evt.metaKey;
+            const input = this;
+            let start = input.selectionStart;
 
             if (promise)
                 $timeout.cancel(promise);
 
-            promise = $timeout(function () {
-                var setCursor = false;
+            promise = $timeout(() => {
+                let setCursor = false;
 
                 // Handle Backspace[8].
-                if (key == 8 && start > 0) {
+                if (key === 8 && start > 0) {
                     start -= 1;
 
                     setCursor = true;
                 }
                 // Handle Del[46].
-                else if (key == 46)
+                else if (key === 46)
                     setCursor = true;
                 // Handle: Caps Lock[20], Tab[9], Shift[16], Ctrl[17], Alt[18], Esc[27], Enter[13], Arrows[37..40], Home[36], End[35], Ins[45], PgUp[33], PgDown[34], F1..F12[111..124], Num Lock[], Scroll Lock[145].
-                else if (!(key == 8 || key == 9 || key == 13 || (key > 15 && key < 20) || key == 27 ||
-                    (key > 32 && key < 41) || key == 45 || (key > 111 && key < 124) || key == 144 || key == 145)) {
+                else if (!(key === 8 || key === 9 || key === 13 || (key > 15 && key < 20) || key === 27 ||
+                    (key > 32 && key < 41) || key === 45 || (key > 111 && key < 124) || key === 144 || key === 145)) {
                     // Handle: Ctrl + [A[65], C[67], V[86]].
-                    if (!(ctrlDown && (key = 65 || key == 67 || key == 86))) {
+                    if (!(ctrlDown && (key === 65 || key === 67 || key === 86))) {
                         start += 1;
 
                         setCursor = true;
@@ -1592,12 +1574,12 @@ consoleModule.directive('retainSelection', ['$timeout', ($timeout) => {
                 if (setCursor)
                     input.setSelectionRange(start, start);
 
-                promise = undefined;
+                promise = null;
             });
         });
 
         // Removes bound events in the element itself when the scope is destroyed
-        scope.$on('$destroy', function () {
+        scope.$on('$destroy', function() {
             elem.off('keydown');
         });
     };
@@ -1605,12 +1587,12 @@ consoleModule.directive('retainSelection', ['$timeout', ($timeout) => {
 
 // Factory function to focus element.
 consoleModule.factory('$focus', ['$timeout', ($timeout) => {
-    return function (id) {
+    return function(id) {
         // Timeout makes sure that is invoked after any other event has been triggered.
         // E.g. click events that need to run before the focus or inputs elements that are
         // in a disabled state but are enabled when those events are triggered.
-        $timeout(function () {
-            var elem = $('#' + id);
+        $timeout(() => {
+            const elem = $('#' + id);
 
             if (elem.length > 0)
                 elem[0].focus();
@@ -1622,18 +1604,16 @@ consoleModule.factory('$focus', ['$timeout', ($timeout) => {
 consoleModule.directive('autoFocus', ['$timeout', ($timeout) => {
     return {
         restrict: 'AC',
-        link: function(scope, element) {
-            $timeout(function(){
-                element[0].focus();
-            });
+        link(scope, element) {
+            $timeout(() => element[0].focus());
         }
     };
 }]);
 
 // Directive to focus next element on ENTER key.
 consoleModule.directive('enterFocusNext', ['$focus', ($focus) => {
-    return function (scope, elem, attrs) {
-        elem.on('keydown keypress', function (event) {
+    return function(scope, elem, attrs) {
+        elem.on('keydown keypress', function(event) {
             if (event.which === 13) {
                 event.preventDefault();
 
@@ -1645,13 +1625,13 @@ consoleModule.directive('enterFocusNext', ['$focus', ($focus) => {
 
 // Directive to mark elements to focus.
 consoleModule.directive('onClickFocus', ['$focus', ($focus) => {
-    return function (scope, elem, attr) {
-        elem.on('click', function () {
+    return function(scope, elem, attr) {
+        elem.on('click', function() {
             $focus(attr.onClickFocus);
         });
 
         // Removes bound events in the element itself when the scope is destroyed
-        scope.$on('$destroy', function () {
+        scope.$on('$destroy', function() {
             elem.off('click');
         });
     };
@@ -1660,9 +1640,9 @@ consoleModule.directive('onClickFocus', ['$focus', ($focus) => {
 consoleModule.controller('resetPassword', [
     '$scope', '$modal', '$http', '$common', '$focus', 'Auth', '$state',
     ($scope, $modal, $http, $common, $focus, Auth, $state) => {
-        if ($state.params.token)
+        if ($state.params.token) {
             $http.post('/api/v1/password/validate/token', {token: $state.params.token})
-                .success(function (res) {
+                .success((res) => {
                     $scope.email = res.email;
                     $scope.token = res.token;
                     $scope.error = res.error;
@@ -1670,16 +1650,17 @@ consoleModule.controller('resetPassword', [
                     if ($scope.token && !$scope.error)
                         $focus('user_password');
                 });
+        }
 
         // Try to reset user password for provided token.
-        $scope.resetPassword = function (reset_info) {
+        $scope.resetPassword = function(reset_info) {
             $http.post('/api/v1/password/reset', reset_info)
-                .success(function () {
+                .success(function() {
                     $common.showInfo('Password successfully changed');
 
                     $state.go('base.configuration.clusters');
                 })
-                .error(function (data, state) {
+                .error(function(data, state) {
                     $common.showError(data);
 
                     if (state === 503)
@@ -1693,7 +1674,7 @@ consoleModule.controller('resetPassword', [
 // TODO IGNITE-1936 Refactor this controller.
 consoleModule.controller('auth', ['$scope', '$focus', 'Auth', 'IgniteCountries', ($scope, $focus, Auth, Countries) => {
     $scope.auth = Auth.auth;
-
+    $scope.forgotPassword = Auth.forgotPassword;
     $scope.action = 'signin';
     $scope.countries = Countries.getAll();
 
@@ -1703,57 +1684,58 @@ consoleModule.controller('auth', ['$scope', '$focus', 'Auth', 'IgniteCountries',
 // Navigation bar controller.
 consoleModule.controller('notebooks', ['$rootScope', '$scope', '$modal', '$state', '$http', '$common',
     ($root, $scope, $modal, $state, $http, $common) => {
-    $root.notebooks = [];
+        $root.notebooks = [];
 
-    // Pre-fetch modal dialogs.
-    var _notebookNewModal = $modal({scope: $scope, templateUrl: '/sql/notebook-new.html', show: false});
+        // Pre-fetch modal dialogs.
+        const _notebookNewModal = $modal({scope: $scope, templateUrl: '/sql/notebook-new.html', show: false});
 
-    $root.rebuildDropdown = function() {
-        $scope.notebookDropdown = [
-            {text: 'Create new notebook', click: 'inputNotebookName()'},
-            {divider: true}
-        ];
+        $root.rebuildDropdown = function() {
+            $scope.notebookDropdown = [
+                {text: 'Create new notebook', click: 'inputNotebookName()'},
+                {divider: true}
+            ];
 
-        _.forEach($root.notebooks, function (notebook) {
-            $scope.notebookDropdown.push({
-                text: notebook.name,
-                sref: 'base.sql.notebook({noteId:"' + notebook._id + '"})'
+            _.forEach($root.notebooks, function(notebook) {
+                $scope.notebookDropdown.push({
+                    text: notebook.name,
+                    sref: 'base.sql.notebook({noteId:"' + notebook._id + '"})'
+                });
             });
-        });
-    };
+        };
 
-    $root.reloadNotebooks = function() {
-        // When landing on the page, get clusters and show them.
-        $http.post('/api/v1/notebooks/list')
-            .success(function (data) {
-                $root.notebooks = data;
+        $root.reloadNotebooks = function() {
+            // When landing on the page, get clusters and show them.
+            $http.post('/api/v1/notebooks/list')
+                .success(function(data) {
+                    $root.notebooks = data;
 
-                $root.rebuildDropdown();
-            })
-            .error(function (errMsg) {
-                $common.showError(errMsg);
-            });
-    };
+                    $root.rebuildDropdown();
+                })
+                .error(function(errMsg) {
+                    $common.showError(errMsg);
+                });
+        };
 
-    $root.inputNotebookName = function() {
-        _notebookNewModal.$promise.then(_notebookNewModal.show);
-    };
+        $root.inputNotebookName = function() {
+            _notebookNewModal.$promise.then(_notebookNewModal.show);
+        };
 
-    $root.createNewNotebook = function(name) {
-        $http.post('/api/v1/notebooks/new', {name: name})
-            .success(function (noteId) {
-                _notebookNewModal.hide();
+        $root.createNewNotebook = function(name) {
+            $http.post('/api/v1/notebooks/new', {name})
+                .success(function(noteId) {
+                    _notebookNewModal.hide();
 
-                $root.reloadNotebooks();
+                    $root.reloadNotebooks();
 
-                $state.go('base.sql.notebook', {noteId: noteId});
-            })
-            .error(function (message) {
-                $common.showError(message);
-            });
-    };
+                    $state.go('base.sql.notebook', {noteId});
+                })
+                .error(function(message) {
+                    $common.showError(message);
+                });
+        };
 
-    $root.reloadNotebooks();
-}]);
+        $root.reloadNotebooks();
+    }
+]);
 
 export default consoleModule;


[13/50] [abbrv] ignite git commit: Merge remote-tracking branch 'upstream/gridgain-7.6.1' into gridgain-7.6.1

Posted by sb...@apache.org.
Merge remote-tracking branch 'upstream/gridgain-7.6.1' into gridgain-7.6.1


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3ca0bc87
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3ca0bc87
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3ca0bc87

Branch: refs/heads/ignite-1232
Commit: 3ca0bc877bf356eca93c9c9a5e225362c2b58769
Parents: 68b25df 482015e
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Tue Jun 21 17:11:37 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Tue Jun 21 17:11:37 2016 +0300

----------------------------------------------------------------------
 modules/clients/pom.xml                         |    8 -
 .../client/ClientDefaultCacheSelfTest.java      |  119 +-
 .../ignite/internal/client/ClientHttpTask.java  |   33 +-
 .../ignite/internal/client/ClientTcpTask.java   |   10 +-
 .../integration/ClientAbstractSelfTest.java     |   92 +-
 .../JettyRestProcessorAbstractSelfTest.java     | 1018 ++++++++----------
 .../internal/processors/rest/SimplePerson.java  |   74 ++
 modules/core/pom.xml                            |   15 +-
 .../apache/ignite/internal/LessNamingBean.java  |   28 +
 .../ignite/internal/MarshallerContextImpl.java  |   29 +-
 .../cache/query/GridCacheSqlIndexMetadata.java  |    3 +-
 .../cache/query/GridCacheSqlMetadata.java       |    3 +-
 .../internal/util/IgniteExceptionRegistry.java  |    5 +-
 .../ignite/internal/visor/cache/VisorCache.java |    4 +-
 .../cache/VisorCacheAffinityConfiguration.java  |    5 +-
 .../cache/VisorCacheAggregatedMetrics.java      |    3 +-
 .../visor/cache/VisorCacheConfiguration.java    |    3 +-
 .../cache/VisorCacheDefaultConfiguration.java   |    5 +-
 .../cache/VisorCacheEvictionConfiguration.java  |    5 +-
 .../internal/visor/cache/VisorCacheMetrics.java |    3 +-
 .../cache/VisorCacheNearConfiguration.java      |    5 +-
 .../visor/cache/VisorCachePartition.java        |    3 +-
 .../visor/cache/VisorCachePartitions.java       |    3 +-
 .../cache/VisorCacheQueryConfiguration.java     |    3 +-
 .../visor/cache/VisorCacheQueryMetrics.java     |    5 +-
 .../cache/VisorCacheRebalanceConfiguration.java |    5 +-
 .../cache/VisorCacheStoreConfiguration.java     |    3 +-
 .../cache/VisorCacheTypeFieldMetadata.java      |    3 +-
 .../visor/cache/VisorCacheTypeMetadata.java     |    3 +-
 .../internal/visor/cache/VisorCacheV4.java      |  124 +++
 .../internal/visor/debug/VisorThreadInfo.java   |    5 +-
 .../visor/debug/VisorThreadLockInfo.java        |    5 +-
 .../internal/visor/event/VisorGridEvent.java    |    5 +-
 .../internal/visor/file/VisorFileBlock.java     |    5 +-
 .../ignite/internal/visor/igfs/VisorIgfs.java   |    5 +-
 .../internal/visor/igfs/VisorIgfsEndpoint.java  |    5 +-
 .../internal/visor/igfs/VisorIgfsMetrics.java   |    5 +-
 .../visor/igfs/VisorIgfsProfilerEntry.java      |    5 +-
 .../VisorIgfsProfilerUniformityCounters.java    |    5 +-
 .../visor/log/VisorLogSearchResult.java         |    5 +-
 .../visor/node/VisorAtomicConfiguration.java    |    5 +-
 .../visor/node/VisorBasicConfiguration.java     |    5 +-
 .../node/VisorExecutorServiceConfiguration.java |    5 +-
 .../visor/node/VisorGridConfiguration.java      |    5 +-
 .../visor/node/VisorIgfsConfiguration.java      |    3 +-
 .../visor/node/VisorLifecycleConfiguration.java |    5 +-
 .../visor/node/VisorMetricsConfiguration.java   |    5 +-
 .../visor/node/VisorNodeDataCollectorJob.java   |   26 +-
 .../node/VisorNodeDataCollectorTaskResult.java  |    5 +-
 .../node/VisorPeerToPeerConfiguration.java      |    5 +-
 .../visor/node/VisorRestConfiguration.java      |    5 +-
 .../node/VisorSegmentationConfiguration.java    |    5 +-
 .../visor/node/VisorSpisConfiguration.java      |    5 +-
 .../node/VisorTransactionConfiguration.java     |    5 +-
 .../internal/visor/query/VisorQueryField.java   |    5 +-
 .../internal/visor/query/VisorQueryResult.java  |    5 +-
 .../plugin/security/SecurityPermissionSet.java  |    5 +-
 .../ignite/plugin/security/SecuritySubject.java |    5 +-
 modules/rest-http/pom.xml                       |   25 +-
 .../http/jetty/GridJettyJsonConfig.java         |  317 ------
 .../http/jetty/GridJettyObjectMapper.java       |  274 +++++
 .../http/jetty/GridJettyRestHandler.java        |  127 +--
 .../IgniteCacheRandomOperationBenchmark.java    |  539 +++++-----
 .../cache/load/model/key/Identifier.java        |    6 +
 .../yardstick/cache/load/model/key/Mark.java    |    7 +
 .../yardstick/cache/load/model/value/Car.java   |    6 +
 .../yardstick/cache/load/model/value/Truck.java |   12 +-
 .../ignite/yardstick/cache/model/Account.java   |    6 +
 .../ignite/yardstick/cache/model/Person1.java   |    2 +-
 .../ignite/yardstick/cache/model/Person2.java   |    2 +-
 .../ignite/yardstick/cache/model/SampleKey.java |    2 +-
 .../yardstick/cache/model/SampleValue.java      |    2 +-
 .../zk/TcpDiscoveryZookeeperIpFinder.java       |   19 +-
 parent/pom.xml                                  |    1 +
 74 files changed, 1673 insertions(+), 1455 deletions(-)
----------------------------------------------------------------------



[09/50] [abbrv] ignite git commit: Merge branch 'gridgain-7.6.1' of https://github.com/gridgain/apache-ignite

Posted by sb...@apache.org.
Merge branch 'gridgain-7.6.1' of https://github.com/gridgain/apache-ignite


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/766c89ef
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/766c89ef
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/766c89ef

Branch: refs/heads/ignite-1232
Commit: 766c89efd4080dd880187dfdd5b46332e23fa855
Parents: 848b027 0c5db20
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Tue Jun 21 15:10:14 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Tue Jun 21 15:10:14 2016 +0700

----------------------------------------------------------------------
 modules/clients/pom.xml | 8 --------
 1 file changed, 8 deletions(-)
----------------------------------------------------------------------



[21/50] [abbrv] ignite git commit: IGNITE-3354: IGFS: Fixed (removed) max space validation logic.

Posted by sb...@apache.org.
IGNITE-3354: IGFS: Fixed (removed) max space validation logic.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/5e915944
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/5e915944
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/5e915944

Branch: refs/heads/ignite-1232
Commit: 5e9159449b7b7704cfec7c82c846badf7689df43
Parents: 212dc06
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Wed Jun 22 17:27:13 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Wed Jun 22 17:29:56 2016 +0300

----------------------------------------------------------------------
 .../internal/processors/igfs/IgfsProcessor.java | 24 ------------------
 .../igfs/IgfsProcessorValidationSelfTest.java   | 26 --------------------
 2 files changed, 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5e915944/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsProcessor.java
index 6df9986..85dcb1c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsProcessor.java
@@ -38,7 +38,6 @@ import org.apache.ignite.internal.util.ipc.IpcServerEndpoint;
 import org.apache.ignite.internal.util.typedef.C1;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.X;
-import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteClosure;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
@@ -57,7 +56,6 @@ import java.util.concurrent.ConcurrentMap;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK;
 import static org.apache.ignite.IgniteSystemProperties.getBoolean;
 import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
-import static org.apache.ignite.cache.CacheMemoryMode.OFFHEAP_VALUES;
 import static org.apache.ignite.igfs.IgfsMode.PROXY;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_IGFS;
 
@@ -346,28 +344,6 @@ public class IgfsProcessor extends IgfsProcessorAdapter {
                         ipcCfg.getThreadCount());
             }
 
-            long maxSpaceSize = cfg.getMaxSpaceSize();
-
-            if (maxSpaceSize > 0) {
-                // Max space validation.
-                long maxHeapSize = Runtime.getRuntime().maxMemory();
-                long offHeapSize = dataCacheCfg.getOffHeapMaxMemory();
-
-                if (offHeapSize < 0 && maxSpaceSize > maxHeapSize)
-                    // Offheap is disabled.
-                    throw new IgniteCheckedException("Maximum IGFS space size cannot be greater that size of available heap " +
-                        "memory [maxHeapSize=" + maxHeapSize + ", maxIgfsSpaceSize=" + maxSpaceSize + ']');
-                else if (offHeapSize > 0 && maxSpaceSize > maxHeapSize + offHeapSize)
-                    // Offheap is enabled, but limited.
-                    throw new IgniteCheckedException("Maximum IGFS space size cannot be greater than size of available heap " +
-                        "memory and offheap storage [maxHeapSize=" + maxHeapSize + ", offHeapSize=" + offHeapSize +
-                        ", maxIgfsSpaceSize=" + maxSpaceSize + ']');
-            }
-
-            if (cfg.getMaxSpaceSize() == 0 && dataCacheCfg.getMemoryMode() == OFFHEAP_VALUES)
-                U.warn(log, "IGFS max space size is not specified but data cache values are stored off-heap (max " +
-                    "space will be limited to 80% of max JVM heap size): " + cfg.getName());
-
             boolean secondary = cfg.getDefaultMode() == PROXY;
 
             if (cfg.getPathModes() != null) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/5e915944/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsProcessorValidationSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsProcessorValidationSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsProcessorValidationSelfTest.java
index 29bb2cd..97334da 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsProcessorValidationSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsProcessorValidationSelfTest.java
@@ -228,32 +228,6 @@ public class IgfsProcessorValidationSelfTest extends IgfsCommonAbstractTest {
     /**
      * @throws Exception If failed.
      */
-    public void testLocalIfOffheapIsDisabledAndMaxSpaceSizeIsGreater() throws Exception {
-        g1Cfg.setCacheConfiguration(concat(dataCaches(1024), metaCaches(), CacheConfiguration.class));
-
-        g1IgfsCfg2.setMaxSpaceSize(999999999999999999L);
-
-        checkGridStartFails(g1Cfg, "Maximum IGFS space size cannot be greater that size of available heap", true);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testLocalIfOffheapIsEnabledAndMaxSpaceSizeIsGreater() throws Exception {
-        g1Cfg.setCacheConfiguration(concat(dataCaches(1024), metaCaches(), CacheConfiguration.class));
-
-        for (CacheConfiguration cc : g1Cfg.getCacheConfiguration())
-            cc.setOffHeapMaxMemory(1000000);
-
-        g1IgfsCfg2.setMaxSpaceSize(999999999999999999L);
-
-        checkGridStartFails(g1Cfg,
-            "Maximum IGFS space size cannot be greater than size of available heap memory and offheap storage", true);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
     public void testLocalIfNonPrimaryModeAndHadoopFileSystemUriIsNull() throws Exception {
         g1Cfg.setCacheConfiguration(concat(dataCaches(1024), metaCaches(), CacheConfiguration.class));
 


[29/50] [abbrv] ignite git commit: IGNITE-3328 .NET: Support user-defined AffinityFunction

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityTopologyVersion.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityTopologyVersion.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityTopologyVersion.cs
new file mode 100644
index 0000000..9bfdfb4
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityTopologyVersion.cs
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Cache.Affinity
+{
+    using System;
+    using Apache.Ignite.Core.Cluster;
+
+    /// <summary>
+    /// Affinity topology version.
+    /// </summary>
+    public struct AffinityTopologyVersion : IEquatable<AffinityTopologyVersion>
+    {
+        /** */
+        private readonly long _version;
+
+        /** */
+        private readonly int _minorVersion;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="AffinityTopologyVersion"/> struct.
+        /// </summary>
+        /// <param name="version">The version.</param>
+        /// <param name="minorVersion">The minor version.</param>
+        public AffinityTopologyVersion(long version, int minorVersion)
+        {
+            _version = version;
+            _minorVersion = minorVersion;
+        }
+
+        /// <summary>
+        /// Gets the major version, same as <see cref="ICluster.TopologyVersion"/>.
+        /// </summary>
+        public long Version
+        {
+            get { return _version; }
+        }
+
+        /// <summary>
+        /// Gets the minor version, which is increased when new caches start.
+        /// </summary>
+        public int MinorVersion
+        {
+            get { return _minorVersion; }
+        }
+
+        /// <summary>
+        /// Indicates whether the current object is equal to another object of the same type.
+        /// </summary>
+        /// <param name="other">An object to compare with this object.</param>
+        /// <returns>
+        /// true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.
+        /// </returns>
+        public bool Equals(AffinityTopologyVersion other)
+        {
+            return _version == other._version && _minorVersion == other._minorVersion;
+        }
+
+        /// <summary>
+        /// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
+        /// </summary>
+        /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
+        /// <returns>
+        /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, 
+        /// <c>false</c>.
+        /// </returns>
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            return obj is AffinityTopologyVersion && Equals((AffinityTopologyVersion) obj);
+        }
+
+        /// <summary>
+        /// Returns a hash code for this instance.
+        /// </summary>
+        /// <returns>
+        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
+        /// </returns>
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                return (_version.GetHashCode()*397) ^ _minorVersion;
+            }
+        }
+
+        /// <summary>
+        /// Implements the operator ==.
+        /// </summary>
+        /// <param name="left">The left.</param>
+        /// <param name="right">The right.</param>
+        /// <returns>
+        /// The result of the operator.
+        /// </returns>
+        public static bool operator ==(AffinityTopologyVersion left, AffinityTopologyVersion right)
+        {
+            return left.Equals(right);
+        }
+
+        /// <summary>
+        /// Implements the operator !=.
+        /// </summary>
+        /// <param name="left">The left.</param>
+        /// <param name="right">The right.</param>
+        /// <returns>
+        /// The result of the operator.
+        /// </returns>
+        public static bool operator !=(AffinityTopologyVersion left, AffinityTopologyVersion right)
+        {
+            return !left.Equals(right);
+        }
+
+        /// <summary>
+        /// Returns a <see cref="string" /> that represents this instance.
+        /// </summary>
+        /// <returns>
+        /// A <see cref="string" /> that represents this instance.
+        /// </returns>
+        public override string ToString()
+        {
+            return string.Format("AffinityTopologyVersion [Version={0}, MinorVersion={1}]", _version, _minorVersion);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/IAffinityFunction.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/IAffinityFunction.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/IAffinityFunction.cs
index 1eb00db..b6c190c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/IAffinityFunction.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/IAffinityFunction.cs
@@ -17,19 +17,66 @@
 
 namespace Apache.Ignite.Core.Cache.Affinity
 {
-    using System.Diagnostics.CodeAnalysis;
+    using System;
+    using System.Collections.Generic;
     using Apache.Ignite.Core.Cache.Affinity.Fair;
     using Apache.Ignite.Core.Cache.Affinity.Rendezvous;
+    using Apache.Ignite.Core.Cluster;
 
     /// <summary>
     /// Represents a function that maps cache keys to cluster nodes.
     /// <para />
-    /// Only predefined implementations are supported now: 
+    /// Predefined implementations: 
     /// <see cref="RendezvousAffinityFunction"/>, <see cref="FairAffinityFunction"/>.
     /// </summary>
-    [SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces")]
     public interface IAffinityFunction
     {
-        // No-op.
+        /// <summary>
+        /// Gets the total number of partitions.
+        /// <para />
+        /// All caches should always provide correct partition count which should be the same on all 
+        /// participating nodes. Note that partitions should always be numbered from 0 inclusively 
+        /// to N exclusively without any gaps.
+        /// </summary>
+        int Partitions { get; }
+
+        /// <summary>
+        /// Gets partition number for a given key starting from 0. Partitioned caches
+        /// should make sure that keys are about evenly distributed across all partitions
+        /// from 0 to <see cref="Partitions"/> for best performance.
+        /// <para />
+        /// Note that for fully replicated caches it is possible to segment key sets among different
+        /// grid node groups. In that case each node group should return a unique partition
+        /// number. However, unlike partitioned cache, mappings of keys to nodes in
+        /// replicated caches are constant and a node cannot migrate from one partition
+        /// to another.
+        /// </summary>
+        /// <param name="key">Key to get partition for.</param>
+        /// <returns>Partition number for a given key.</returns>
+        int GetPartition(object key);
+
+        /// <summary>
+        /// Removes node from affinity. This method is called when it is safe to remove 
+        /// disconnected node from affinity mapping.
+        /// </summary>
+        /// <param name="nodeId">The node identifier.</param>
+        void RemoveNode(Guid nodeId);
+
+        /// <summary>
+        /// Gets affinity nodes for a partition. In case of replicated cache, all returned
+        /// nodes are updated in the same manner. In case of partitioned cache, the returned
+        /// list should contain only the primary and back up nodes with primary node being
+        /// always first.
+        /// <pare />
+        /// Note that partitioned affinity must obey the following contract: given that node
+        /// <code>N</code> is primary for some key <code>K</code>, if any other node(s) leave
+        /// grid and no node joins grid, node <code>N</code> will remain primary for key <code>K</code>.
+        /// </summary>
+        /// <param name="context">The affinity function context.</param>
+        /// <returns>
+        /// A collection of partitions, where each partition is a collection of nodes,
+        /// where first node is a primary node, and other nodes are backup nodes.
+        /// </returns>
+        IEnumerable<IEnumerable<IClusterNode>> AssignPartitions(AffinityFunctionContext context);
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs
index 6b37895..54f4753 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/CacheConfiguration.cs
@@ -28,6 +28,8 @@ namespace Apache.Ignite.Core.Cache.Configuration
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cache;
     using Apache.Ignite.Core.Cache.Affinity;
+    using Apache.Ignite.Core.Cache.Affinity.Fair;
+    using Apache.Ignite.Core.Cache.Affinity.Rendezvous;
     using Apache.Ignite.Core.Cache.Eviction;
     using Apache.Ignite.Core.Cache.Store;
     using Apache.Ignite.Core.Common;
@@ -277,7 +279,7 @@ namespace Apache.Ignite.Core.Cache.Configuration
         }
 
         /// <summary>
-        /// Writes this instane to the specified writer.
+        /// Writes this instance to the specified writer.
         /// </summary>
         /// <param name="writer">The writer.</param>
         internal void Write(IBinaryRawWriter writer)
@@ -589,7 +591,7 @@ namespace Apache.Ignite.Core.Cache.Configuration
         public bool ReadFromBackup { get; set; }
 
         /// <summary>
-        /// Gets or sets flag indicating whether copy of of the value stored in cache should be created
+        /// Gets or sets flag indicating whether copy of the value stored in cache should be created
         /// for cache operation implying return value. 
         /// </summary>
         [DefaultValue(DefaultCopyOnRead)]
@@ -665,6 +667,9 @@ namespace Apache.Ignite.Core.Cache.Configuration
 
         /// <summary>
         /// Gets or sets the affinity function to provide mapping from keys to nodes.
+        /// <para />
+        /// Predefined implementations: 
+        /// <see cref="RendezvousAffinityFunction"/>, <see cref="FairAffinityFunction"/>.
         /// </summary>
         public IAffinityFunction AffinityFunction { get; set; }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/Events/EventBase.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Events/EventBase.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Events/EventBase.cs
index ed60332..4992266 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Events/EventBase.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Events/EventBase.cs
@@ -195,7 +195,7 @@ namespace Apache.Ignite.Core.Events
         public override string ToString()
         {
             return string.Format(CultureInfo.InvariantCulture, 
-                "CacheEntry [Name={0}, Type={1}, Timestamp={2}, Message={3}]", Name, Type, Timestamp, Message);
+                "{0} [Name={1}, Type={2}, Timestamp={3}, Message={4}]", GetType().Name, Name, Type, Timestamp, Message);
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/Events/EventReader.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Events/EventReader.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Events/EventReader.cs
index cb1c715..ee1c837 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Events/EventReader.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Events/EventReader.cs
@@ -32,16 +32,14 @@ namespace Apache.Ignite.Core.Events
         /// <param name="reader">Reader.</param>
         /// <returns>Deserialized event.</returns>
         /// <exception cref="System.InvalidCastException">Incompatible event type.</exception>
-        public static T Read<T>(IBinaryReader reader) where T : IEvent
+        public static T Read<T>(IBinaryRawReader reader) where T : IEvent
         {
-            var r = reader.GetRawReader();
-
-            var clsId = r.ReadInt();
+            var clsId = reader.ReadInt();
 
             if (clsId == -1)
                 return default(T);
 
-            return (T) CreateInstance(clsId, r);
+            return (T) CreateInstance(clsId, reader);
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs
index 6bdf1ab..69a2f6a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs
@@ -37,6 +37,7 @@
     using Apache.Ignite.Core.Impl;
     using Apache.Ignite.Core.Impl.Binary;
     using Apache.Ignite.Core.Impl.Common;
+    using Apache.Ignite.Core.Impl.Handle;
     using Apache.Ignite.Core.Lifecycle;
     using Apache.Ignite.Core.Transactions;
     using BinaryReader = Apache.Ignite.Core.Impl.Binary.BinaryReader;

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd
index 68fd5bf..24eaa30 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd
@@ -33,7 +33,7 @@
                             <xs:element name="typeConfigurations" minOccurs="0">
                                 <xs:complexType>
                                     <xs:sequence>
-                                        <xs:element name="binaryTypeConfiguration">
+                                        <xs:element name="binaryTypeConfiguration" maxOccurs="unbounded">
                                             <xs:complexType>
                                                 <xs:all>
                                                     <xs:element name="nameMapper" minOccurs="0">
@@ -191,7 +191,7 @@
                                         </xs:element>
                                         <xs:element name="affinityFunction" minOccurs="0">
                                             <xs:complexType>
-                                                <xs:attribute name="partitionCount" type="xs:int" />
+                                                <xs:attribute name="partitions" type="xs:int" />
                                                 <xs:attribute name="excludeNeighbors" type="xs:boolean" />
                                                 <xs:attribute name="type" type="xs:string" use="required" />
                                             </xs:complexType>

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
index 7dc103c..a22c9d0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
@@ -272,7 +272,7 @@ namespace Apache.Ignite.Core
         }
 
         /// <summary>
-        /// Preapare configuration.
+        /// Prepare configuration.
         /// </summary>
         /// <param name="reader">Reader.</param>
         /// <param name="outStream">Response stream.</param>
@@ -706,7 +706,7 @@ namespace Apache.Ignite.Core
             /** <inheritdoc /> */
             public void OnLifecycleEvent(LifecycleEventType evt)
             {
-                if (evt == LifecycleEventType.BeforeNodeStop)
+                if (evt == LifecycleEventType.BeforeNodeStop && _ignite != null)
                     ((IgniteProxy) _ignite).Target.BeforeNodeStop();
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs
index fb52033..51d9c74 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbackHandlers.cs
@@ -98,5 +98,11 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
 
         internal void* onClientDisconnected;
         internal void* ocClientReconnected;
+
+        internal void* affinityFunctionInit;
+        internal void* affinityFunctionPartition;
+        internal void* affinityFunctionAssignPartitions;
+        internal void* affinityFunctionRemoveNode;
+        internal void* affinityFunctionDestroy;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
index f0e881c..89ed838 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
@@ -21,9 +21,10 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
     using System.Collections.Generic;
     using System.Diagnostics;
     using System.Diagnostics.CodeAnalysis;
+    using System.IO;
     using System.Runtime.InteropServices;
     using System.Threading;
-
+    using Apache.Ignite.Core.Cache.Affinity;
     using Apache.Ignite.Core.Cluster;
     using Apache.Ignite.Core.Common;
     using Apache.Ignite.Core.Impl.Binary;
@@ -165,6 +166,12 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
         private delegate void OnClientDisconnectedDelegate(void* target);
         private delegate void OnClientReconnectedDelegate(void* target, bool clusterRestarted);
 
+        private delegate long AffinityFunctionInitDelegate(void* target, long memPtr);
+        private delegate int AffinityFunctionPartitionDelegate(void* target, long ptr, long memPtr);
+        private delegate void AffinityFunctionAssignPartitionsDelegate(void* target, long ptr, long inMemPtr, long outMemPtr);
+        private delegate void AffinityFunctionRemoveNodeDelegate(void* target, long ptr, long memPtr);
+        private delegate void AffinityFunctionDestroyDelegate(void* target, long ptr);
+
         /// <summary>
         /// constructor.
         /// </summary>
@@ -248,6 +255,12 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
 
                 onClientDisconnected = CreateFunctionPointer((OnClientDisconnectedDelegate)OnClientDisconnected),
                 ocClientReconnected = CreateFunctionPointer((OnClientReconnectedDelegate)OnClientReconnected),
+
+                affinityFunctionInit = CreateFunctionPointer((AffinityFunctionInitDelegate)AffinityFunctionInit),
+                affinityFunctionPartition = CreateFunctionPointer((AffinityFunctionPartitionDelegate)AffinityFunctionPartition),
+                affinityFunctionAssignPartitions = CreateFunctionPointer((AffinityFunctionAssignPartitionsDelegate)AffinityFunctionAssignPartitions),
+                affinityFunctionRemoveNode = CreateFunctionPointer((AffinityFunctionRemoveNodeDelegate)AffinityFunctionRemoveNode),
+                affinityFunctionDestroy = CreateFunctionPointer((AffinityFunctionDestroyDelegate)AffinityFunctionDestroy)
             };
 
             _cbsPtr = Marshal.AllocHGlobal(UU.HandlersSize());
@@ -1089,6 +1102,111 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
 
         #endregion
 
+        #region AffinityFunction
+
+        private long AffinityFunctionInit(void* target, long memPtr)
+        {
+            return SafeCall(() =>
+            {
+                using (var stream = IgniteManager.Memory.Get(memPtr).GetStream())
+                {
+                    var func = _ignite.Marshaller.Unmarshal<IAffinityFunction>(stream);
+
+                    ResourceProcessor.Inject(func, _ignite);
+
+                    return _handleRegistry.Allocate(func);
+                }
+            });
+        }
+
+        private int AffinityFunctionPartition(void* target, long ptr, long memPtr)
+        {
+            return SafeCall(() =>
+            {
+                using (var stream = IgniteManager.Memory.Get(memPtr).GetStream())
+                {
+                    var key = _ignite.Marshaller.Unmarshal<object>(stream);
+
+                    return _handleRegistry.Get<IAffinityFunction>(ptr, true).GetPartition(key);
+                }
+            });
+        }
+
+        private void AffinityFunctionAssignPartitions(void* target, long ptr, long inMemPtr, long outMemPtr)
+        {
+            SafeCall(() =>
+            {
+                using (var inStream = IgniteManager.Memory.Get(inMemPtr).GetStream())
+                {
+                    var ctx = new AffinityFunctionContext(_ignite.Marshaller.StartUnmarshal(inStream));
+                    var func = _handleRegistry.Get<IAffinityFunction>(ptr, true);
+                    var parts = func.AssignPartitions(ctx);
+
+                    if (parts == null)
+                        throw new IgniteException(func.GetType() + ".AssignPartitions() returned invalid result: null");
+
+                    using (var outStream = IgniteManager.Memory.Get(outMemPtr).GetStream())
+                    {
+                        var writer = _ignite.Marshaller.StartMarshal(outStream);
+
+                        var partCnt = 0;
+                        writer.WriteInt(partCnt);  // reserve size
+
+                        foreach (var part in parts)
+                        {
+                            if (part == null)
+                                throw new IgniteException(func.GetType() +
+                                                          ".AssignPartitions() returned invalid partition: null");
+
+                            partCnt++;
+
+                            var nodeCnt = 0;
+                            var cntPos = outStream.Position;
+                            writer.WriteInt(nodeCnt);  // reserve size
+
+                            foreach (var node in part)
+                            {
+                                nodeCnt++;
+                                writer.WriteGuid(node.Id);
+                            }
+
+                            var endPos = outStream.Position;
+                            outStream.Seek(cntPos, SeekOrigin.Begin);
+                            outStream.WriteInt(nodeCnt);
+                            outStream.Seek(endPos, SeekOrigin.Begin);
+                        }
+
+                        outStream.SynchronizeOutput();
+                        outStream.Seek(0, SeekOrigin.Begin);
+                        writer.WriteInt(partCnt);
+                    }
+                }
+            });
+        }
+
+        private void AffinityFunctionRemoveNode(void* target, long ptr, long memPtr)
+        {
+            SafeCall(() =>
+            {
+                using (var stream = IgniteManager.Memory.Get(memPtr).GetStream())
+                {
+                    var nodeId = _ignite.Marshaller.Unmarshal<Guid>(stream);
+
+                    _handleRegistry.Get<IAffinityFunction>(ptr, true).RemoveNode(nodeId);
+                }
+            });
+        }
+
+        private void AffinityFunctionDestroy(void* target, long ptr)
+        {
+            SafeCall(() =>
+            {
+                _handleRegistry.Release(ptr);
+            });
+        }
+
+        #endregion
+
         #region HELPERS
 
         [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings b/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings
index 187a909..ac065bc 100644
--- a/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings
+++ b/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings
@@ -1,4 +1,5 @@
 \ufeff<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
-	<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AddImportsToDeepestScope/@EntryValue">True</s:Boolean>
-	
-	<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/QualifiedUsingAtNestedScope/@EntryValue">True</s:Boolean></wpf:ResourceDictionary>
\ No newline at end of file
+	<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp50</s:String>
+	<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AddImportsToDeepestScope/@EntryValue">True</s:Boolean>	
+	<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/QualifiedUsingAtNestedScope/@EntryValue">True</s:Boolean>
+</wpf:ResourceDictionary>
\ No newline at end of file


[05/50] [abbrv] ignite git commit: IGNITE-3277 Replaced outdated json-lib 2.4 to modern Jackson 2.7.5.

Posted by sb...@apache.org.
IGNITE-3277 Replaced outdated json-lib 2.4 to modern Jackson 2.7.5.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f177d431
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f177d431
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f177d431

Branch: refs/heads/ignite-1232
Commit: f177d4312c47cd31e4931c8c1e0f89c2325dedb1
Parents: 106b869
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Tue Jun 21 11:45:29 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Tue Jun 21 11:45:29 2016 +0700

----------------------------------------------------------------------
 .../client/ClientDefaultCacheSelfTest.java      | 119 ++-
 .../ignite/internal/client/ClientHttpTask.java  |  33 +-
 .../ignite/internal/client/ClientTcpTask.java   |  10 +-
 .../integration/ClientAbstractSelfTest.java     |  92 +-
 .../JettyRestProcessorAbstractSelfTest.java     | 985 ++++++++-----------
 .../internal/processors/rest/SimplePerson.java  |  74 ++
 modules/core/pom.xml                            |  15 +-
 .../apache/ignite/internal/LessNamingBean.java  |  28 +
 .../cache/query/GridCacheSqlIndexMetadata.java  |   3 +-
 .../cache/query/GridCacheSqlMetadata.java       |   3 +-
 .../internal/util/IgniteExceptionRegistry.java  |   5 +-
 .../ignite/internal/visor/cache/VisorCache.java |   4 +-
 .../cache/VisorCacheAffinityConfiguration.java  |   5 +-
 .../cache/VisorCacheAggregatedMetrics.java      |   3 +-
 .../visor/cache/VisorCacheConfiguration.java    |   3 +-
 .../cache/VisorCacheDefaultConfiguration.java   |   5 +-
 .../cache/VisorCacheEvictionConfiguration.java  |   5 +-
 .../internal/visor/cache/VisorCacheMetrics.java |   3 +-
 .../cache/VisorCacheNearConfiguration.java      |   5 +-
 .../visor/cache/VisorCachePartition.java        |   3 +-
 .../visor/cache/VisorCachePartitions.java       |   3 +-
 .../cache/VisorCacheQueryConfiguration.java     |   3 +-
 .../visor/cache/VisorCacheQueryMetrics.java     |   5 +-
 .../cache/VisorCacheRebalanceConfiguration.java |   5 +-
 .../cache/VisorCacheStoreConfiguration.java     |   3 +-
 .../cache/VisorCacheTypeFieldMetadata.java      |   3 +-
 .../visor/cache/VisorCacheTypeMetadata.java     |   3 +-
 .../internal/visor/cache/VisorCacheV4.java      | 124 +++
 .../internal/visor/debug/VisorThreadInfo.java   |   5 +-
 .../visor/debug/VisorThreadLockInfo.java        |   5 +-
 .../internal/visor/event/VisorGridEvent.java    |   5 +-
 .../internal/visor/file/VisorFileBlock.java     |   5 +-
 .../ignite/internal/visor/igfs/VisorIgfs.java   |   5 +-
 .../internal/visor/igfs/VisorIgfsEndpoint.java  |   5 +-
 .../internal/visor/igfs/VisorIgfsMetrics.java   |   5 +-
 .../visor/igfs/VisorIgfsProfilerEntry.java      |   5 +-
 .../VisorIgfsProfilerUniformityCounters.java    |   5 +-
 .../visor/log/VisorLogSearchResult.java         |   5 +-
 .../visor/node/VisorAtomicConfiguration.java    |   5 +-
 .../visor/node/VisorBasicConfiguration.java     |   5 +-
 .../node/VisorExecutorServiceConfiguration.java |   5 +-
 .../visor/node/VisorGridConfiguration.java      |   5 +-
 .../visor/node/VisorIgfsConfiguration.java      |   3 +-
 .../visor/node/VisorLifecycleConfiguration.java |   5 +-
 .../visor/node/VisorMetricsConfiguration.java   |   5 +-
 .../visor/node/VisorNodeDataCollectorJob.java   |  26 +-
 .../node/VisorNodeDataCollectorTaskResult.java  |   5 +-
 .../node/VisorPeerToPeerConfiguration.java      |   5 +-
 .../visor/node/VisorRestConfiguration.java      |   5 +-
 .../node/VisorSegmentationConfiguration.java    |   5 +-
 .../visor/node/VisorSpisConfiguration.java      |   5 +-
 .../node/VisorTransactionConfiguration.java     |   5 +-
 .../internal/visor/query/VisorQueryField.java   |   5 +-
 .../internal/visor/query/VisorQueryResult.java  |   5 +-
 .../plugin/security/SecurityPermissionSet.java  |   5 +-
 .../ignite/plugin/security/SecuritySubject.java |   5 +-
 modules/rest-http/pom.xml                       |  25 +-
 .../http/jetty/GridJettyJsonConfig.java         | 317 ------
 .../http/jetty/GridJettyObjectMapper.java       | 259 +++++
 .../http/jetty/GridJettyRestHandler.java        | 127 ++-
 parent/pom.xml                                  |   1 +
 61 files changed, 1277 insertions(+), 1163 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientDefaultCacheSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientDefaultCacheSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientDefaultCacheSelfTest.java
index f910b7d..09f99fd 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientDefaultCacheSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientDefaultCacheSelfTest.java
@@ -17,20 +17,26 @@
 
 package org.apache.ignite.internal.client;
 
-import java.io.BufferedReader;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.LineNumberReader;
 import java.net.URL;
 import java.net.URLConnection;
+import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Map;
 import java.util.UUID;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.ConnectorConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.processors.rest.GridRestCommand;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
@@ -58,7 +64,7 @@ public class ClientDefaultCacheSelfTest extends GridCommonAbstractTest {
     private static final int HTTP_PORT = 8081;
 
     /** Url address to send HTTP request. */
-    private static final String TEST_URL = "http://" + HOST + ":" + HTTP_PORT + "/ignite";
+    private static final String TEST_URL = "http://" + HOST + ":" + HTTP_PORT + "/ignite?";
 
     /** Used to sent request charset. */
     private static final String CHARSET = StandardCharsets.UTF_8.name();
@@ -66,6 +72,9 @@ public class ClientDefaultCacheSelfTest extends GridCommonAbstractTest {
     /** Name of node local cache. */
     private static final String LOCAL_CACHE = "local";
 
+    /** JSON to java mapper. */
+    private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
+
     /** {@inheritDoc} */
     @Override protected void beforeTestsStarted() throws Exception {
         System.setProperty(IGNITE_JETTY_PORT, String.valueOf(HTTP_PORT));
@@ -103,77 +112,95 @@ public class ClientDefaultCacheSelfTest extends GridCommonAbstractTest {
 
         cfg.setDiscoverySpi(disco);
 
-        CacheConfiguration cLocal = new CacheConfiguration();
+        CacheConfiguration cLoc = new CacheConfiguration();
 
-        cLocal.setName(LOCAL_CACHE);
+        cLoc.setName(LOCAL_CACHE);
 
-        cLocal.setCacheMode(CacheMode.LOCAL);
+        cLoc.setCacheMode(CacheMode.LOCAL);
 
-        cLocal.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
+        cLoc.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
 
-        cfg.setCacheConfiguration(defaultCacheConfiguration(), cLocal);
+        cfg.setCacheConfiguration(defaultCacheConfiguration(), cLoc);
 
         return cfg;
     }
 
     /**
-     * Builds list of connection strings with few different ports.
-     * Used to avoid possible failures in case of port range active.
-     *
-     * @param startPort Port to start list from.
-     * @return List of client connection strings.
-     */
-    private Collection<String> getServerList(int startPort) {
-        Collection<String> srvs = new ArrayList<>();
-
-        for (int i = startPort; i < startPort + 10; i++)
-            srvs.add(HOST + ":" + i);
-
-        return srvs;
-    }
-
-    /*
      * Send HTTP request to Jetty server of node and process result.
      *
-     * @param query Send query parameters.
+     * @param params Command parameters.
      * @return Processed response string.
+     * @throws IOException If failed.
      */
-    private String sendHttp(String query) {
-        String res = "No result";
+    private String content(Map<String, String> params) throws IOException {
+        SB sb = new SB(TEST_URL);
+
+        for (Map.Entry<String, String> e : params.entrySet())
+            sb.a(e.getKey()).a('=').a(e.getValue()).a('&');
+
+        String qry = sb.toString();
 
         try {
-            URLConnection connection = new URL(TEST_URL + "?" + query).openConnection();
+            URL url = new URL(qry);
 
-            connection.setRequestProperty("Accept-Charset", CHARSET);
+            URLConnection conn = url.openConnection();
 
-            BufferedReader r = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+            conn.setRequestProperty("Accept-Charset", CHARSET);
 
-            res = r.readLine();
+            InputStream in = conn.getInputStream();
 
-            r.close();
+            StringBuilder buf = new StringBuilder(256);
+
+            try (LineNumberReader rdr = new LineNumberReader(new InputStreamReader(in, "UTF-8"))) {
+                for (String line = rdr.readLine(); line != null; line = rdr.readLine())
+                    buf.append(line);
+            }
+
+            return buf.toString();
         }
         catch (IOException e) {
-            error("Failed to send HTTP request: " + TEST_URL + "?" + query, e);
+            error("Failed to send HTTP request: " + TEST_URL + "?" + qry, e);
+
+            throw e;
         }
+    }
+
+    /**
+     * @param content Content to check.
+     */
+    private JsonNode jsonResponse(String content) throws IOException {
+        assertNotNull(content);
+        assertFalse(content.isEmpty());
+
+        JsonNode node = JSON_MAPPER.readTree(content);
+
+        assertFalse(node.get("affinityNodeId").asText().isEmpty());
+        assertEquals(0, node.get("successStatus").asInt());
+        assertTrue(node.get("error").asText().isEmpty());
+        assertTrue(node.get("sessionToken").asText().isEmpty());
 
-        // Cut node id from response.
-        return res.substring(res.indexOf("\"response\""));
+        return node.get("response");
     }
 
     /**
      * Json format string in cache should not transform to Json object on get request.
      */
-    public void testSkipString2JsonTransformation() {
+    public void testSkipString2JsonTransformation() throws Exception {
+        String val = "{\"v\":\"my Value\",\"t\":1422559650154}";
+
         // Put to cache JSON format string value.
-        assertEquals("Incorrect query response", "\"response\":true,\"sessionToken\":\"\",\"successStatus\":0}",
-            sendHttp("cmd=put&cacheName=" + LOCAL_CACHE +
-                "&key=a&val=%7B%22v%22%3A%22my%20Value%22%2C%22t%22%3A1422559650154%7D"));
+        String ret = content(F.asMap("cmd", GridRestCommand.CACHE_PUT.key(), "cacheName", LOCAL_CACHE,
+            "key", "a", "val", URLEncoder.encode(val, CHARSET)));
+
+        JsonNode res = jsonResponse(ret);
+
+        assertEquals("Incorrect put response", true, res.asBoolean());
 
         // Escape '\' symbols disappear from response string on transformation to JSON object.
-        assertEquals(
-            "Incorrect query response",
-            "\"response\":\"{\\\"v\\\":\\\"my Value\\\",\\\"t\\\":1422559650154}\"," +
-                "\"sessionToken\":\"\",\"successStatus\":0}",
-            sendHttp("cmd=get&cacheName=" + LOCAL_CACHE + "&key=a"));
+        ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "cacheName", LOCAL_CACHE, "key", "a"));
+
+        res = jsonResponse(ret);
+
+        assertEquals("Incorrect get response", val, res.asText());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientHttpTask.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientHttpTask.java b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientHttpTask.java
index 9604c29..977a1eb 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientHttpTask.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientHttpTask.java
@@ -17,12 +17,13 @@
 
 package org.apache.ignite.internal.client;
 
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
-import net.sf.json.JSON;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONSerializer;
-import net.sf.json.JsonConfig;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.ignite.IgniteException;
 import org.apache.ignite.compute.ComputeJob;
 import org.apache.ignite.compute.ComputeJobResult;
 import org.apache.ignite.compute.ComputeJobResultPolicy;
@@ -40,14 +41,28 @@ public class ClientHttpTask extends ComputeTaskSplitAdapter<String, Integer> {
     /** Task delegate. */
     private final ClientTcpTask delegate = new ClientTcpTask();
 
+    /** JSON to java mapper. */
+    private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
+
     /** {@inheritDoc} */
     @Override protected Collection<? extends ComputeJob> split(int gridSize, String arg) {
-        JSON json = JSONSerializer.toJSON(arg);
+        try {
+            JsonNode json = JSON_MAPPER.readTree(arg);
+
+            List<String> list = null;
+
+            if (json.isArray()) {
+                list = new ArrayList<>();
 
-        List list = json.isArray() ? JSONArray.toList((JSONArray)json, String.class, new JsonConfig()) : null;
+                for (JsonNode child : json)
+                    list.add(child.asText());
+            }
 
-        //noinspection unchecked
-        return delegate.split(gridSize, list);
+            return delegate.split(gridSize, list);
+        }
+        catch (IOException e) {
+            throw new IgniteException(e);
+        }
     }
 
     /** {@inheritDoc} */
@@ -62,4 +77,4 @@ public class ClientHttpTask extends ComputeTaskSplitAdapter<String, Integer> {
 
         return WAIT;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientTcpTask.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientTcpTask.java b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientTcpTask.java
index 8458c0e..54a58e6 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientTcpTask.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientTcpTask.java
@@ -34,13 +34,13 @@ import static org.apache.ignite.compute.ComputeJobResultPolicy.WAIT;
  * <p>
  * The argument of the task is a collection of objects to calculate string length sum of.
  */
-public class ClientTcpTask extends ComputeTaskSplitAdapter<List<Object>, Integer> {
+public class ClientTcpTask extends ComputeTaskSplitAdapter<List<String>, Integer> {
     /** {@inheritDoc} */
-    @Override protected Collection<? extends ComputeJob> split(int gridSize, List<Object> list) {
+    @Override protected Collection<? extends ComputeJob> split(int gridSize, List<String> list) {
         Collection<ComputeJobAdapter> jobs = new ArrayList<>();
 
         if (list != null)
-            for (final Object val : list)
+            for (final String val : list)
                 jobs.add(new ComputeJobAdapter() {
                     @Override public Object execute() {
                         try {
@@ -50,7 +50,7 @@ public class ClientTcpTask extends ComputeTaskSplitAdapter<List<Object>, Integer
                             Thread.currentThread().interrupt();
                         }
 
-                        return val == null ? 0 : val.toString().length();
+                        return val == null ? 0 : val.length();
                     }
                 });
 
@@ -74,4 +74,4 @@ public class ClientTcpTask extends ComputeTaskSplitAdapter<List<Object>, Integer
 
         return WAIT;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientAbstractSelfTest.java
index 125603e..3fbd570 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientAbstractSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientAbstractSelfTest.java
@@ -17,9 +17,11 @@
 
 package org.apache.ignite.internal.client.integration;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -31,12 +33,12 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicInteger;
+import javax.cache.Cache;
 import javax.cache.configuration.Factory;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import junit.framework.Assert;
-import net.sf.json.JSON;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONSerializer;
-import net.sf.json.JsonConfig;
+import org.apache.ignite.IgniteException;
 import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.cache.store.CacheStoreAdapter;
 import org.apache.ignite.compute.ComputeJob;
@@ -246,8 +248,8 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
             cacheConfiguration("partitioned"), cacheConfiguration(CACHE_NAME));
 
         clientCfg.setMessageInterceptor(new ConnectorMessageInterceptor() {
-            @Override
-            public Object onReceive(@Nullable Object obj) {
+            /** {@inheritDoc} */
+            @Override public Object onReceive(@Nullable Object obj) {
                 if (obj != null)
                     INTERCEPTED_OBJECTS.put(obj, obj);
 
@@ -255,8 +257,8 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
                     obj + INTERCEPTED_SUF : obj;
             }
 
-            @Override
-            public Object onSend(Object obj) {
+            /** {@inheritDoc} */
+            @Override public Object onSend(Object obj) {
                 if (obj != null)
                     INTERCEPTED_OBJECTS.put(obj, obj);
 
@@ -332,7 +334,7 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
         cfg.setDataConfigurations(Arrays.asList(nullCache, cache));
 
         cfg.setProtocol(protocol());
-        cfg.setServers(Arrays.asList(serverAddress()));
+        cfg.setServers(Collections.singleton(serverAddress()));
 
         // Setting custom executor, to avoid failures on client shutdown.
         // And applying custom naming scheme to ease debugging.
@@ -390,9 +392,9 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
         futs.put("put", data.putAsync("key", "val"));
         futs.put("putAll", data.putAllAsync(F.asMap("key", "val")));
         futs.put("get", data.getAsync("key"));
-        futs.put("getAll", data.getAllAsync(Arrays.asList("key")));
+        futs.put("getAll", data.getAllAsync(Collections.singletonList("key")));
         futs.put("remove", data.removeAsync("key"));
-        futs.put("removeAll", data.removeAllAsync(Arrays.asList("key")));
+        futs.put("removeAll", data.removeAllAsync(Collections.singletonList("key")));
         futs.put("replace", data.replaceAsync("key", "val"));
         futs.put("cas", data.casAsync("key", "val", "val2"));
         futs.put("metrics", data.metricsAsync());
@@ -500,8 +502,8 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
 
         GridClientCompute compute = client.compute();
 
-        Assert.assertEquals(new Integer(17), compute.execute(taskName, taskArg));
-        Assert.assertEquals(new Integer(17), compute.executeAsync(taskName, taskArg).get());
+        Assert.assertEquals(17, compute.execute(taskName, taskArg));
+        Assert.assertEquals(17, compute.executeAsync(taskName, taskArg).get());
     }
 
     /**
@@ -570,13 +572,13 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
     /**
      * Test task.
      */
-    private static class TestTask extends ComputeTaskSplitAdapter<List<Object>, Integer> {
+    private static class TestTask extends ComputeTaskSplitAdapter<List<String>, Integer> {
         /** {@inheritDoc} */
-        @Override protected Collection<? extends ComputeJob> split(int gridSize, List<Object> list) {
+        @Override protected Collection<? extends ComputeJob> split(int gridSize, List<String> list) {
             Collection<ComputeJobAdapter> jobs = new ArrayList<>();
 
             if (list != null)
-                for (final Object val : list)
+                for (final String val : list)
                     jobs.add(new ComputeJobAdapter() {
                         @Override public Object execute() {
                             try {
@@ -586,7 +588,7 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
                                 Thread.currentThread().interrupt();
                             }
 
-                            return val == null ? 0 : val.toString().length();
+                            return val == null ? 0 : val.length();
                         }
                     });
 
@@ -607,20 +609,20 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
     /**
      * Test task that sleeps 5 seconds.
      */
-    private static class SleepTestTask extends ComputeTaskSplitAdapter<List<Object>, Integer> {
+    private static class SleepTestTask extends ComputeTaskSplitAdapter<List<String>, Integer> {
         /** {@inheritDoc} */
-        @Override protected Collection<? extends ComputeJob> split(int gridSize, List<Object> list)
+        @Override protected Collection<? extends ComputeJob> split(int gridSize, List<String> list)
             {
             Collection<ComputeJobAdapter> jobs = new ArrayList<>();
 
             if (list != null)
-                for (final Object val : list)
+                for (final String val : list)
                     jobs.add(new ComputeJobAdapter() {
                         @Override public Object execute() {
                             try {
                                 Thread.sleep(5000);
 
-                                return val == null ? 0 : val.toString().length();
+                                return val == null ? 0 : val.length();
                             }
                             catch (InterruptedException ignored) {
                                 return -1;
@@ -642,10 +644,14 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
         }
     }
 
+    /** JSON to java mapper. */
+    private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
+
     /**
      * Http test task with restriction to string arguments only.
      */
     protected static class HttpTestTask extends ComputeTaskSplitAdapter<String, Integer> {
+        /** */
         private final TestTask delegate = new TestTask();
 
         /** {@inheritDoc} */
@@ -654,11 +660,23 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
             if (arg.endsWith("intercepted"))
                 arg = arg.substring(0, arg.length() - 11);
 
-            JSON json = JSONSerializer.toJSON(arg);
+            try {
+                JsonNode json = JSON_MAPPER.readTree(arg);
+
+                List<String> list = null;
 
-            List list = json.isArray() ? JSONArray.toList((JSONArray)json, String.class, new JsonConfig()) : null;
+                if (json.isArray()) {
+                    list = new ArrayList<>();
 
-            return delegate.split(gridSize, list);
+                    for (JsonNode child : json)
+                        list.add(child.asText());
+                }
+
+                return delegate.split(gridSize, list);
+            }
+            catch (IOException e) {
+                throw new IgniteException(e);
+            }
         }
 
         /** {@inheritDoc} */
@@ -671,16 +689,29 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
      * Http wrapper for sleep task.
      */
     protected static class SleepHttpTestTask extends ComputeTaskSplitAdapter<String, Integer> {
+        /** */
         private final SleepTestTask delegate = new SleepTestTask();
 
         /** {@inheritDoc} */
         @SuppressWarnings("unchecked")
         @Override protected Collection<? extends ComputeJob> split(int gridSize, String arg) {
-            JSON json = JSONSerializer.toJSON(arg);
+            try {
+                JsonNode json = JSON_MAPPER.readTree(arg);
+
+                List<String> list = null;
 
-            List list = json.isArray() ? JSONArray.toList((JSONArray)json, String.class, new JsonConfig()) : null;
+                if (json.isArray()) {
+                    list = new ArrayList<>();
+
+                    for (JsonNode child : json)
+                        list.add(child.asText());
+                }
 
-            return delegate.split(gridSize, list);
+                return delegate.split(gridSize, list);
+            }
+            catch (IOException e) {
+                throw new IgniteException(e);
+            }
         }
 
         /** {@inheritDoc} */
@@ -698,9 +729,8 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
 
         /** {@inheritDoc} */
         @Override public void loadCache(IgniteBiInClosure<Object, Object> clo, Object... args) {
-            for (Map.Entry e : map.entrySet()) {
+            for (Map.Entry e : map.entrySet())
                 clo.apply(e.getKey(), e.getValue());
-            }
         }
 
         /** {@inheritDoc} */
@@ -709,7 +739,7 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
         }
 
         /** {@inheritDoc} */
-        @Override public void write(javax.cache.Cache.Entry<? extends Object, ? extends Object> e) {
+        @Override public void write(Cache.Entry<?, ?> e) {
             map.put(e.getKey(), e.getValue());
         }
 
@@ -718,4 +748,4 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
             map.remove(key);
         }
     }
-}
\ No newline at end of file
+}


[30/50] [abbrv] ignite git commit: IGNITE-3328 .NET: Support user-defined AffinityFunction

Posted by sb...@apache.org.
IGNITE-3328 .NET: Support user-defined AffinityFunction

This closes #826


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e1c755c7
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e1c755c7
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e1c755c7

Branch: refs/heads/ignite-1232
Commit: e1c755c7ec1e8e7d6fc60b722c32d25bf188cd6b
Parents: 6cfd991
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri Jun 24 18:57:07 2016 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Jun 24 18:57:07 2016 +0300

----------------------------------------------------------------------
 .../GridAffinityFunctionContextImpl.java        |   9 +
 .../affinity/PlatformAffinityFunction.java      | 242 ++++++++++++++++
 .../callback/PlatformCallbackGateway.java       |  87 ++++++
 .../callback/PlatformCallbackUtils.java         |  46 +++
 .../utils/PlatformConfigurationUtils.java       |  13 +-
 .../platforms/cpp/jni/include/ignite/jni/java.h |  19 +-
 modules/platforms/cpp/jni/src/java.cpp          |  35 ++-
 .../Apache.Ignite.Core.Tests.csproj             |   5 +-
 .../Cache/Affinity/AffinityFieldTest.cs         | 199 +++++++++++++
 .../Cache/Affinity/AffinityFunctionTest.cs      | 282 +++++++++++++++++++
 .../Cache/Affinity/AffinityTest.cs              | 138 +++++++++
 .../Cache/CacheAffinityFieldTest.cs             | 199 -------------
 .../Cache/CacheAffinityTest.cs                  | 139 ---------
 .../Cache/CacheConfigurationTest.cs             |   6 +-
 .../native-client-test-cache-affinity.xml       |   2 +-
 .../IgniteConfigurationSerializerTest.cs        |  14 +-
 .../Apache.Ignite.Core.Tests/TestRunner.cs      |   6 +-
 .../Apache.Ignite.Core.csproj                   |   2 +
 .../Cache/Affinity/AffinityFunctionBase.cs      | 102 ++++++-
 .../Cache/Affinity/AffinityFunctionContext.cs   | 116 ++++++++
 .../Cache/Affinity/AffinityTopologyVersion.cs   | 138 +++++++++
 .../Cache/Affinity/IAffinityFunction.cs         |  55 +++-
 .../Cache/Configuration/CacheConfiguration.cs   |   9 +-
 .../Apache.Ignite.Core/Events/EventBase.cs      |   2 +-
 .../Apache.Ignite.Core/Events/EventReader.cs    |   8 +-
 .../Apache.Ignite.Core/IgniteConfiguration.cs   |   1 +
 .../IgniteConfigurationSection.xsd              |   4 +-
 .../dotnet/Apache.Ignite.Core/Ignition.cs       |   4 +-
 .../Impl/Unmanaged/UnmanagedCallbackHandlers.cs |   6 +
 .../Impl/Unmanaged/UnmanagedCallbacks.cs        | 120 +++++++-
 .../dotnet/Apache.Ignite.sln.DotSettings        |   7 +-
 31 files changed, 1629 insertions(+), 386 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityFunctionContextImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityFunctionContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityFunctionContextImpl.java
index 6c97efd..e2bb99d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityFunctionContextImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityFunctionContextImpl.java
@@ -80,4 +80,13 @@ public class GridAffinityFunctionContextImpl implements AffinityFunctionContext
     @Override public int backups() {
         return backups;
     }
+
+    /**
+     * Gets the previous assignment.
+     *
+     * @return Previous assignment
+     */
+    public List<List<ClusterNode>> prevAssignment() {
+        return prevAssignment;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/affinity/PlatformAffinityFunction.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/affinity/PlatformAffinityFunction.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/affinity/PlatformAffinityFunction.java
new file mode 100644
index 0000000..4da5e24
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/affinity/PlatformAffinityFunction.java
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.platform.cache.affinity;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.cache.affinity.AffinityFunction;
+import org.apache.ignite.cache.affinity.AffinityFunctionContext;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.internal.binary.BinaryRawReaderEx;
+import org.apache.ignite.internal.binary.BinaryRawWriterEx;
+import org.apache.ignite.internal.cluster.IgniteClusterEx;
+import org.apache.ignite.internal.processors.affinity.GridAffinityFunctionContextImpl;
+import org.apache.ignite.internal.processors.platform.PlatformContext;
+import org.apache.ignite.internal.processors.platform.memory.PlatformInputStream;
+import org.apache.ignite.internal.processors.platform.memory.PlatformMemory;
+import org.apache.ignite.internal.processors.platform.memory.PlatformOutputStream;
+import org.apache.ignite.internal.processors.platform.utils.PlatformUtils;
+import org.apache.ignite.lifecycle.LifecycleAware;
+import org.apache.ignite.resources.IgniteInstanceResource;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Platform AffinityFunction.
+ */
+public class PlatformAffinityFunction implements AffinityFunction, Externalizable, LifecycleAware {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** */
+    private Object userFunc;
+
+    /** */
+    private int partitions;
+
+    /** */
+    private transient Ignite ignite;
+
+    /** */
+    private transient PlatformContext ctx;
+
+    /** */
+    private transient long ptr;
+
+    /**
+     * Ctor for serialization.
+     *
+     */
+    public PlatformAffinityFunction() {
+        partitions = -1;
+    }
+
+    /**
+     * Ctor.
+     *
+     * @param func User fun object.
+     * @param partitions Initial number of partitions.
+     */
+    public PlatformAffinityFunction(Object func, int partitions) {
+        userFunc = func;
+        this.partitions = partitions;
+    }
+
+    /** {@inheritDoc} */
+    public Object getUserFunc() {
+        return userFunc;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void reset() {
+        // No-op: userFunc is always in initial state (it is serialized only once on start).
+    }
+
+    /** {@inheritDoc} */
+    @Override public int partitions() {
+        // Affinity function can not return different number of partitions,
+        // so we pass this value once from the platform.
+        assert partitions > 0;
+
+        return partitions;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int partition(Object key) {
+        assert ctx != null;
+        assert ptr != 0;
+
+        try (PlatformMemory mem = ctx.memory().allocate()) {
+            PlatformOutputStream out = mem.output();
+            BinaryRawWriterEx writer = ctx.writer(out);
+
+            writer.writeObject(key);
+
+            out.synchronize();
+
+            return ctx.gateway().affinityFunctionPartition(ptr, mem.pointer());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public List<List<ClusterNode>> assignPartitions(AffinityFunctionContext affCtx) {
+        assert ctx != null;
+        assert ptr != 0;
+        assert affCtx != null;
+
+        try (PlatformMemory outMem = ctx.memory().allocate()) {
+            try (PlatformMemory inMem = ctx.memory().allocate()) {
+                PlatformOutputStream out = outMem.output();
+                BinaryRawWriterEx writer = ctx.writer(out);
+
+                // Write previous assignment
+                List<List<ClusterNode>> prevAssignment = ((GridAffinityFunctionContextImpl)affCtx).prevAssignment();
+
+                if (prevAssignment == null)
+                    writer.writeInt(-1);
+                else {
+                    writer.writeInt(prevAssignment.size());
+
+                    for (List<ClusterNode> part : prevAssignment)
+                        ctx.writeNodes(writer, part);
+                }
+
+                // Write other props
+                writer.writeInt(affCtx.backups());
+                ctx.writeNodes(writer, affCtx.currentTopologySnapshot());
+                writer.writeLong(affCtx.currentTopologyVersion().topologyVersion());
+                writer.writeInt(affCtx.currentTopologyVersion().minorTopologyVersion());
+                ctx.writeEvent(writer, affCtx.discoveryEvent());
+
+                // Call platform
+                out.synchronize();
+                ctx.gateway().affinityFunctionAssignPartitions(ptr, outMem.pointer(), inMem.pointer());
+
+                PlatformInputStream in = inMem.input();
+                BinaryRawReaderEx reader = ctx.reader(in);
+
+                // Read result
+                int partCnt = in.readInt();
+                List<List<ClusterNode>> res = new ArrayList<>(partCnt);
+                IgniteClusterEx cluster = ctx.kernalContext().grid().cluster();
+
+                for (int i = 0; i < partCnt; i++) {
+                    int partSize = in.readInt();
+                    List<ClusterNode> part = new ArrayList<>(partSize);
+
+                    for (int j = 0; j < partSize; j++)
+                        part.add(cluster.node(reader.readUuid()));
+
+                    res.add(part);
+                }
+
+                return res;
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void removeNode(UUID nodeId) {
+        assert ctx != null;
+        assert ptr != 0;
+
+        try (PlatformMemory mem = ctx.memory().allocate()) {
+            PlatformOutputStream out = mem.output();
+            BinaryRawWriterEx writer = ctx.writer(out);
+
+            writer.writeUuid(nodeId);
+
+            out.synchronize();
+
+            ctx.gateway().affinityFunctionRemoveNode(ptr, mem.pointer());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeObject(userFunc);
+        out.writeInt(partitions);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        userFunc = in.readObject();
+        partitions = in.readInt();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void start() throws IgniteException {
+        assert ignite != null;
+        ctx = PlatformUtils.platformContext(ignite);
+        assert ctx != null;
+
+        try (PlatformMemory mem = ctx.memory().allocate()) {
+            PlatformOutputStream out = mem.output();
+            BinaryRawWriterEx writer = ctx.writer(out);
+
+            writer.writeObject(userFunc);
+
+            out.synchronize();
+
+            ptr = ctx.gateway().affinityFunctionInit(mem.pointer());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void stop() throws IgniteException {
+        assert ctx != null;
+
+        ctx.gateway().affinityFunctionDestroy(ptr);
+    }
+
+    /**
+     * Injects the Ignite.
+     *
+     * @param ignite Ignite.
+     */
+    @IgniteInstanceResource
+    private void setIgnite(Ignite ignite) {
+        this.ignite = ignite;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackGateway.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackGateway.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackGateway.java
index 3439f38..3708e8f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackGateway.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackGateway.java
@@ -951,6 +951,93 @@ public class PlatformCallbackGateway {
     }
 
     /**
+     * Initializes affinity function.
+     *
+     * @param memPtr Pointer to a stream with serialized affinity function.
+     * @return Affinity function pointer.
+     */
+    public long affinityFunctionInit(long memPtr) {
+        enter();
+
+        try {
+            return PlatformCallbackUtils.affinityFunctionInit(envPtr, memPtr);
+        }
+        finally {
+            leave();
+        }
+    }
+
+    /**
+     * Gets the partition from affinity function.
+     *
+     * @param ptr Affinity function pointer.
+     * @param memPtr Pointer to a stream with key object.
+     * @return Partition number for a given key.
+     */
+    public int affinityFunctionPartition(long ptr, long memPtr) {
+        enter();
+
+        try {
+            return PlatformCallbackUtils.affinityFunctionPartition(envPtr, ptr, memPtr);
+        }
+        finally {
+            leave();
+        }
+    }
+
+    /**
+     * Assigns the affinity partitions.
+     *
+     * @param ptr Affinity function pointer.
+     * @param outMemPtr Pointer to a stream with affinity context.
+     * @param inMemPtr Pointer to a stream with result.
+     */
+    public void affinityFunctionAssignPartitions(long ptr, long outMemPtr, long inMemPtr){
+        enter();
+
+        try {
+            PlatformCallbackUtils.affinityFunctionAssignPartitions(envPtr, ptr, outMemPtr, inMemPtr);
+        }
+        finally {
+            leave();
+        }
+    }
+
+    /**
+     * Removes the node from affinity function.
+     *
+     * @param ptr Affinity function pointer.
+     * @param memPtr Pointer to a stream with node id.
+     */
+    public void affinityFunctionRemoveNode(long ptr, long memPtr) {
+        enter();
+
+        try {
+            PlatformCallbackUtils.affinityFunctionRemoveNode(envPtr, ptr, memPtr);
+        }
+        finally {
+            leave();
+        }
+    }
+
+    /**
+     * Destroys the affinity function.
+     *
+     * @param ptr Affinity function pointer.
+     */
+    public void affinityFunctionDestroy(long ptr) {
+        if (!lock.enterBusy())
+            return;  // skip: destroy is not necessary during shutdown.
+
+        try {
+            PlatformCallbackUtils.affinityFunctionDestroy(envPtr, ptr);
+        }
+        finally {
+            leave();
+        }
+    }
+
+    /**
      * Enter gateway.
      */
     protected void enter() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackUtils.java
index f7d6586..d19782d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/callback/PlatformCallbackUtils.java
@@ -496,6 +496,52 @@ public class PlatformCallbackUtils {
     static native void onClientReconnected(long envPtr, boolean clusterRestarted);
 
     /**
+     * Initializes affinity function.
+     *
+     * @param envPtr Environment pointer.
+     * @param memPtr Pointer to a stream with serialized affinity function.
+     * @return Affinity function pointer.
+     */
+    static native long affinityFunctionInit(long envPtr, long memPtr);
+
+    /**
+     * Gets the partition from affinity function.
+     *
+     * @param envPtr Environment pointer.
+     * @param ptr Affinity function pointer.
+     * @param memPtr Pointer to a stream with key object.
+     * @return Partition number for a given key.
+     */
+    static native int affinityFunctionPartition(long envPtr, long ptr, long memPtr);
+
+    /**
+     * Assigns the affinity partitions.
+     *
+     * @param envPtr Environment pointer.
+     * @param ptr Affinity function pointer.
+     * @param outMemPtr Pointer to a stream with affinity context.
+     * @param inMemPtr Pointer to a stream with result.
+     */
+    static native void affinityFunctionAssignPartitions(long envPtr, long ptr, long outMemPtr, long inMemPtr);
+
+    /**
+     * Removes the node from affinity function.
+     *
+     * @param envPtr Environment pointer.
+     * @param ptr Affinity function pointer.
+     * @param memPtr Pointer to a stream with node id.
+     */
+    static native void affinityFunctionRemoveNode(long envPtr, long ptr, long memPtr);
+
+    /**
+     * Destroys the affinity function.
+     *
+     * @param envPtr Environment pointer.
+     * @param ptr Affinity function pointer.
+     */
+    static native void affinityFunctionDestroy(long envPtr, long ptr);
+
+    /**
      * Private constructor.
      */
     private PlatformCallbackUtils() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
index 29b6a70..7353f08 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
@@ -41,6 +41,7 @@ import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.NearCacheConfiguration;
 import org.apache.ignite.configuration.TransactionConfiguration;
 import org.apache.ignite.internal.binary.*;
+import org.apache.ignite.internal.processors.platform.cache.affinity.PlatformAffinityFunction;
 import org.apache.ignite.platform.dotnet.PlatformDotNetBinaryConfiguration;
 import org.apache.ignite.platform.dotnet.PlatformDotNetBinaryTypeConfiguration;
 import org.apache.ignite.platform.dotnet.PlatformDotNetCacheStoreFactoryNative;
@@ -237,7 +238,7 @@ public class PlatformConfigurationUtils {
      * @param in Stream.
      * @return Affinity function.
      */
-    private static AffinityFunction readAffinityFunction(BinaryRawReader in) {
+    private static AffinityFunction readAffinityFunction(BinaryRawReaderEx in) {
         byte plcTyp = in.readByte();
 
         switch (plcTyp) {
@@ -255,6 +256,9 @@ public class PlatformConfigurationUtils {
                 f.setExcludeNeighbors(in.readBoolean());
                 return f;
             }
+            case 3: {
+                return new PlatformAffinityFunction(in.readObjectDetached(), in.readInt());
+            }
             default:
                 assert false;
         }
@@ -296,6 +300,13 @@ public class PlatformConfigurationUtils {
             out.writeInt(f0.getPartitions());
             out.writeBoolean(f0.isExcludeNeighbors());
         }
+        else if (f instanceof PlatformAffinityFunction) {
+            out.writeByte((byte)3);
+
+            PlatformAffinityFunction f0 = (PlatformAffinityFunction)f;
+            out.writeObject(f0.getUserFunc());
+            out.writeInt(f.partitions());
+        }
         else {
             out.writeByte((byte)0);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/cpp/jni/include/ignite/jni/java.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/jni/include/ignite/jni/java.h b/modules/platforms/cpp/jni/include/ignite/jni/java.h
index 3d45ec0..98779c4 100644
--- a/modules/platforms/cpp/jni/include/ignite/jni/java.h
+++ b/modules/platforms/cpp/jni/include/ignite/jni/java.h
@@ -21,7 +21,6 @@
 #include <jni.h>
 
 #include "ignite/common/common.h"
-#include "ignite/ignite_error.h"
 
 namespace ignite
 {
@@ -101,6 +100,12 @@ namespace ignite
             typedef void(JNICALL *OnClientDisconnectedHandler)(void* target);
             typedef void(JNICALL *OnClientReconnectedHandler)(void* target, unsigned char clusterRestarted);
 
+            typedef long long(JNICALL *AffinityFunctionInitHandler)(void* target, long long memPtr);
+            typedef int(JNICALL *AffinityFunctionPartitionHandler)(void* target, long long ptr, long long memPtr);
+            typedef void(JNICALL *AffinityFunctionAssignPartitionsHandler)(void* target, long long ptr, long long inMemPtr, long long outMemPtr);
+            typedef void(JNICALL *AffinityFunctionRemoveNodeHandler)(void* target, long long ptr, long long memPtr);
+            typedef void(JNICALL *AffinityFunctionDestroyHandler)(void* target, long long ptr);
+
             /**
              * JNI handlers holder.
              */
@@ -178,6 +183,12 @@ namespace ignite
 
                 OnClientDisconnectedHandler onClientDisconnected;
                 OnClientReconnectedHandler onClientReconnected;
+                
+                AffinityFunctionInitHandler affinityFunctionInit;
+                AffinityFunctionPartitionHandler affinityFunctionPartition;
+                AffinityFunctionAssignPartitionsHandler affinityFunctionAssignPartitions;
+                AffinityFunctionRemoveNodeHandler affinityFunctionRemoveNode;
+                AffinityFunctionDestroyHandler affinityFunctionDestroy;
             };
 
             /**
@@ -740,6 +751,12 @@ namespace ignite
 
             JNIEXPORT void JNICALL JniOnClientDisconnected(JNIEnv *env, jclass cls, jlong envPtr);
             JNIEXPORT void JNICALL JniOnClientReconnected(JNIEnv *env, jclass cls, jlong envPtr, jboolean clusterRestarted);
+
+            JNIEXPORT jlong JNICALL JniAffinityFunctionInit(JNIEnv *env, jclass cls, jlong envPtr, jlong memPtr);
+            JNIEXPORT jint JNICALL JniAffinityFunctionPartition(JNIEnv *env, jclass cls, jlong envPtr, jlong ptr, jlong memPtr);
+            JNIEXPORT void JNICALL JniAffinityFunctionAssignPartitions(JNIEnv *env, jclass cls, jlong envPtr, jlong ptr, jlong inMemPtr, jlong outMemPtr);
+            JNIEXPORT void JNICALL JniAffinityFunctionRemoveNode(JNIEnv *env, jclass cls, jlong envPtr, jlong ptr, jlong memPtr);
+            JNIEXPORT void JNICALL JniAffinityFunctionDestroy(JNIEnv *env, jclass cls, jlong envPtr, jlong ptr);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/cpp/jni/src/java.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/jni/src/java.cpp b/modules/platforms/cpp/jni/src/java.cpp
index 66be0ca..577ee26 100644
--- a/modules/platforms/cpp/jni/src/java.cpp
+++ b/modules/platforms/cpp/jni/src/java.cpp
@@ -22,6 +22,7 @@
 #include "ignite/jni/utils.h"
 #include "ignite/common/concurrent.h"
 #include "ignite/jni/java.h"
+#include <ignite/ignite_error.h>
 
 #define IGNITE_SAFE_PROC_NO_ARG(jniEnv, envPtr, type, field) { \
     JniHandlers* hnds = reinterpret_cast<JniHandlers*>(envPtr); \
@@ -362,6 +363,12 @@ namespace ignite
             JniMethod M_PLATFORM_CALLBACK_UTILS_ON_CLIENT_DISCONNECTED = JniMethod("onClientDisconnected", "(J)V", true);
             JniMethod M_PLATFORM_CALLBACK_UTILS_ON_CLIENT_RECONNECTED = JniMethod("onClientReconnected", "(JZ)V", true);
 
+            JniMethod M_PLATFORM_CALLBACK_UTILS_AFFINITY_FUNCTION_INIT = JniMethod("affinityFunctionInit", "(JJ)J", true);
+            JniMethod M_PLATFORM_CALLBACK_UTILS_AFFINITY_FUNCTION_PARTITION = JniMethod("affinityFunctionPartition", "(JJJ)I", true);
+            JniMethod M_PLATFORM_CALLBACK_UTILS_AFFINITY_FUNCTION_ASSIGN_PARTITIONS = JniMethod("affinityFunctionAssignPartitions", "(JJJJ)V", true);
+            JniMethod M_PLATFORM_CALLBACK_UTILS_AFFINITY_FUNCTION_REMOVE_NODE = JniMethod("affinityFunctionRemoveNode", "(JJJ)V", true);
+            JniMethod M_PLATFORM_CALLBACK_UTILS_AFFINITY_FUNCTION_DESTROY = JniMethod("affinityFunctionDestroy", "(JJ)V", true);
+
             const char* C_PLATFORM_UTILS = "org/apache/ignite/internal/processors/platform/utils/PlatformUtils";
             JniMethod M_PLATFORM_UTILS_REALLOC = JniMethod("reallocate", "(JI)V", true);
             JniMethod M_PLATFORM_UTILS_ERR_DATA = JniMethod("errorData", "(Ljava/lang/Throwable;)[B", true);
@@ -821,7 +828,7 @@ namespace ignite
 
             void RegisterNatives(JNIEnv* env) {
                 {
-					JNINativeMethod methods[54];
+					JNINativeMethod methods[59];
 
                     int idx = 0;
 
@@ -898,6 +905,12 @@ namespace ignite
                     AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_ON_CLIENT_DISCONNECTED, reinterpret_cast<void*>(JniOnClientDisconnected));
                     AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_ON_CLIENT_RECONNECTED, reinterpret_cast<void*>(JniOnClientReconnected));
 
+                    AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_AFFINITY_FUNCTION_INIT, reinterpret_cast<void*>(JniAffinityFunctionInit));
+                    AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_AFFINITY_FUNCTION_PARTITION, reinterpret_cast<void*>(JniAffinityFunctionPartition));
+                    AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_AFFINITY_FUNCTION_ASSIGN_PARTITIONS, reinterpret_cast<void*>(JniAffinityFunctionAssignPartitions));
+                    AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_AFFINITY_FUNCTION_REMOVE_NODE, reinterpret_cast<void*>(JniAffinityFunctionRemoveNode));
+                    AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_AFFINITY_FUNCTION_DESTROY, reinterpret_cast<void*>(JniAffinityFunctionDestroy));
+
                     jint res = env->RegisterNatives(FindClass(env, C_PLATFORM_CALLBACK_UTILS), methods, idx);
 
                     if (res != JNI_OK)
@@ -2833,6 +2846,26 @@ namespace ignite
             JNIEXPORT void JNICALL JniOnClientReconnected(JNIEnv *env, jclass cls, jlong envPtr, jboolean clusterRestarted) {
                 IGNITE_SAFE_PROC(env, envPtr, OnClientReconnectedHandler, onClientReconnected, clusterRestarted);
             }
+            
+            JNIEXPORT jlong JNICALL JniAffinityFunctionInit(JNIEnv *env, jclass cls, jlong envPtr, jlong memPtr) {
+                IGNITE_SAFE_FUNC(env, envPtr, AffinityFunctionInitHandler, affinityFunctionInit, memPtr);
+            }
+
+            JNIEXPORT jint JNICALL JniAffinityFunctionPartition(JNIEnv *env, jclass cls, jlong envPtr, jlong ptr, jlong memPtr) {
+                IGNITE_SAFE_FUNC(env, envPtr, AffinityFunctionPartitionHandler, affinityFunctionPartition, ptr, memPtr);
+            }
+            
+            JNIEXPORT void JNICALL JniAffinityFunctionAssignPartitions(JNIEnv *env, jclass cls, jlong envPtr, jlong ptr, jlong inMemPtr, jlong outMemPtr) {
+                IGNITE_SAFE_PROC(env, envPtr, AffinityFunctionAssignPartitionsHandler, affinityFunctionAssignPartitions, ptr, inMemPtr, outMemPtr);
+            }
+
+            JNIEXPORT void JNICALL JniAffinityFunctionRemoveNode(JNIEnv *env, jclass cls, jlong envPtr, jlong ptr, jlong memPtr) {
+                IGNITE_SAFE_PROC(env, envPtr, AffinityFunctionRemoveNodeHandler, affinityFunctionRemoveNode, ptr, memPtr);
+            }
+
+            JNIEXPORT void JNICALL JniAffinityFunctionDestroy(JNIEnv *env, jclass cls, jlong envPtr, jlong ptr) {
+                IGNITE_SAFE_PROC(env, envPtr, AffinityFunctionDestroyHandler, affinityFunctionDestroy, ptr);
+            }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
index 1a367d4..15e46ae 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
@@ -59,13 +59,14 @@
     <Compile Include="Binary\BinaryCompactFooterInteropTest.cs" />
     <Compile Include="Binary\BinarySelfTestFullFooter.cs" />
     <Compile Include="Binary\BinaryStringTest.cs" />
-    <Compile Include="Cache\CacheAffinityFieldTest.cs" />
+    <Compile Include="Cache\Affinity\AffinityFieldTest.cs" />
+    <Compile Include="Cache\Affinity\AffinityFunctionTest.cs" />
     <Compile Include="Cache\CacheConfigurationTest.cs" />
     <Compile Include="Cache\CacheDynamicStartTest.cs" />
     <Compile Include="Cache\CacheNearTest.cs" />
     <Compile Include="Cache\CacheTestAsyncWrapper.cs" />
     <Compile Include="Cache\CacheAbstractTest.cs" />
-    <Compile Include="Cache\CacheAffinityTest.cs" />
+    <Compile Include="Cache\Affinity\AffinityTest.cs" />
     <Compile Include="Cache\CacheEntryTest.cs" />
     <Compile Include="Cache\CacheForkedTest.cs" />
     <Compile Include="Cache\CacheLocalAtomicTest.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFieldTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFieldTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFieldTest.cs
new file mode 100644
index 0000000..ceb04cd
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFieldTest.cs
@@ -0,0 +1,199 @@
+\ufeff/*
+ * 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.
+ */
+
+// ReSharper disable UnusedAutoPropertyAccessor.Local
+namespace Apache.Ignite.Core.Tests.Cache.Affinity
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Cache.Affinity;
+    using Apache.Ignite.Core.Cache.Configuration;
+    using Apache.Ignite.Core.Tests.Compute;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests custom affinity mapping.
+    /// </summary>
+    public class AffinityFieldTest
+    {
+        /** */
+        private ICache<object, string> _cache1;
+
+        /** */
+        private ICache<object, string> _cache2;
+
+        /// <summary>
+        /// Fixture set up.
+        /// </summary>
+        [TestFixtureSetUp]
+        public void FixtureSetUp()
+        {
+            var grid1 = Ignition.Start(GetConfig());
+            var grid2 = Ignition.Start(GetConfig("grid2"));
+
+            _cache1 = grid1.CreateCache<object, string>(new CacheConfiguration
+            {
+                CacheMode = CacheMode.Partitioned
+            });
+            _cache2 = grid2.GetCache<object, string>(null);
+        }
+
+        /// <summary>
+        /// Fixture tear down.
+        /// </summary>
+        [TestFixtureTearDown]
+        public void FixtureTearDown()
+        {
+            Ignition.StopAll(true);
+        }
+
+        /// <summary>
+        /// Tests the metadata.
+        /// </summary>
+        [Test]
+        public void TestMetadata()
+        {
+            // Put keys to update meta
+            _cache1.Put(new CacheKey(), string.Empty);
+            _cache1.Put(new CacheKeyAttr(), string.Empty);
+            _cache1.Put(new CacheKeyAttrOverride(), string.Empty);
+
+            // Verify
+            foreach (var type in new[] { typeof(CacheKey) , typeof(CacheKeyAttr), typeof(CacheKeyAttrOverride)})
+            {
+                Assert.AreEqual("AffinityKey", _cache1.Ignite.GetBinary().GetBinaryType(type).AffinityKeyFieldName);
+                Assert.AreEqual("AffinityKey", _cache2.Ignite.GetBinary().GetBinaryType(type).AffinityKeyFieldName);
+            }
+        }
+
+        /// <summary>
+        /// Tests that keys are located properly in cache partitions.
+        /// </summary>
+        [Test]
+        public void TestKeyLocation()
+        {
+            TestKeyLocation0((key, affKey) => new CacheKey {Key = key, AffinityKey = affKey});
+            TestKeyLocation0((key, affKey) => new CacheKeyAttr {Key = key, AffinityKey = affKey});
+            TestKeyLocation0((key, affKey) => new CacheKeyAttrOverride {Key = key, AffinityKey = affKey});
+        }
+
+        /// <summary>
+        /// Tests the <see cref="AffinityKey"/> class.
+        /// </summary>
+        [Test]
+        public void TestAffinityKeyClass()
+        {
+            // Check location
+            TestKeyLocation0((key, affKey) => new AffinityKey(key, affKey));
+
+            // Check meta
+            Assert.AreEqual("affKey",
+                _cache1.Ignite.GetBinary().GetBinaryType(typeof (AffinityKey)).AffinityKeyFieldName);
+        }
+
+        /// <summary>
+        /// Tests <see cref="AffinityKey"/> class interoperability.
+        /// </summary>
+        [Test]
+        public void TestInterop()
+        {
+            var affKey = _cache1.Ignite.GetCompute()
+                .ExecuteJavaTask<AffinityKey>(ComputeApiTest.EchoTask, ComputeApiTest.EchoTypeAffinityKey);
+
+            Assert.AreEqual("interopAffinityKey", affKey.Key);
+        }
+
+        /// <summary>
+        /// Tests the key location.
+        /// </summary>
+        private void TestKeyLocation0<T>(Func<int, int, T> ctor)
+        {
+            var aff = _cache1.Ignite.GetAffinity(_cache1.Name);
+
+            foreach (var cache in new[] { _cache1, _cache2 })
+            {
+                cache.RemoveAll();
+
+                var localNode = cache.Ignite.GetCluster().GetLocalNode();
+
+                var localKeys = Enumerable.Range(1, int.MaxValue)
+                    .Where(x => aff.MapKeyToNode(x).Id == localNode.Id).Take(100).ToArray();
+
+                for (int index = 0; index < localKeys.Length; index++)
+                {
+                    var cacheKey = ctor(index, localKeys[index]);
+
+                    cache.Put(cacheKey, index.ToString());
+
+                    // Verify that key is stored locally according to AffinityKeyFieldName
+                    Assert.AreEqual(index.ToString(), cache.LocalPeek(cacheKey, CachePeekMode.Primary));
+
+                    // Other cache does not have this key locally
+                    var otherCache = cache == _cache1 ? _cache2 : _cache1;
+                    Assert.Throws<KeyNotFoundException>(() => otherCache.LocalPeek(cacheKey, CachePeekMode.All));
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets the configuration.
+        /// </summary>
+        private static IgniteConfiguration GetConfig(string gridName = null)
+        {
+            return new IgniteConfiguration(TestUtils.GetTestConfiguration())
+            {
+                GridName = gridName,
+                BinaryConfiguration = new BinaryConfiguration
+                {
+                    TypeConfigurations = new[]
+                    {
+                        new BinaryTypeConfiguration(typeof (CacheKey))
+                        {
+                            AffinityKeyFieldName = "AffinityKey"
+                        },
+                        new BinaryTypeConfiguration(typeof(CacheKeyAttr)),
+                        new BinaryTypeConfiguration(typeof (CacheKeyAttrOverride))
+                        {
+                            AffinityKeyFieldName = "AffinityKey"
+                        }
+                    }
+                },
+            };
+        }
+
+        private class CacheKey
+        {
+            public int Key { get; set; }
+            public int AffinityKey { get; set; }
+        }
+
+        private class CacheKeyAttr
+        {
+            public int Key { get; set; }
+            [AffinityKeyMapped] public int AffinityKey { get; set; }
+        }
+
+        private class CacheKeyAttrOverride
+        {
+            [AffinityKeyMapped] public int Key { get; set; }
+            public int AffinityKey { get; set; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFunctionTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFunctionTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFunctionTest.cs
new file mode 100644
index 0000000..70e0d78
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFunctionTest.cs
@@ -0,0 +1,282 @@
+\ufeff/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache.Affinity
+{
+    using System;
+    using System.Collections.Concurrent;
+    using System.Collections.Generic;
+    using System.Linq;
+    using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Cache.Affinity;
+    using Apache.Ignite.Core.Cache.Configuration;
+    using Apache.Ignite.Core.Cluster;
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Resource;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests user-defined <see cref="IAffinityFunction"/>
+    /// </summary>
+    public class AffinityFunctionTest
+    {
+        /** */
+        private IIgnite _ignite;
+
+        /** */
+        private IIgnite _ignite2;
+
+        /** */
+        private const string CacheName = "cache";
+
+        /** */
+        private const int PartitionCount = 10;
+
+        /** */
+        private static readonly ConcurrentBag<Guid> RemovedNodes = new ConcurrentBag<Guid>();
+
+        /** */
+        private static readonly ConcurrentBag<AffinityFunctionContext> Contexts =
+            new ConcurrentBag<AffinityFunctionContext>();
+
+        /// <summary>
+        /// Fixture set up.
+        /// </summary>
+        [TestFixtureSetUp]
+        public void FixtureSetUp()
+        {
+            var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
+            {
+                CacheConfiguration = new[]
+                {
+                    new CacheConfiguration(CacheName)
+                    {
+                        AffinityFunction = new SimpleAffinityFunction(),
+                        Backups = 7
+                    }
+                }
+            };
+
+            _ignite = Ignition.Start(cfg);
+
+            _ignite2 = Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration()) {GridName = "grid2"});
+        }
+
+        /// <summary>
+        /// Fixture tear down.
+        /// </summary>
+        [TestFixtureTearDown]
+        public void FixtureTearDown()
+        {
+            // Check that affinity handles are present
+            TestUtils.AssertHandleRegistryHasItems(_ignite, _ignite.GetCacheNames().Count, 0);
+            TestUtils.AssertHandleRegistryHasItems(_ignite2, _ignite.GetCacheNames().Count, 0);
+
+            // Destroy all caches
+            _ignite.GetCacheNames().ToList().ForEach(_ignite.DestroyCache);
+            Assert.AreEqual(0, _ignite.GetCacheNames().Count);
+
+            // Check that all affinity functions got released
+            TestUtils.AssertHandleRegistryIsEmpty(1000, _ignite, _ignite2);
+
+            Ignition.StopAll(true);
+        }
+
+        /// <summary>
+        /// Tests the static cache.
+        /// </summary>
+        [Test]
+        public void TestStaticCache()
+        {
+            VerifyCacheAffinity(_ignite.GetCache<int, int>(CacheName));
+            VerifyCacheAffinity(_ignite2.GetCache<int, int>(CacheName));
+        }
+
+        /// <summary>
+        /// Tests the dynamic cache.
+        /// </summary>
+        [Test]
+        public void TestDynamicCache()
+        {
+            const string cacheName = "dynCache";
+
+            VerifyCacheAffinity(_ignite.CreateCache<int, int>(new CacheConfiguration(cacheName)
+            {
+                AffinityFunction = new SimpleAffinityFunction(),
+                Backups = 5
+            }));
+
+            VerifyCacheAffinity(_ignite2.GetCache<int, int>(cacheName));
+            
+            // Verify context for new cache
+            var lastCtx = Contexts.Where(x => x.GetPreviousAssignment(1) == null)
+                .OrderBy(x => x.DiscoveryEvent.Timestamp).Last();
+
+            Assert.AreEqual(new AffinityTopologyVersion(2, 1), lastCtx.CurrentTopologyVersion);
+            Assert.AreEqual(5, lastCtx.Backups);
+
+            // Verify context for old cache
+            var ctx = Contexts.Where(x => x.GetPreviousAssignment(1) != null)
+                .OrderBy(x => x.DiscoveryEvent.Timestamp).Last();
+
+            Assert.AreEqual(new AffinityTopologyVersion(2, 0), ctx.CurrentTopologyVersion);
+            Assert.AreEqual(7, ctx.Backups);
+            CollectionAssert.AreEquivalent(_ignite.GetCluster().GetNodes(), ctx.CurrentTopologySnapshot);
+
+            var evt = ctx.DiscoveryEvent;
+            CollectionAssert.AreEquivalent(_ignite.GetCluster().GetNodes(), evt.TopologyNodes);
+            CollectionAssert.Contains(_ignite.GetCluster().GetNodes(), evt.EventNode);
+            Assert.AreEqual(_ignite.GetCluster().TopologyVersion, evt.TopologyVersion);
+
+            var firstTop = _ignite.GetCluster().GetTopology(1);
+            var parts = Enumerable.Range(0, PartitionCount).ToArray();
+            CollectionAssert.AreEqual(parts.Select(x => firstTop), parts.Select(x => ctx.GetPreviousAssignment(x)));
+        }
+
+        /// <summary>
+        /// Verifies the cache affinity.
+        /// </summary>
+        private static void VerifyCacheAffinity(ICache<int, int> cache)
+        {
+            Assert.IsInstanceOf<SimpleAffinityFunction>(cache.GetConfiguration().AffinityFunction);
+
+            var aff = cache.Ignite.GetAffinity(cache.Name);
+            Assert.AreEqual(PartitionCount, aff.Partitions);
+
+            for (int i = 0; i < 100; i++)
+                Assert.AreEqual(i % PartitionCount, aff.GetPartition(i));
+        }
+
+        /// <summary>
+        /// Tests the RemoveNode method.
+        /// </summary>
+        [Test]
+        public void TestRemoveNode()
+        {
+            Assert.AreEqual(0, RemovedNodes.Count);
+
+            Guid expectedNodeId;
+
+            using (var ignite = Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration())
+            {
+                GridName = "grid3",
+            }))
+            {
+                expectedNodeId = ignite.GetCluster().GetLocalNode().Id;
+                Assert.AreEqual(0, RemovedNodes.Count);
+                VerifyCacheAffinity(ignite.GetCache<int, int>(CacheName));
+            }
+
+            // Called on both nodes
+            TestUtils.WaitForCondition(() => RemovedNodes.Count > 0, 3000);
+            Assert.AreEqual(expectedNodeId, RemovedNodes.Distinct().Single());
+        }
+
+        /// <summary>
+        /// Tests the error on non-serializable function.
+        /// </summary>
+        [Test]
+        public void TestNonSerializableFunction()
+        {
+            var ex = Assert.Throws<IgniteException>(() =>
+                _ignite.CreateCache<int, int>(new CacheConfiguration("failCache")
+                {
+                    AffinityFunction = new NonSerializableAffinityFunction()
+                }));
+
+            Assert.AreEqual(ex.Message, "AffinityFunction should be serializable.");
+        }
+
+        /// <summary>
+        /// Tests the exception propagation.
+        /// </summary>
+        [Test]
+        public void TestExceptionInFunction()
+        {
+            var cache = _ignite.CreateCache<int, int>(new CacheConfiguration("failCache2")
+            {
+                AffinityFunction = new FailInGetPartitionAffinityFunction()
+            });
+
+            var ex = Assert.Throws<CacheException>(() => cache.Put(1, 2));
+            Assert.AreEqual("User error", ex.InnerException.Message);
+        }
+
+        [Serializable]
+        private class SimpleAffinityFunction : IAffinityFunction
+        {
+            #pragma warning disable 649  // field is never assigned
+            [InstanceResource] private readonly IIgnite _ignite;
+
+            public int Partitions
+            {
+                get { return PartitionCount; }
+            }
+
+            public int GetPartition(object key)
+            {
+                Assert.IsNotNull(_ignite);
+
+                return (int) key % Partitions;
+            }
+
+            public void RemoveNode(Guid nodeId)
+            {
+                RemovedNodes.Add(nodeId);
+            }
+
+            public IEnumerable<IEnumerable<IClusterNode>> AssignPartitions(AffinityFunctionContext context)
+            {
+                Assert.IsNotNull(_ignite);
+
+                Contexts.Add(context);
+
+                // All partitions are the same
+                return Enumerable.Range(0, Partitions).Select(x => context.CurrentTopologySnapshot);
+            }
+        }
+
+        private class NonSerializableAffinityFunction : SimpleAffinityFunction
+        {
+            // No-op.
+        }
+
+        [Serializable]
+        private class FailInGetPartitionAffinityFunction : IAffinityFunction
+        {
+            public int Partitions
+            {
+                get { return 5; }
+            }
+
+            public int GetPartition(object key)
+            {
+                throw new ArithmeticException("User error");
+            }
+
+            public void RemoveNode(Guid nodeId)
+            {
+                // No-op.
+            }
+
+            public IEnumerable<IEnumerable<IClusterNode>> AssignPartitions(AffinityFunctionContext context)
+            {
+                return Enumerable.Range(0, Partitions).Select(x => context.CurrentTopologySnapshot);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityTest.cs
new file mode 100644
index 0000000..e38668b
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityTest.cs
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache.Affinity
+{
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Cluster;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Affinity key tests.
+    /// </summary>
+    public sealed class AffinityTest
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        [TestFixtureSetUp]
+        public void StartGrids()
+        {
+            TestUtils.KillProcesses();
+
+            for (int i = 0; i < 3; i++)
+            {
+                var cfg = new IgniteConfiguration
+                {
+                    JvmClasspath = TestUtils.CreateTestClasspath(),
+                    JvmOptions = TestUtils.TestJavaOptions(),
+                    SpringConfigUrl = "config\\native-client-test-cache-affinity.xml",
+                    GridName = "grid-" + i
+                };
+
+                Ignition.Start(cfg);
+            }
+        }
+
+        /// <summary>
+        /// Tear-down routine.
+        /// </summary>
+        [TestFixtureTearDown]
+        public void StopGrids()
+        {
+            Ignition.StopAll(true);
+        }
+
+        /// <summary>
+        /// Test affinity key.
+        /// </summary>
+        [Test]
+        public void TestAffinity()
+        {
+            IIgnite g = Ignition.GetIgnite("grid-0");
+
+            ICacheAffinity aff = g.GetAffinity(null);
+
+            IClusterNode node = aff.MapKeyToNode(new AffinityTestKey(0, 1));
+
+            for (int i = 0; i < 10; i++)
+                Assert.AreEqual(node.Id, aff.MapKeyToNode(new AffinityTestKey(i, 1)).Id);
+        }
+
+        /// <summary>
+        /// Test affinity with binary flag.
+        /// </summary>
+        [Test]
+        public void TestAffinityBinary()
+        {
+            IIgnite g = Ignition.GetIgnite("grid-0");
+
+            ICacheAffinity aff = g.GetAffinity(null);  
+
+            IBinaryObject affKey = g.GetBinary().ToBinary<IBinaryObject>(new AffinityTestKey(0, 1));
+
+            IClusterNode node = aff.MapKeyToNode(affKey);
+
+            for (int i = 0; i < 10; i++)
+            {
+                IBinaryObject otherAffKey =
+                    g.GetBinary().ToBinary<IBinaryObject>(new AffinityTestKey(i, 1));
+
+                Assert.AreEqual(node.Id, aff.MapKeyToNode(otherAffKey).Id);
+            }
+        }
+
+        /// <summary>
+        /// Affinity key.
+        /// </summary>
+        public class AffinityTestKey
+        {
+            /** ID. */
+            private readonly int _id;
+
+            /** Affinity key. */
+            // ReSharper disable once NotAccessedField.Local
+            private readonly int _affKey;
+
+            /// <summary>
+            /// Constructor.
+            /// </summary>
+            /// <param name="id">ID.</param>
+            /// <param name="affKey">Affinity key.</param>
+            public AffinityTestKey(int id, int affKey)
+            {
+                _id = id;
+                _affKey = affKey;
+            }
+
+            /** <inheritdoc /> */
+            public override bool Equals(object obj)
+            {
+                var other = obj as AffinityTestKey;
+
+                return other != null && _id == other._id;
+            }
+
+            /** <inheritdoc /> */
+            public override int GetHashCode()
+            {
+                return _id;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAffinityFieldTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAffinityFieldTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAffinityFieldTest.cs
deleted file mode 100644
index 4fb7738..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAffinityFieldTest.cs
+++ /dev/null
@@ -1,199 +0,0 @@
-\ufeff/*
- * 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.
- */
-
-// ReSharper disable UnusedAutoPropertyAccessor.Local
-namespace Apache.Ignite.Core.Tests.Cache
-{
-    using System;
-    using System.Collections.Generic;
-    using System.Linq;
-    using Apache.Ignite.Core.Binary;
-    using Apache.Ignite.Core.Cache;
-    using Apache.Ignite.Core.Cache.Affinity;
-    using Apache.Ignite.Core.Cache.Configuration;
-    using Apache.Ignite.Core.Tests.Compute;
-    using NUnit.Framework;
-
-    /// <summary>
-    /// Tests custom affinity mapping.
-    /// </summary>
-    public class CacheAffinityFieldTest
-    {
-        /** */
-        private ICache<object, string> _cache1;
-
-        /** */
-        private ICache<object, string> _cache2;
-
-        /// <summary>
-        /// Fixture set up.
-        /// </summary>
-        [TestFixtureSetUp]
-        public void FixtureSetUp()
-        {
-            var grid1 = Ignition.Start(GetConfig());
-            var grid2 = Ignition.Start(GetConfig("grid2"));
-
-            _cache1 = grid1.CreateCache<object, string>(new CacheConfiguration
-            {
-                CacheMode = CacheMode.Partitioned
-            });
-            _cache2 = grid2.GetCache<object, string>(null);
-        }
-
-        /// <summary>
-        /// Fixture tear down.
-        /// </summary>
-        [TestFixtureTearDown]
-        public void FixtureTearDown()
-        {
-            Ignition.StopAll(true);
-        }
-
-        /// <summary>
-        /// Tests the metadata.
-        /// </summary>
-        [Test]
-        public void TestMetadata()
-        {
-            // Put keys to update meta
-            _cache1.Put(new CacheKey(), string.Empty);
-            _cache1.Put(new CacheKeyAttr(), string.Empty);
-            _cache1.Put(new CacheKeyAttrOverride(), string.Empty);
-
-            // Verify
-            foreach (var type in new[] { typeof(CacheKey) , typeof(CacheKeyAttr), typeof(CacheKeyAttrOverride)})
-            {
-                Assert.AreEqual("AffinityKey", _cache1.Ignite.GetBinary().GetBinaryType(type).AffinityKeyFieldName);
-                Assert.AreEqual("AffinityKey", _cache2.Ignite.GetBinary().GetBinaryType(type).AffinityKeyFieldName);
-            }
-        }
-
-        /// <summary>
-        /// Tests that keys are located properly in cache partitions.
-        /// </summary>
-        [Test]
-        public void TestKeyLocation()
-        {
-            TestKeyLocation0((key, affKey) => new CacheKey {Key = key, AffinityKey = affKey});
-            TestKeyLocation0((key, affKey) => new CacheKeyAttr {Key = key, AffinityKey = affKey});
-            TestKeyLocation0((key, affKey) => new CacheKeyAttrOverride {Key = key, AffinityKey = affKey});
-        }
-
-        /// <summary>
-        /// Tests the <see cref="AffinityKey"/> class.
-        /// </summary>
-        [Test]
-        public void TestAffinityKeyClass()
-        {
-            // Check location
-            TestKeyLocation0((key, affKey) => new AffinityKey(key, affKey));
-
-            // Check meta
-            Assert.AreEqual("affKey",
-                _cache1.Ignite.GetBinary().GetBinaryType(typeof (AffinityKey)).AffinityKeyFieldName);
-        }
-
-        /// <summary>
-        /// Tests <see cref="AffinityKey"/> class interoperability.
-        /// </summary>
-        [Test]
-        public void TestInterop()
-        {
-            var affKey = _cache1.Ignite.GetCompute()
-                .ExecuteJavaTask<AffinityKey>(ComputeApiTest.EchoTask, ComputeApiTest.EchoTypeAffinityKey);
-
-            Assert.AreEqual("interopAffinityKey", affKey.Key);
-        }
-
-        /// <summary>
-        /// Tests the key location.
-        /// </summary>
-        private void TestKeyLocation0<T>(Func<int, int, T> ctor)
-        {
-            var aff = _cache1.Ignite.GetAffinity(_cache1.Name);
-
-            foreach (var cache in new[] { _cache1, _cache2 })
-            {
-                cache.RemoveAll();
-
-                var localNode = cache.Ignite.GetCluster().GetLocalNode();
-
-                var localKeys = Enumerable.Range(1, int.MaxValue)
-                    .Where(x => aff.MapKeyToNode(x).Id == localNode.Id).Take(100).ToArray();
-
-                for (int index = 0; index < localKeys.Length; index++)
-                {
-                    var cacheKey = ctor(index, localKeys[index]);
-
-                    cache.Put(cacheKey, index.ToString());
-
-                    // Verify that key is stored locally accroding to AffinityKeyFieldName
-                    Assert.AreEqual(index.ToString(), cache.LocalPeek(cacheKey, CachePeekMode.Primary));
-
-                    // Other cache does not have this key locally
-                    var otherCache = cache == _cache1 ? _cache2 : _cache1;
-                    Assert.Throws<KeyNotFoundException>(() => otherCache.LocalPeek(cacheKey, CachePeekMode.All));
-                }
-            }
-        }
-
-        /// <summary>
-        /// Gets the configuration.
-        /// </summary>
-        private static IgniteConfiguration GetConfig(string gridName = null)
-        {
-            return new IgniteConfiguration(TestUtils.GetTestConfiguration())
-            {
-                GridName = gridName,
-                BinaryConfiguration = new BinaryConfiguration
-                {
-                    TypeConfigurations = new[]
-                    {
-                        new BinaryTypeConfiguration(typeof (CacheKey))
-                        {
-                            AffinityKeyFieldName = "AffinityKey"
-                        },
-                        new BinaryTypeConfiguration(typeof(CacheKeyAttr)),
-                        new BinaryTypeConfiguration(typeof (CacheKeyAttrOverride))
-                        {
-                            AffinityKeyFieldName = "AffinityKey"
-                        }
-                    }
-                },
-            };
-        }
-
-        private class CacheKey
-        {
-            public int Key { get; set; }
-            public int AffinityKey { get; set; }
-        }
-
-        private class CacheKeyAttr
-        {
-            public int Key { get; set; }
-            [AffinityKeyMapped] public int AffinityKey { get; set; }
-        }
-
-        private class CacheKeyAttrOverride
-        {
-            [AffinityKeyMapped] public int Key { get; set; }
-            public int AffinityKey { get; set; }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAffinityTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAffinityTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAffinityTest.cs
deleted file mode 100644
index 689804c..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAffinityTest.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.
- */
-
-namespace Apache.Ignite.Core.Tests.Cache
-{
-    using Apache.Ignite.Core.Binary;
-    using Apache.Ignite.Core.Cache;
-    using Apache.Ignite.Core.Cluster;
-    using Apache.Ignite.Core.Impl;
-    using NUnit.Framework;
-
-    /// <summary>
-    /// Affinity key tests.
-    /// </summary>
-    public class CacheAffinityTest
-    {
-        /// <summary>
-        ///
-        /// </summary>
-        [TestFixtureSetUp]
-        public virtual void StartGrids()
-        {
-            TestUtils.KillProcesses();
-
-            IgniteConfiguration cfg = new IgniteConfiguration();
-
-            cfg.JvmClasspath = TestUtils.CreateTestClasspath();
-            cfg.JvmOptions = TestUtils.TestJavaOptions();
-            cfg.SpringConfigUrl = "config\\native-client-test-cache-affinity.xml";
-
-            for (int i = 0; i < 3; i++)
-            {
-                cfg.GridName = "grid-" + i;
-
-                Ignition.Start(cfg);
-            }
-        }
-
-        /// <summary>
-        /// Tear-down routine.
-        /// </summary>
-        [TestFixtureTearDown]
-        public virtual void StopGrids()
-        {
-            for (int i = 0; i < 3; i++)
-                Ignition.Stop("grid-" + i, true);
-        }
-
-        /// <summary>
-        /// Test affinity key.
-        /// </summary>
-        [Test]
-        public void TestAffinity()
-        {
-            IIgnite g = Ignition.GetIgnite("grid-0");
-
-            ICacheAffinity aff = g.GetAffinity(null);
-
-            IClusterNode node = aff.MapKeyToNode(new AffinityTestKey(0, 1));
-
-            for (int i = 0; i < 10; i++)
-                Assert.AreEqual(node.Id, aff.MapKeyToNode(new AffinityTestKey(i, 1)).Id);
-        }
-
-        /// <summary>
-        /// Test affinity with binary flag.
-        /// </summary>
-        [Test]
-        public void TestAffinityBinary()
-        {
-            IIgnite g = Ignition.GetIgnite("grid-0");
-
-            ICacheAffinity aff = g.GetAffinity(null);  
-
-            IBinaryObject affKey = g.GetBinary().ToBinary<IBinaryObject>(new AffinityTestKey(0, 1));
-
-            IClusterNode node = aff.MapKeyToNode(affKey);
-
-            for (int i = 0; i < 10; i++)
-            {
-                IBinaryObject otherAffKey =
-                    g.GetBinary().ToBinary<IBinaryObject>(new AffinityTestKey(i, 1));
-
-                Assert.AreEqual(node.Id, aff.MapKeyToNode(otherAffKey).Id);
-            }
-        }
-
-        /// <summary>
-        /// Affinity key.
-        /// </summary>
-        public class AffinityTestKey
-        {
-            /** ID. */
-            private int _id;
-
-            /** Affinity key. */
-            private int _affKey;
-
-            /// <summary>
-            /// Constructor.
-            /// </summary>
-            /// <param name="id">ID.</param>
-            /// <param name="affKey">Affinity key.</param>
-            public AffinityTestKey(int id, int affKey)
-            {
-                _id = id;
-                _affKey = affKey;
-            }
-
-            /** <inheritdoc /> */
-            public override bool Equals(object obj)
-            {
-                AffinityTestKey other = obj as AffinityTestKey;
-
-                return other != null && _id == other._id;
-            }
-
-            /** <inheritdoc /> */
-            public override int GetHashCode()
-            {
-                return _id;
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs
index eb73abe..da68ca2 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs
@@ -271,7 +271,7 @@ namespace Apache.Ignite.Core.Tests.Cache
             var py = (AffinityFunctionBase) y;
 
             Assert.AreEqual(px.GetType(), py.GetType());
-            Assert.AreEqual(px.PartitionCount, py.PartitionCount);
+            Assert.AreEqual(px.Partitions, py.Partitions);
             Assert.AreEqual(px.ExcludeNeighbors, py.ExcludeNeighbors);
         }
 
@@ -552,7 +552,7 @@ namespace Apache.Ignite.Core.Tests.Cache
                 },
                 AffinityFunction = new RendezvousAffinityFunction
                 {
-                    PartitionCount = 513,
+                    Partitions = 513,
                     ExcludeNeighbors = true
                 }
             };
@@ -645,7 +645,7 @@ namespace Apache.Ignite.Core.Tests.Cache
                 },
                 AffinityFunction = new FairAffinityFunction
                 {
-                    PartitionCount = 113,
+                    Partitions = 113,
                     ExcludeNeighbors = false
                 }
             };

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-affinity.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-affinity.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-affinity.xml
index 6fe3e70..9c7bfb0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-affinity.xml
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-affinity.xml
@@ -34,7 +34,7 @@
                             <list>
                                 <bean class="org.apache.ignite.platform.dotnet.PlatformDotNetBinaryTypeConfiguration">
                                     <property name="typeName"
-                                              value="Apache.Ignite.Core.Tests.Cache.CacheAffinityTest+AffinityTestKey"/>
+                                              value="Apache.Ignite.Core.Tests.Cache.Affinity.AffinityTest+AffinityTestKey"/>
                                     <property name="affinityKeyFieldName" value="_affKey"/>
                                 </bean>
                             </list>

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
index 3056273..e435cf6 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
@@ -97,7 +97,7 @@ namespace Apache.Ignite.Core.Tests
                                     <nearConfiguration nearStartSize='7'>
                                         <evictionPolicy type='FifoEvictionPolicy' batchSize='10' maxSize='20' maxMemorySize='30' />
                                     </nearConfiguration>
-                                    <affinityFunction type='RendezvousAffinityFunction' partitionCount='99' excludeNeighbors='true' />
+                                    <affinityFunction type='RendezvousAffinityFunction' partitions='99' excludeNeighbors='true' />
                                 </cacheConfiguration>
                                 <cacheConfiguration name='secondCache' />
                             </cacheConfiguration>
@@ -172,7 +172,7 @@ namespace Apache.Ignite.Core.Tests
 
             var af = cacheCfg.AffinityFunction as RendezvousAffinityFunction;
             Assert.IsNotNull(af);
-            Assert.AreEqual(99, af.PartitionCount);
+            Assert.AreEqual(99, af.Partitions);
             Assert.IsTrue(af.ExcludeNeighbors);
 
             Assert.AreEqual(new Dictionary<string, object> {{"myNode", "true"}}, cfg.UserAttributes);
@@ -365,6 +365,14 @@ namespace Apache.Ignite.Core.Tests
                             IdMapper = new IdMapper(),
                             NameMapper = new NameMapper(),
                             Serializer = new TestSerializer()
+                        },
+                        new BinaryTypeConfiguration
+                        {
+                            IsEnum = false,
+                            KeepDeserialized = false,
+                            AffinityKeyFieldName = "affKeyFieldName",
+                            TypeName = "typeName2",
+                            Serializer = new BinaryReflectiveSerializer()
                         }
                     },
                     Types = new[] {typeof (string).FullName},
@@ -448,7 +456,7 @@ namespace Apache.Ignite.Core.Tests
                         AffinityFunction = new FairAffinityFunction
                         {
                             ExcludeNeighbors = true,
-                            PartitionCount = 48
+                            Partitions = 48
                         }
                     }
                 },

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs
index c6274ff..726fa3b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestRunner.cs
@@ -22,6 +22,8 @@ namespace Apache.Ignite.Core.Tests
     using System.Linq;
     using System.Reflection;
     using Apache.Ignite.Core.Tests.Binary;
+    using Apache.Ignite.Core.Tests.Cache.Affinity;
+    using Apache.Ignite.Core.Tests.Cache.Query;
     using Apache.Ignite.Core.Tests.Memory;
     using NUnit.ConsoleRunner;
 
@@ -46,9 +48,9 @@ namespace Apache.Ignite.Core.Tests
                 return;
             }
 
-            TestOne(typeof(BinaryStringTest), "Test");
+            //TestOne(typeof(BinaryStringTest), "Test");
 
-            //TestAll(typeof (CacheQueriesCodeConfigurationTest));
+            TestAll(typeof (AffinityFunctionTest));
             //TestAllInAssembly();
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
index 46dbd94..e7f772f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -84,6 +84,8 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Binary\BinaryReflectiveSerializer.cs" />
+    <Compile Include="Cache\Affinity\AffinityTopologyVersion.cs" />
+    <Compile Include="Cache\Affinity\AffinityFunctionContext.cs" />
     <Compile Include="Impl\Binary\BinaryReflectiveSerializerInternal.cs" />
     <Compile Include="Impl\Binary\IBinarySerializerInternal.cs" />
     <Compile Include="Binary\Package-Info.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityFunctionBase.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityFunctionBase.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityFunctionBase.cs
index ea5b21c..9b89780 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityFunctionBase.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityFunctionBase.cs
@@ -18,10 +18,13 @@
 namespace Apache.Ignite.Core.Cache.Affinity
 {
     using System;
+    using System.Collections.Generic;
     using System.ComponentModel;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cache.Affinity.Fair;
     using Apache.Ignite.Core.Cache.Affinity.Rendezvous;
+    using Apache.Ignite.Core.Cluster;
+    using Apache.Ignite.Core.Common;
 
     /// <summary>
     /// Base class for predefined affinity functions.
@@ -37,14 +40,67 @@ namespace Apache.Ignite.Core.Cache.Affinity
         /** */
         private const byte TypeCodeRendezvous = 2;
 
-        /// <summary> The default value for <see cref="PartitionCount"/> property. </summary>
-        public const int DefaultPartitionCount = 1024;
+        /** */
+        private const byte TypeCodeUser = 3;
+
+        /// <summary> The default value for <see cref="Partitions"/> property. </summary>
+        public const int DefaultPartitions = 1024;
 
         /// <summary>
         /// Gets or sets the total number of partitions.
         /// </summary>
-        [DefaultValue(DefaultPartitionCount)]
-        public int PartitionCount { get; set; }
+        [DefaultValue(DefaultPartitions)]
+        public int Partitions { get; set; }
+
+        /// <summary>
+        /// Gets partition number for a given key starting from 0. Partitioned caches
+        /// should make sure that keys are about evenly distributed across all partitions
+        /// from 0 to <see cref="Partitions" /> for best performance.
+        /// <para />
+        /// Note that for fully replicated caches it is possible to segment key sets among different
+        /// grid node groups. In that case each node group should return a unique partition
+        /// number. However, unlike partitioned cache, mappings of keys to nodes in
+        /// replicated caches are constant and a node cannot migrate from one partition
+        /// to another.
+        /// </summary>
+        /// <param name="key">Key to get partition for.</param>
+        /// <returns>
+        /// Partition number for a given key.
+        /// </returns>
+        public int GetPartition(object key)
+        {
+            throw GetDirectUsageError();
+        }
+
+        /// <summary>
+        /// Removes node from affinity. This method is called when it is safe to remove
+        /// disconnected node from affinity mapping.
+        /// </summary>
+        /// <param name="nodeId">The node identifier.</param>
+        public void RemoveNode(Guid nodeId)
+        {
+            throw GetDirectUsageError();
+        }
+
+        /// <summary>
+        /// Gets affinity nodes for a partition. In case of replicated cache, all returned
+        /// nodes are updated in the same manner. In case of partitioned cache, the returned
+        /// list should contain only the primary and back up nodes with primary node being
+        /// always first.
+        /// <pare />
+        /// Note that partitioned affinity must obey the following contract: given that node
+        /// <code>N</code> is primary for some key <code>K</code>, if any other node(s) leave
+        /// grid and no node joins grid, node <code>N</code> will remain primary for key <code>K</code>.
+        /// </summary>
+        /// <param name="context">The affinity function context.</param>
+        /// <returns>
+        /// A collection of partitions, where each partition is a collection of nodes,
+        /// where first node is a primary node, and other nodes are backup nodes.
+        /// </returns>
+        public IEnumerable<IEnumerable<IClusterNode>> AssignPartitions(AffinityFunctionContext context)
+        {
+            throw GetDirectUsageError();
+        }
 
         /// <summary>
         /// Gets or sets a value indicating whether to exclude same-host-neighbors from being backups of each other.
@@ -56,7 +112,7 @@ namespace Apache.Ignite.Core.Cache.Affinity
         /// </summary>
         internal AffinityFunctionBase()
         {
-            PartitionCount = DefaultPartitionCount;
+            Partitions = DefaultPartitions;
         }
 
         /// <summary>
@@ -77,11 +133,16 @@ namespace Apache.Ignite.Core.Cache.Affinity
                 case TypeCodeRendezvous:
                     fun = new RendezvousAffinityFunction();
                     break;
+                case TypeCodeUser:
+                    var f = reader.ReadObject<IAffinityFunction>();
+                    reader.ReadInt(); // skip partition count
+
+                    return f;
                 default:
                     throw new InvalidOperationException("Invalid AffinityFunction type code: " + typeCode);
             }
 
-            fun.PartitionCount = reader.ReadInt();
+            fun.Partitions = reader.ReadInt();
             fun.ExcludeNeighbors = reader.ReadBoolean();
 
             return fun;
@@ -100,17 +161,30 @@ namespace Apache.Ignite.Core.Cache.Affinity
 
             var p = fun as AffinityFunctionBase;
 
-            if (p == null)
+            if (p != null)
             {
-                throw new NotSupportedException(
-                    string.Format("Unsupported AffinityFunction: {0}. Only predefined affinity function types " +
-                                  "are supported: {1}, {2}", fun.GetType(), typeof(FairAffinityFunction),
-                        typeof(RendezvousAffinityFunction)));
+                writer.WriteByte(p is FairAffinityFunction ? TypeCodeFair : TypeCodeRendezvous);
+                writer.WriteInt(p.Partitions);
+                writer.WriteBoolean(p.ExcludeNeighbors);
             }
+            else
+            {
+                writer.WriteByte(TypeCodeUser);
+
+                if (!fun.GetType().IsSerializable)
+                    throw new IgniteException("AffinityFunction should be serializable.");
 
-            writer.WriteByte(p is FairAffinityFunction ? TypeCodeFair : TypeCodeRendezvous);
-            writer.WriteInt(p.PartitionCount);
-            writer.WriteBoolean(p.ExcludeNeighbors);
+                writer.WriteObject(fun);
+                writer.WriteInt(fun.Partitions);  // partition count is written once and can not be changed.
+            }
+        }
+
+        /// <summary>
+        /// Gets the direct usage error.
+        /// </summary>
+        private Exception GetDirectUsageError()
+        {
+            return new IgniteException(GetType() + " can not be used directly.");
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e1c755c7/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityFunctionContext.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityFunctionContext.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityFunctionContext.cs
new file mode 100644
index 0000000..1f44d8c
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Affinity/AffinityFunctionContext.cs
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Cache.Affinity
+{
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Cluster;
+    using Apache.Ignite.Core.Events;
+    using Apache.Ignite.Core.Impl;
+
+    /// <summary>
+    /// Affinity function context.
+    /// </summary>
+    public class AffinityFunctionContext
+    {
+        /** */
+        private readonly List<List<IClusterNode>> _previousAssignment;
+
+        /** */
+        private readonly int _backups;
+
+        /** */
+        private readonly ICollection<IClusterNode> _currentTopologySnapshot;
+
+        /** */
+        private readonly AffinityTopologyVersion _currentTopologyVersion;
+
+        /** */
+        private readonly DiscoveryEvent _discoveryEvent;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="AffinityFunctionContext"/> class.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        internal AffinityFunctionContext(IBinaryRawReader reader)
+        {
+            var cnt = reader.ReadInt();
+
+            if (cnt > 0)
+            {
+                _previousAssignment = new List<List<IClusterNode>>(cnt);
+
+                for (var i = 0; i < cnt; i++)
+                    _previousAssignment.Add(IgniteUtils.ReadNodes(reader));
+            }
+
+            _backups = reader.ReadInt();
+            _currentTopologySnapshot = IgniteUtils.ReadNodes(reader);
+            _currentTopologyVersion = new AffinityTopologyVersion(reader.ReadLong(), reader.ReadInt());
+            _discoveryEvent = EventReader.Read<DiscoveryEvent>(reader);
+        }
+
+        /// <summary>
+        /// Gets the affinity assignment for given partition on previous topology version.
+        /// First node in returned list is a primary node, other nodes are backups.
+        /// </summary>
+        /// <param name="partition">The partition to get previous assignment for.</param>
+        /// <returns>
+        /// List of nodes assigned to a given partition on previous topology version or <code>null</code>
+        /// if this information is not available.
+        /// </returns>
+        public ICollection<IClusterNode> GetPreviousAssignment(int partition)
+        {
+            return _previousAssignment == null ? null : _previousAssignment[partition];
+        }
+
+        /// <summary>
+        /// Gets number of backups for new assignment.
+        /// </summary>
+        public int Backups
+        {
+            get { return _backups; }
+        }
+
+        /// <summary>
+        /// Gets the current topology snapshot. Snapshot will contain only nodes on which the particular
+        /// cache is configured. List of passed nodes is guaranteed to be sorted in a same order
+        /// on all nodes on which partition assignment is performed.
+        /// </summary>
+        public ICollection<IClusterNode> CurrentTopologySnapshot
+        {
+            get { return _currentTopologySnapshot; }
+        }
+
+        /// <summary>
+        /// Gets the current topology version.
+        /// </summary>
+        public AffinityTopologyVersion CurrentTopologyVersion
+        {
+            get { return _currentTopologyVersion; }
+        }
+
+        /// <summary>
+        /// Gets the discovery event that caused the topology change.
+        /// </summary>
+        public DiscoveryEvent DiscoveryEvent
+        {
+            get { return _discoveryEvent; }
+        }
+    }
+}
\ No newline at end of file


[06/50] [abbrv] ignite git commit: IGNITE-3326 Map-reduce query waits for rebalancing forever when it's disabled. - Fixes #813.

Posted by sb...@apache.org.
IGNITE-3326 Map-reduce query waits for rebalancing forever when it's disabled. - Fixes #813.

Signed-off-by: Sergi Vladykin <se...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f238b760
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f238b760
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f238b760

Branch: refs/heads/ignite-1232
Commit: f238b760b683a0fe75132e84d37f2a4f3cf32086
Parents: 54bd923
Author: ascherbakoff <al...@gmail.com>
Authored: Tue Jun 21 08:25:56 2016 +0300
Committer: Sergi Vladykin <se...@gmail.com>
Committed: Tue Jun 21 08:25:56 2016 +0300

----------------------------------------------------------------------
 .../ignite/internal/GridGetOrStartSelfTest.java | 70 +++++++++++++++++
 .../query/h2/twostep/GridMapQueryExecutor.java  |  2 +-
 .../IgniteCacheQueryNoRebalanceSelfTest.java    | 82 ++++++++++++++++++++
 .../IgniteCacheQuerySelfTestSuite.java          |  2 +
 4 files changed, 155 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/f238b760/modules/core/src/test/java/org/apache/ignite/internal/GridGetOrStartSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/GridGetOrStartSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/GridGetOrStartSelfTest.java
new file mode 100644
index 0000000..26d98ba
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/GridGetOrStartSelfTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal;
+
+import org.apache.ignite.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.testframework.junits.common.*;
+
+/**
+ * The GirdGetOrStartSelfTest tests get or start semantics. See IGNITE-2941
+ */
+
+@GridCommonTest(group = "Kernal Self")
+public class GridGetOrStartSelfTest extends GridCommonAbstractTest {
+    /**
+     * Default constructor.
+     */
+    public GridGetOrStartSelfTest() {
+        super(false);
+    }
+
+    /**
+     * Tests default grid
+     */
+    public void testDefaultGridGetOrStart() throws Exception {
+        IgniteConfiguration cfg = getConfiguration(null);
+        try(Ignite ignite = Ignition.getOrStart(cfg)) {
+            try {
+                Ignition.start(cfg);
+                fail("Expected exception after grid started");
+            }
+            catch (IgniteException ignored) {
+            }
+            Ignite ignite2 = Ignition.getOrStart(cfg);
+            assertEquals("Must return same instance", ignite, ignite2);
+        }
+    }
+
+    /**
+     * Tests named grid
+     */
+    public void testNamedGridGetOrStart() throws Exception {
+        IgniteConfiguration cfg = getConfiguration("test");
+        try(Ignite ignite = Ignition.getOrStart(cfg)) {
+            try {
+                Ignition.start(cfg);
+                fail("Expected exception after grid started");
+            }
+            catch (IgniteException ignored) {
+            }
+            Ignite ignite2 = Ignition.getOrStart(cfg);
+            assertEquals("Must return same instance", ignite, ignite2);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f238b760/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
index 3d226e5..580058c 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
@@ -277,7 +277,7 @@ public class GridMapQueryExecutor {
             if (cctx == null) // Cache was not found, probably was not deployed yet.
                 return false;
 
-            if (cctx.isLocal())
+            if (cctx.isLocal() || !cctx.rebalanceEnabled())
                 continue;
 
             // For replicated cache topology version does not make sense.

http://git-wip-us.apache.org/repos/asf/ignite/blob/f238b760/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCacheQueryNoRebalanceSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCacheQueryNoRebalanceSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCacheQueryNoRebalanceSelfTest.java
new file mode 100644
index 0000000..ac96cc5
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCacheQueryNoRebalanceSelfTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed.near;
+
+import javax.cache.Cache;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheRebalanceMode;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * Test added to check for https://issues.apache.org/jira/browse/IGNITE-3326.
+ */
+public class IgniteCacheQueryNoRebalanceSelfTest extends GridCommonAbstractTest {
+    /** */
+    private static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
+
+    /**
+     *
+     */
+    public IgniteCacheQueryNoRebalanceSelfTest() {
+        super(true);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration() throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration();
+
+        ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(ipFinder);
+
+        CacheConfiguration<Integer, Integer> ccfg = new CacheConfiguration<>();
+        ccfg.setBackups(0);
+        ccfg.setIndexedTypes(Integer.class, Integer.class);
+        ccfg.setRebalanceMode(CacheRebalanceMode.NONE);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+
+        super.afterTestsStopped();
+    }
+
+    /**
+     * Tests correct query execution with disabled re-balancing.
+     */
+    public void testQueryNoRebalance() {
+        IgniteCache<Object, Object> cache = grid().cache(null);
+
+        cache.put(1, 1);
+
+        QueryCursor<Cache.Entry<Integer, Integer>> qry =
+            cache.query(new SqlQuery<Integer, Integer>(Integer.class, "_key >= 0"));
+
+        assertEquals("Bad results count", 1, qry.getAll().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f238b760/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index 7b39453..1b1908d 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -47,6 +47,7 @@ import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheC
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCachePartitionedQueryP2PDisabledSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCachePartitionedQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCachePartitionedSnapshotEnabledQuerySelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNoRebalanceSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeFailTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeRestartSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeRestartSelfTest2;
@@ -113,6 +114,7 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
         suite.addTestSuite(IgniteBinaryObjectFieldsQuerySelfTest.class);
         suite.addTestSuite(IgniteBinaryWrappedObjectFieldsQuerySelfTest.class);
         suite.addTestSuite(IgniteCacheQueryH2IndexingLeakTest.class);
+        suite.addTestSuite(IgniteCacheQueryNoRebalanceSelfTest.class);
 
         return suite;
     }


[39/50] [abbrv] ignite git commit: Ignite Web Console beta2.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/controllers/domains-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/controllers/domains-controller.js b/modules/web-console/src/main/js/controllers/domains-controller.js
index 5483560..467dc98 100644
--- a/modules/web-console/src/main/js/controllers/domains-controller.js
+++ b/modules/web-console/src/main/js/controllers/domains-controller.js
@@ -20,14 +20,14 @@ import consoleModule from 'controllers/common-module';
 
 consoleModule.controller('domainsController', [
     '$rootScope', '$scope', '$http', '$state', '$filter', '$timeout', '$modal', '$common', '$focus', '$confirm', '$confirmBatch', '$clone', '$loading', '$cleanup', '$unsavedChangesGuard', 'IgniteAgentMonitor', '$table',
-    function ($root, $scope, $http, $state, $filter, $timeout, $modal, $common, $focus, $confirm, $confirmBatch, $clone, $loading, $cleanup, $unsavedChangesGuard, IgniteAgentMonitor, $table) {
+    function($root, $scope, $http, $state, $filter, $timeout, $modal, $common, $focus, $confirm, $confirmBatch, $clone, $loading, $cleanup, $unsavedChangesGuard, IgniteAgentMonitor, $table) {
         $unsavedChangesGuard.install($scope);
 
-        var emptyDomain = {empty: true};
+        const emptyDomain = {empty: true};
 
-        var __original_value;
+        let __original_value;
 
-        var blank = {};
+        const blank = {};
 
         // We need to initialize backupItem with empty object in order to properly used from angular directives.
         $scope.backupItem = emptyDomain;
@@ -36,8 +36,8 @@ consoleModule.controller('domainsController', [
         $scope.ui.activePanels = [0, 1];
         $scope.ui.topPanels = [0, 1, 2];
 
-        var IMPORT_DM_NEW_CACHE = 1;
-        var IMPORT_DM_ASSOCIATE_CACHE = 2;
+        const IMPORT_DM_NEW_CACHE = 1;
+        const IMPORT_DM_ASSOCIATE_CACHE = 2;
 
         /**
          * Convert some name to valid java package name.
@@ -46,7 +46,7 @@ consoleModule.controller('domainsController', [
          * @returns {string} Valid java package name.
          */
         const _toJavaPackage = (name) => {
-            return name ? name.replace(/[^A-Za-z_0-9/.]+/g, '_') : 'org'
+            return name ? name.replace(/[^A-Za-z_0-9/.]+/g, '_') : 'org';
         };
 
         $scope.ui.packageNameUserInput = $scope.ui.packageName =
@@ -57,17 +57,13 @@ consoleModule.controller('domainsController', [
         $scope.ui.generatedCachesClusters = [];
 
         function _mapCaches(caches) {
-            return _.map(caches, function (cache) {
-                return {
-                    label: cache.name,
-                    value: cache._id,
-                    cache: cache
-                }
+            return _.map(caches, (cache) => {
+                return {label: cache.name, value: cache._id, cache};
             });
         }
 
-        $scope.contentVisible = function () {
-            var item = $scope.backupItem;
+        $scope.contentVisible = function() {
+            const item = $scope.backupItem;
 
             return !item.empty && (!item._id || _.find($scope.displayedRows, {_id: item._id}));
         };
@@ -78,7 +74,7 @@ consoleModule.controller('domainsController', [
         $scope.widthIsSufficient = $common.widthIsSufficient;
         $scope.saveBtnTipText = $common.saveBtnTipText;
 
-        $scope.tableSave = function (field, index, stopEdit) {
+        $scope.tableSave = function(field, index, stopEdit) {
             if ($table.tableEditing({model: 'table-index-fields'}, $table.tableEditedRowIndex())) {
                 if ($scope.tableIndexItemSaveVisible(field, index))
                     return $scope.tableIndexItemSave(field, field.indexIdx, index, stopEdit);
@@ -103,57 +99,77 @@ consoleModule.controller('domainsController', [
                             return $scope.tableDbFieldSave(field, index, stopEdit);
 
                         break;
+
+                    default:
                 }
             }
 
             return true;
         };
 
-        $scope.tableReset = function (save) {
-            var field = $table.tableField();
+        $scope.tableReset = (trySave) => {
+            const field = $table.tableField();
 
-            if (!save || !$common.isDefined(field) || $scope.tableSave(field, $table.tableEditedRowIndex(), true)) {
-                $table.tableReset();
+            if (trySave && $common.isDefined(field) && !$scope.tableSave(field, $table.tableEditedRowIndex(), true))
+                return false;
 
-                return true;
-            }
+            $table.tableReset();
 
-            return false;
+            return true;
         };
 
-        $scope.tableNewItem = function (field) {
+        $scope.tableNewItem = function(field) {
             if ($scope.tableReset(true))
                 $table.tableNewItem(field);
         };
 
         $scope.tableNewItemActive = $table.tableNewItemActive;
 
-        $scope.tableStartEdit = function (item, field, index) {
+        $scope.tableStartEdit = function(item, field, index) {
             if ($scope.tableReset(true))
-                $table.tableStartEdit(item, field, index);
+                $table.tableStartEdit(item, field, index, $scope.tableSave);
         };
 
         $scope.tableEditing = $table.tableEditing;
 
-        $scope.tableRemove = function (item, field, index) {
+        $scope.tableRemove = function(item, field, index) {
             if ($scope.tableReset(true))
                 $table.tableRemove(item, field, index);
         };
 
-        $scope.tablePairStartEdit = $table.tablePairStartEdit;
         $scope.tablePairSave = $table.tablePairSave;
         $scope.tablePairSaveVisible = $table.tablePairSaveVisible;
 
+        $scope.queryFieldsTbl = {
+            type: 'fields',
+            model: 'fields',
+            focusId: 'QryField',
+            ui: 'table-pair',
+            keyName: 'name',
+            valueName: 'className',
+            save: $scope.tableSave
+        };
+
+        $scope.aliasesTbl = {
+            type: 'aliases',
+            model: 'aliases',
+            focusId: 'Alias',
+            ui: 'table-pair',
+            keyName: 'field',
+            valueName: 'alias',
+            save: $scope.tableSave
+        };
+
         $scope.queryMetadataVariants = $common.mkOptions(['Annotations', 'Configuration']);
 
-        var INFO_CONNECT_TO_DB = 'Configure connection to database';
-        var INFO_SELECT_SCHEMAS = 'Select schemas to load tables from';
-        var INFO_SELECT_TABLES = 'Select tables to import as domain model';
-        var INFO_SELECT_OPTIONS = 'Select import domain model options';
-        var LOADING_JDBC_DRIVERS = {text: 'Loading JDBC drivers...'};
-        var LOADING_SCHEMAS = {text: 'Loading schemas...'};
-        var LOADING_TABLES = {text: 'Loading tables...'};
-        var SAVING_DOMAINS = {text: 'Saving domain model...'};
+        const INFO_CONNECT_TO_DB = 'Configure connection to database';
+        const INFO_SELECT_SCHEMAS = 'Select schemas to load tables from';
+        const INFO_SELECT_TABLES = 'Select tables to import as domain model';
+        const INFO_SELECT_OPTIONS = 'Select import domain model options';
+        const LOADING_JDBC_DRIVERS = {text: 'Loading JDBC drivers...'};
+        const LOADING_SCHEMAS = {text: 'Loading schemas...'};
+        const LOADING_TABLES = {text: 'Loading tables...'};
+        const SAVING_DOMAINS = {text: 'Saving domain model...'};
 
         $scope.ui.invalidKeyFieldsTooltip = 'Found key types without configured key fields<br/>' +
             'It may be a result of import tables from database without primary keys<br/>' +
@@ -161,11 +177,11 @@ consoleModule.controller('domainsController', [
 
         $scope.hidePopover = $common.hidePopover;
 
-        var showPopoverMessage = $common.showPopoverMessage;
+        const showPopoverMessage = $common.showPopoverMessage;
 
         $scope.indexType = $common.mkOptions(['SORTED', 'FULLTEXT', 'GEOSPATIAL']);
 
-        var _dbPresets = [
+        const _dbPresets = [
             {
                 db: 'Oracle',
                 jdbcDriverClass: 'oracle.jdbc.OracleDriver',
@@ -224,10 +240,10 @@ consoleModule.controller('domainsController', [
 
         function _loadPresets() {
             try {
-                var restoredPresets = JSON.parse(localStorage.dbPresets);
+                const restoredPresets = JSON.parse(localStorage.dbPresets);
 
-                _.forEach(restoredPresets, function (restoredPreset) {
-                    var preset = _.find(_dbPresets, {jdbcDriverClass: restoredPreset.jdbcDriverClass});
+                _.forEach(restoredPresets, (restoredPreset) => {
+                    const preset = _.find(_dbPresets, {jdbcDriverClass: restoredPreset.jdbcDriverClass});
 
                     if (preset) {
                         preset.jdbcUrl = restoredPreset.jdbcUrl;
@@ -244,7 +260,7 @@ consoleModule.controller('domainsController', [
 
         function _savePreset(preset) {
             try {
-                var oldPreset = _.find(_dbPresets, {jdbcDriverClass: preset.jdbcDriverClass});
+                const oldPreset = _.find(_dbPresets, {jdbcDriverClass: preset.jdbcDriverClass});
 
                 if (oldPreset)
                     angular.extend(oldPreset, preset);
@@ -258,11 +274,25 @@ consoleModule.controller('domainsController', [
             }
         }
 
-        $scope.$watch('ui.selectedJdbcDriverJar', function (val) {
+        function _findPreset(selectedJdbcJar) {
+            let result = _.find(_dbPresets, function(preset) {
+                return preset.jdbcDriverClass === selectedJdbcJar.jdbcDriverClass;
+            });
+
+            if (!result)
+                result = {db: 'General', jdbcUrl: 'jdbc:[database]', user: 'admin'};
+
+            result.jdbcDriverJar = selectedJdbcJar.jdbcDriverJar;
+            result.jdbcDriverClass = selectedJdbcJar.jdbcDriverClass;
+
+            return result;
+        }
+
+        $scope.$watch('ui.selectedJdbcDriverJar', function(val) {
             if (val && !$scope.importDomain.demo) {
-                var foundPreset = _findPreset(val);
+                const foundPreset = _findPreset(val);
 
-                var selectedPreset = $scope.selectedPreset;
+                const selectedPreset = $scope.selectedPreset;
 
                 selectedPreset.db = foundPreset.db;
                 selectedPreset.jdbcDriverJar = foundPreset.jdbcDriverJar;
@@ -274,24 +304,6 @@ consoleModule.controller('domainsController', [
 
         $scope.ui.showValid = true;
 
-        function _findPreset(selectedJdbcJar) {
-            var result = _.find(_dbPresets, function (preset) {
-                return preset.jdbcDriverClass === selectedJdbcJar.jdbcDriverClass;
-            });
-
-            if (!result)
-                result = {
-                    db: 'General',
-                    jdbcUrl: 'jdbc:[database]',
-                    user: 'admin'
-                };
-
-            result.jdbcDriverJar = selectedJdbcJar.jdbcDriverJar;
-            result.jdbcDriverClass = selectedJdbcJar.jdbcDriverClass;
-
-            return result;
-        }
-
         $scope.supportedJdbcTypes = $common.mkOptions($common.SUPPORTED_JDBC_TYPES);
 
         $scope.supportedJavaTypes = $common.mkOptions($common.javaBuiltInTypes);
@@ -303,8 +315,8 @@ consoleModule.controller('domainsController', [
 
         $scope.domains = [];
 
-        $scope.isJavaBuiltInClass = function () {
-            var item = $scope.backupItem;
+        $scope.isJavaBuiltInClass = function() {
+            const item = $scope.backupItem;
 
             if (item && item.keyType)
                 return $common.isJavaBuiltInClass(item.keyType);
@@ -312,32 +324,28 @@ consoleModule.controller('domainsController', [
             return false;
         };
 
-        $scope.selectAllSchemas = function () {
-            var allSelected = $scope.importDomain.allSchemasSelected;
+        $scope.selectAllSchemas = function() {
+            const allSelected = $scope.importDomain.allSchemasSelected;
 
-            _.forEach($scope.importDomain.displayedSchemas, function (schema) {
-                schema.use = allSelected;
-            });
+            _.forEach($scope.importDomain.displayedSchemas, (schema) => schema.use = allSelected);
         };
 
-        $scope.selectSchema = function () {
+        $scope.selectSchema = function() {
             if ($common.isDefined($scope.importDomain) && $common.isDefined($scope.importDomain.displayedSchemas))
-                $scope.importDomain.allSchemasSelected = $scope.importDomain.displayedSchemas.length > 0 &&
-                    _.every($scope.importDomain.displayedSchemas, 'use', true);
+                $scope.importDomain.allSchemasSelected = $scope.importDomain.displayedSchemas.length > 0 && _.every($scope.importDomain.displayedSchemas, 'use', true);
         };
 
-        $scope.selectAllTables = function () {
-            var allSelected = $scope.importDomain.allTablesSelected;
+        $scope.selectAllTables = function() {
+            const allSelected = $scope.importDomain.allTablesSelected;
 
-            _.forEach($scope.importDomain.displayedTables, function (table) {
+            _.forEach($scope.importDomain.displayedTables, function(table) {
                 table.use = allSelected;
             });
         };
 
-        $scope.selectTable = function () {
+        $scope.selectTable = function() {
             if ($common.isDefined($scope.importDomain) && $common.isDefined($scope.importDomain.displayedTables))
-                $scope.importDomain.allTablesSelected = $scope.importDomain.displayedTables.length > 0 &&
-                    _.every($scope.importDomain.displayedTables, 'use', true);
+                $scope.importDomain.allTablesSelected = $scope.importDomain.displayedTables.length > 0 && _.every($scope.importDomain.displayedTables, 'use', true);
         };
 
         $scope.$watch('importDomain.displayedSchemas', $scope.selectSchema);
@@ -345,30 +353,41 @@ consoleModule.controller('domainsController', [
         $scope.$watch('importDomain.displayedTables', $scope.selectTable);
 
         // Pre-fetch modal dialogs.
-        var importDomainModal = $modal({scope: $scope, templateUrl: '/configuration/domains-import.html', show: false});
+        const importDomainModal = $modal({scope: $scope, templateUrl: '/configuration/domains-import.html', show: false});
 
-        var hideImportDomain = importDomainModal.hide;
+        const hideImportDomain = importDomainModal.hide;
 
-        importDomainModal.hide = function () {
+        importDomainModal.hide = function() {
             IgniteAgentMonitor.stopWatch();
 
             hideImportDomain();
         };
 
+        $scope.linkId = () => $scope.backupItem._id ? $scope.backupItem._id : 'create';
+
+        function prepareNewItem(cacheId) {
+            return {
+                space: $scope.spaces[0]._id,
+                caches: cacheId && _.find($scope.caches, {value: cacheId}) ? [cacheId] : // eslint-disable-line no-nested-ternary
+                    (_.isEmpty($scope.caches) ? [] : [$scope.caches[0].value]),
+                queryMetadata: 'Configuration'
+            };
+        }
+
         /**
          * Show import domain models modal.
          */
-        $scope.showImportDomainModal = function () {
+        $scope.showImportDomainModal = function() {
             $table.tableReset();
 
-            $common.confirmUnsavedChanges($scope.ui.inputForm.$dirty, function () {
+            $common.confirmUnsavedChanges($scope.ui.inputForm.$dirty, function() {
                 if ($scope.ui.inputForm.$dirty)
                     $scope.backupItem = $scope.selectedItem ? angular.copy($scope.selectedItem) : prepareNewItem();
 
                 const demo = $root.IgniteDemoMode;
 
                 $scope.importDomain = {
-                    demo: demo,
+                    demo,
                     action: demo ? 'connect' : 'drivers',
                     jdbcDriversNotFound: demo,
                     schemas: [],
@@ -381,10 +400,7 @@ consoleModule.controller('domainsController', [
 
                 $scope.importDomain.loadingOptions = LOADING_JDBC_DRIVERS;
 
-                IgniteAgentMonitor.startWatch({
-                        text: 'Back to Domain models',
-                        goal: 'import domain model from database'
-                    })
+                IgniteAgentMonitor.startWatch({text: 'Back to Domain models', goal: 'import domain model from database'})
                     .then(function() {
                         importDomainModal.$promise.then(importDomainModal.show);
 
@@ -408,7 +424,7 @@ consoleModule.controller('domainsController', [
                                 if (drivers && drivers.length > 0) {
                                     drivers = _.sortBy(drivers, 'jdbcDriverJar');
 
-                                    _.forEach(drivers, function (drv) {
+                                    _.forEach(drivers, function(drv) {
                                         $scope.jdbcDriverJars.push({
                                             label: drv.jdbcDriverJar,
                                             value: {
@@ -420,8 +436,8 @@ consoleModule.controller('domainsController', [
 
                                     $scope.ui.selectedJdbcDriverJar = $scope.jdbcDriverJars[0].value;
 
-                                    $common.confirmUnsavedChanges($scope.ui.inputForm.$dirty, function () {
-                                        importDomainModal.$promise.then(function () {
+                                    $common.confirmUnsavedChanges($scope.ui.inputForm.$dirty, function() {
+                                        importDomainModal.$promise.then(() => {
                                             $scope.importDomain.action = 'connect';
                                             $scope.importDomain.tables = [];
 
@@ -434,12 +450,12 @@ consoleModule.controller('domainsController', [
                                     $scope.importDomain.button = 'Cancel';
                                 }
                             })
-                            .finally(function () {
+                            .finally(function() {
                                 $scope.importDomain.info = INFO_CONNECT_TO_DB;
 
                                 $loading.finish('importDomainFromDb');
                             });
-                    })
+                    });
             });
         };
 
@@ -459,10 +475,10 @@ consoleModule.controller('domainsController', [
 
                     _savePreset(preset);
 
-                    return IgniteAgentMonitor.schemas(preset)
+                    return IgniteAgentMonitor.schemas(preset);
                 })
                 .then(function(schemas) {
-                    $scope.importDomain.schemas = _.map(schemas, function (schema) {
+                    $scope.importDomain.schemas = _.map(schemas, function(schema) {
                         return {use: true, name: schema};
                     });
 
@@ -476,12 +492,12 @@ consoleModule.controller('domainsController', [
                 .catch(function(errMsg) {
                     $common.showError(errMsg);
                 })
-                .finally(function () {
+                .finally(function() {
                     $loading.finish('importDomainFromDb');
                 });
         }
 
-        var DFLT_PARTITIONED_CACHE = {
+        const DFLT_PARTITIONED_CACHE = {
             label: 'PARTITIONED',
             value: -1,
             cache: {
@@ -493,7 +509,7 @@ consoleModule.controller('domainsController', [
             }
         };
 
-        var DFLT_REPLICATED_CACHE = {
+        const DFLT_REPLICATED_CACHE = {
             label: 'REPLICATED',
             value: -2,
             cache: {
@@ -505,8 +521,10 @@ consoleModule.controller('domainsController', [
             }
         };
 
+        let _importCachesOrTemplates = [];
+
         $scope.tableActionView = function(tbl) {
-            var cacheName = _.find(_importCachesOrTemplates, {value: tbl.cacheOrTemplate}).label;
+            const cacheName = _.find(_importCachesOrTemplates, {value: tbl.cacheOrTemplate}).label;
 
             if (tbl.action === IMPORT_DM_NEW_CACHE)
                 return 'Create ' + tbl.generatedCacheName + ' (' + cacheName + ')';
@@ -514,6 +532,61 @@ consoleModule.controller('domainsController', [
             return 'Associate with ' + cacheName;
         };
 
+        function toJavaClassName(name) {
+            const len = name.length;
+
+            let buf = '';
+
+            let capitalizeNext = true;
+
+            for (let i = 0; i < len; i++) {
+                const ch = name.charAt(i);
+
+                if (ch === ' ' || ch === '_')
+                    capitalizeNext = true;
+                else if (capitalizeNext) {
+                    buf += ch.toLocaleUpperCase();
+
+                    capitalizeNext = false;
+                }
+                else
+                    buf += ch.toLocaleLowerCase();
+            }
+
+            return buf;
+        }
+
+        function toJavaName(dbName) {
+            const javaName = toJavaClassName(dbName);
+
+            return javaName.charAt(0).toLocaleLowerCase() + javaName.slice(1);
+        }
+
+        function _fillCommonCachesOrTemplates(item) {
+            return function(action) {
+                if (item.cachesOrTemplates)
+                    item.cachesOrTemplates.length = 0;
+                else
+                    item.cachesOrTemplates = [];
+
+                if (action === IMPORT_DM_NEW_CACHE) {
+                    item.cachesOrTemplates.push(DFLT_PARTITIONED_CACHE);
+                    item.cachesOrTemplates.push(DFLT_REPLICATED_CACHE);
+                }
+
+                if (!_.isEmpty($scope.caches)) {
+                    if (item.cachesOrTemplates.length > 0)
+                        item.cachesOrTemplates.push(null);
+
+                    _.forEach($scope.caches, function(cache) {
+                        item.cachesOrTemplates.push(cache);
+                    });
+                }
+
+                if (!_.find(item.cachesOrTemplates, {value: item.cacheOrTemplate}))
+                    item.cacheOrTemplate = item.cachesOrTemplates[0].value;
+            };
+        }
         /**
          * Load list of database tables.
          */
@@ -525,30 +598,30 @@ consoleModule.controller('domainsController', [
 
                     $scope.importDomain.allTablesSelected = false;
 
-                    var preset = $scope.importDomain.demo ? $scope.demoConnection : $scope.selectedPreset;
+                    const preset = $scope.importDomain.demo ? $scope.demoConnection : $scope.selectedPreset;
 
                     preset.schemas = [];
 
-                    _.forEach($scope.importDomain.schemas, function (schema) {
+                    _.forEach($scope.importDomain.schemas, function(schema) {
                         if (schema.use)
                             preset.schemas.push(schema.name);
                     });
 
                     return IgniteAgentMonitor.tables(preset);
                 })
-                .then(function (tables) {
+                .then(function(tables) {
                     _importCachesOrTemplates = [DFLT_PARTITIONED_CACHE, DFLT_REPLICATED_CACHE].concat($scope.caches);
 
                     _fillCommonCachesOrTemplates($scope.importCommon)($scope.importCommon.action);
 
-                    _.forEach(tables, function (tbl, idx) {
+                    _.forEach(tables, function(tbl, idx) {
                         tbl.id = idx;
                         tbl.action = IMPORT_DM_NEW_CACHE;
                         tbl.generatedCacheName = toJavaClassName(tbl.tbl) + 'Cache';
                         tbl.cacheOrTemplate = DFLT_PARTITIONED_CACHE.value;
                         tbl.label = tbl.schema + '.' + tbl.tbl;
                         tbl.edit = false;
-                        tbl.use = $common.isDefined(_.find(tbl.cols, function (col) {
+                        tbl.use = $common.isDefined(_.find(tbl.cols, function(col) {
                             return col.key;
                         }));
                     });
@@ -560,13 +633,13 @@ consoleModule.controller('domainsController', [
                 .catch(function(errMsg) {
                     $common.showError(errMsg);
                 })
-                .finally(function () {
+                .finally(function() {
                     $loading.finish('importDomainFromDb');
                 });
         }
 
-        $scope.applyDefaults = function () {
-            _.forEach($scope.importDomain.displayedTables, function (table) {
+        $scope.applyDefaults = function() {
+            _.forEach($scope.importDomain.displayedTables, function(table) {
                 table.edit = false;
                 table.action = $scope.importCommon.action;
                 table.cacheOrTemplate = $scope.importCommon.cacheOrTemplate;
@@ -575,7 +648,7 @@ consoleModule.controller('domainsController', [
 
         $scope._curDbTable = null;
 
-        $scope.startEditDbTableCache = function (tbl) {
+        $scope.startEditDbTableCache = function(tbl) {
             if ($scope._curDbTable) {
                 $scope._curDbTable.edit = false;
 
@@ -588,7 +661,7 @@ consoleModule.controller('domainsController', [
 
             $scope._curDbTable = tbl;
 
-            var _fillFn = _fillCommonCachesOrTemplates($scope._curDbTable);
+            const _fillFn = _fillCommonCachesOrTemplates($scope._curDbTable);
 
             _fillFn($scope._curDbTable.action);
 
@@ -604,36 +677,8 @@ consoleModule.controller('domainsController', [
             $scope.importDomain.action = 'options';
             $scope.importDomain.button = 'Save';
             $scope.importDomain.info = INFO_SELECT_OPTIONS;
-        }
-
-        function toJavaClassName(name) {
-            var len = name.length;
-
-            var buf = '';
-
-            var capitalizeNext = true;
 
-            for (var i = 0; i < len; i++) {
-                var ch = name.charAt(i);
-
-                if (ch === ' ' || ch === '_')
-                    capitalizeNext = true;
-                else if (capitalizeNext) {
-                    buf += ch.toLocaleUpperCase();
-
-                    capitalizeNext = false;
-                }
-                else
-                    buf += ch.toLocaleLowerCase();
-            }
-
-            return buf;
-        }
-
-        function toJavaName(dbName) {
-            var javaName = toJavaClassName(dbName);
-
-            return javaName.charAt(0).toLocaleLowerCase() + javaName.slice(1);
+            $focus('domainPackageName');
         }
 
         function _saveBatch(batch) {
@@ -642,16 +687,16 @@ consoleModule.controller('domainsController', [
                 $loading.start('importDomainFromDb');
 
                 $http.post('/api/v1/configuration/domains/save/batch', batch)
-                    .success(function (savedBatch) {
-                        var lastItem;
-                        var newItems = [];
+                    .success(function(savedBatch) {
+                        let lastItem;
+                        const newItems = [];
 
                         _.forEach(_mapCaches(savedBatch.generatedCaches), function(cache) {
                             $scope.caches.push(cache);
                         });
 
-                        _.forEach(savedBatch.savedDomains, function (savedItem) {
-                            var idx = _.findIndex($scope.domains, function (domain) {
+                        _.forEach(savedBatch.savedDomains, function(savedItem) {
+                            const idx = _.findIndex($scope.domains, function(domain) {
                                 return domain._id === savedItem._id;
                             });
 
@@ -663,7 +708,7 @@ consoleModule.controller('domainsController', [
                             lastItem = savedItem;
                         });
 
-                        _.forEach(newItems, function (item) {
+                        _.forEach(newItems, function(item) {
                             $scope.domains.push(item);
                         });
 
@@ -678,10 +723,10 @@ consoleModule.controller('domainsController', [
 
                         $scope.ui.showValid = true;
                     })
-                    .error(function (errMsg) {
+                    .error(function(errMsg) {
                         $common.showError(errMsg);
                     })
-                    .finally(function () {
+                    .finally(function() {
                         $loading.finish('importDomainFromDb');
 
                         importDomainModal.hide();
@@ -693,18 +738,17 @@ consoleModule.controller('domainsController', [
 
         function _saveDomainModel() {
             if ($common.isEmptyString($scope.ui.packageName))
-                return $common.showPopoverMessage(undefined, undefined, 'domainPackageName',
-                    'Package should be not empty');
+                return $common.showPopoverMessage(null, null, 'domainPackageName', 'Package could not be empty');
 
             if (!$common.isValidJavaClass('Package', $scope.ui.packageName, false, 'domainPackageName', true))
                 return false;
 
-            var batch = [];
-            var tables = [];
-            var checkedCaches = [];
-            var dupCnt = 0;
+            const batch = [];
+            const tables = [];
+            const checkedCaches = [];
 
-            var containKey = true;
+            let dupCnt = 0;
+            let containKey = true;
 
             function queryField(name, jdbcType) {
                 return {name: toJavaName(name), className: jdbcType.javaType};
@@ -712,7 +756,7 @@ consoleModule.controller('domainsController', [
 
             function dbField(name, jdbcType, nullable) {
                 return {
-                    jdbcType: jdbcType,
+                    jdbcType,
                     databaseFieldName: name,
                     databaseFieldType: jdbcType.dbName,
                     javaFieldName: toJavaName(name),
@@ -721,34 +765,34 @@ consoleModule.controller('domainsController', [
                 };
             }
 
-            _.forEach($scope.importDomain.tables, function (table) {
+            _.forEach($scope.importDomain.tables, function(table) {
                 if (table.use) {
-                    var qryFields = [];
-                    var indexes = [];
-                    var keyFields = [];
-                    var valFields = [];
-                    var aliases = [];
+                    const qryFields = [];
+                    const indexes = [];
+                    const keyFields = [];
+                    const valFields = [];
+                    const aliases = [];
 
-                    var tableName = table.tbl;
+                    const tableName = table.tbl;
 
-                    var dup = tables.indexOf(tableName) >= 0;
+                    const dup = tables.indexOf(tableName) >= 0;
 
                     if (dup)
                         dupCnt++;
 
-                    var typeName = toJavaClassName(tableName);
-                    var valType = _toJavaPackage($scope.ui.packageName) + '.' + typeName;
+                    const typeName = toJavaClassName(tableName);
+                    const valType = _toJavaPackage($scope.ui.packageName) + '.' + typeName;
 
-                    var _containKey = false;
+                    let _containKey = false;
 
-                    _.forEach(table.cols, function (col) {
-                        var colName = col.name;
-                        var jdbcType = $common.findJdbcType(col.type);
-                        var nullable = col.nullable;
+                    _.forEach(table.cols, function(col) {
+                        const colName = col.name;
+                        const jdbcType = $common.findJdbcType(col.type);
+                        const nullable = col.nullable;
 
                         qryFields.push(queryField(colName, jdbcType));
 
-                        var fld = dbField(colName, jdbcType, nullable);
+                        const fld = dbField(colName, jdbcType, nullable);
 
                         if ($scope.ui.generateAliases && !_.find(aliases, {field: fld.javaFieldName}) &&
                             fld.javaFieldName.toUpperCase() !== fld.databaseFieldName.toUpperCase())
@@ -766,11 +810,11 @@ consoleModule.controller('domainsController', [
                     containKey &= _containKey;
 
                     if (table.idxs) {
-                        _.forEach(table.idxs, function (idx) {
-                            var fields = Object.keys(idx.fields);
+                        _.forEach(table.idxs, function(idx) {
+                            const fields = Object.keys(idx.fields);
 
                             indexes.push({
-                                name: idx.name, indexType: 'SORTED', fields: _.map(fields, function (fieldName) {
+                                name: idx.name, indexType: 'SORTED', fields: _.map(fields, function(fieldName) {
                                     return {
                                         name: toJavaName(fieldName),
                                         direction: idx.fields[fieldName]
@@ -780,11 +824,11 @@ consoleModule.controller('domainsController', [
                         });
                     }
 
-                    var domainFound = _.find($scope.domains, function (domain) {
+                    const domainFound = _.find($scope.domains, function(domain) {
                         return domain.valueType === valType;
                     });
 
-                    var newDomain = {
+                    const newDomain = {
                         confirm: false,
                         skip: false,
                         space: $scope.spaces[0],
@@ -797,7 +841,7 @@ consoleModule.controller('domainsController', [
                         newDomain.confirm = true;
                     }
 
-                    var dupSfx = (dup ? '_' + dupCnt : '');
+                    const dupSfx = (dup ? '_' + dupCnt : '');
 
                     newDomain.keyType = valType + 'Key' + dupSfx;
                     newDomain.valueType = valType + dupSfx;
@@ -816,19 +860,19 @@ consoleModule.controller('domainsController', [
 
                     // Use Java built-in type for key.
                     if ($scope.ui.builtinKeys && newDomain.keyFields.length === 1) {
-                        var keyField = newDomain.keyFields[0];
+                        const keyField = newDomain.keyFields[0];
 
                         newDomain.keyType = keyField.jdbcType.javaType;
 
                         // Exclude key column from query fields and indexes.
-                        newDomain.fields = _.filter(newDomain.fields, function (field) {
-                            return field.name != keyField.javaFieldName;
+                        newDomain.fields = _.filter(newDomain.fields, function(field) {
+                            return field.name !== keyField.javaFieldName;
                         });
 
-                        _.forEach(newDomain.indexes, function (index) {
-                            index.fields = _.filter(index.fields, function (field) {
+                        _.forEach(newDomain.indexes, function(index) {
+                            index.fields = _.filter(index.fields, function(field) {
                                 return field.name !== keyField.javaFieldName;
-                            })
+                            });
                         });
 
                         newDomain.indexes = _.filter(newDomain.indexes, (index) => !_.isEmpty(index.fields));
@@ -836,9 +880,9 @@ consoleModule.controller('domainsController', [
 
                     // Prepare caches for generation.
                     if (table.action === IMPORT_DM_NEW_CACHE) {
-                        var template = _.find(_importCachesOrTemplates, {value: table.cacheOrTemplate});
+                        const template = _.find(_importCachesOrTemplates, {value: table.cacheOrTemplate});
 
-                        var newCache = angular.copy(template.cache);
+                        const newCache = angular.copy(template.cache);
 
                         newDomain.newCache = newCache;
 
@@ -847,17 +891,10 @@ consoleModule.controller('domainsController', [
                         newCache.clusters = $scope.ui.generatedCachesClusters;
 
                         // POJO store factory is not defined in template.
-                        if (!newCache.cacheStoreFactory ||
-                            newCache.cacheStoreFactory.kind !== 'CacheJdbcPojoStoreFactory') {
-                            var dialect = $scope.importDomain.demo ? 'H2' : $scope.selectedPreset.db;
-
-                            newCache.cacheStoreFactory = {
-                                kind: 'CacheJdbcPojoStoreFactory',
-                                CacheJdbcPojoStoreFactory: {
-                                    dataSourceBean: 'ds' + dialect,
-                                    dialect: dialect
-                                }
-                            };
+                        if (!newCache.cacheStoreFactory || newCache.cacheStoreFactory.kind !== 'CacheJdbcPojoStoreFactory') {
+                            const dialect = $scope.importDomain.demo ? 'H2' : $scope.selectedPreset.db;
+
+                            newCache.cacheStoreFactory = {kind: 'CacheJdbcPojoStoreFactory', CacheJdbcPojoStoreFactory: {dataSourceBean: 'ds' + dialect, dialect}};
                         }
 
                         if (!newCache.readThrough && !newCache.writeThrough) {
@@ -866,19 +903,19 @@ consoleModule.controller('domainsController', [
                         }
                     }
                     else {
-                        var cacheId = table.cacheOrTemplate;
+                        const cacheId = table.cacheOrTemplate;
 
                         newDomain.caches = [cacheId];
 
                         if (!_.includes(checkedCaches, cacheId)) {
-                            var cache = _.find($scope.caches, {value: cacheId}).cache;
+                            const cache = _.find($scope.caches, {value: cacheId}).cache;
 
-                            var change = $common.autoCacheStoreConfiguration(cache, [newDomain]);
+                            const change = $common.autoCacheStoreConfiguration(cache, [newDomain]);
 
                             if (change)
-                                newDomain.cacheStoreChanges = [{cacheId: cacheId, change: change}];
+                                newDomain.cacheStoreChanges = [{cacheId, change}];
 
-                            checkedCaches.push(cacheId)
+                            checkedCaches.push(cacheId);
                         }
                     }
 
@@ -900,40 +937,32 @@ consoleModule.controller('domainsController', [
                     '</span>';
             }
 
-            var itemsToConfirm = _.filter(batch, function (item) {
-                return item.confirm;
-            });
+            const itemsToConfirm = _.filter(batch, (item) => item.confirm);
 
             function checkOverwrite() {
-                if (itemsToConfirm.length > 0)
+                if (itemsToConfirm.length > 0) {
                     $confirmBatch.confirm(overwriteMessage, itemsToConfirm)
-                        .then(function () {
-                            _saveBatch(_.filter(batch, function (item) {
-                                return !item.skip;
-                            }));
-                        })
-                        .catch(function () {
-                            $common.showError('Importing of domain models interrupted by user.');
-                        });
+                        .then(() => _saveBatch(_.filter(batch, (item) => !item.skip)))
+                        .catch(() => $common.showError('Importing of domain models interrupted by user.'));
+                }
                 else
                     _saveBatch(batch);
             }
 
             if (containKey)
                 checkOverwrite();
-            else
+            else {
                 $confirm.confirm('Some tables have no primary key.<br/>' +
                         'You will need to configure key type and key fields for such tables after import complete.')
-                    .then(function () {
-                        checkOverwrite();
-                    });
+                    .then(() => checkOverwrite());
+            }
         }
 
-        $scope.importDomainNext = function () {
+        $scope.importDomainNext = function() {
             if (!$scope.importDomainNextAvailable())
                 return;
 
-            var act = $scope.importDomain.action;
+            const act = $scope.importDomain.action;
 
             if (act === 'drivers' && $scope.importDomain.jdbcDriversNotFound)
                 importDomainModal.hide();
@@ -947,10 +976,10 @@ consoleModule.controller('domainsController', [
                 _saveDomainModel();
         };
 
-        $scope.nextTooltipText = function () {
-            var importDomainNextAvailable = $scope.importDomainNextAvailable();
+        $scope.nextTooltipText = function() {
+            const importDomainNextAvailable = $scope.importDomainNextAvailable();
 
-            var act = $scope.importDomain.action;
+            const act = $scope.importDomain.action;
 
             if (act === 'drivers' && $scope.importDomain.jdbcDriversNotFound)
                 return 'Resolve issue with JDBC drivers<br>Close this dialog and try again';
@@ -970,8 +999,8 @@ consoleModule.controller('domainsController', [
             return 'Click to continue';
         };
 
-        $scope.prevTooltipText = function () {
-            var act = $scope.importDomain.action;
+        $scope.prevTooltipText = function() {
+            const act = $scope.importDomain.action;
 
             if (act === 'schemas')
                 return $scope.importDomain.demo ? 'Click to return on demo description step' : 'Click to return on connection configuration step';
@@ -983,8 +1012,8 @@ consoleModule.controller('domainsController', [
                 return 'Click to return on tables selection step';
         };
 
-        $scope.importDomainNextAvailable = function () {
-            var res = true;
+        $scope.importDomainNextAvailable = function() {
+            let res = true;
 
             switch ($scope.importDomain.action) {
                 case 'schemas':
@@ -996,12 +1025,14 @@ consoleModule.controller('domainsController', [
                     res = _.find($scope.importDomain.tables, {use: true});
 
                     break;
+
+                default:
             }
 
             return res;
         };
 
-        $scope.importDomainPrev = function () {
+        $scope.importDomainPrev = function() {
             $scope.importDomain.button = 'Next';
 
             if ($scope.importDomain.action === 'options') {
@@ -1018,7 +1049,7 @@ consoleModule.controller('domainsController', [
             }
         };
 
-        $scope.domainModelTitle = function () {
+        $scope.domainModelTitle = function() {
             return $scope.ui.showValid ? 'Domain model types:' : 'Domain model types without key fields:';
         };
 
@@ -1035,41 +1066,13 @@ consoleModule.controller('domainsController', [
 
         $scope.importCommon = {};
 
-        function _fillCommonCachesOrTemplates(item) {
-            return function (action) {
-                if (item.cachesOrTemplates)
-                    item.cachesOrTemplates.length = 0;
-                else
-                    item.cachesOrTemplates = [];
-
-                if (action == IMPORT_DM_NEW_CACHE) {
-                    item.cachesOrTemplates.push(DFLT_PARTITIONED_CACHE);
-                    item.cachesOrTemplates.push(DFLT_REPLICATED_CACHE);
-                }
-
-                if (!_.isEmpty($scope.caches)) {
-                    if (item.cachesOrTemplates.length > 0)
-                        item.cachesOrTemplates.push(null);
-
-                    _.forEach($scope.caches, function (cache) {
-                        item.cachesOrTemplates.push(cache);
-                    });
-                }
-
-                if (!_.find(item.cachesOrTemplates, {value: item.cacheOrTemplate}))
-                    item.cacheOrTemplate = item.cachesOrTemplates[0].value;
-            }
-        }
-
         // When landing on the page, get domain models and show them.
         $loading.start('loadingDomainModelsScreen');
 
-        var _importCachesOrTemplates = [];
-
         $http.post('/api/v1/configuration/domains/list')
-            .success(function (data) {
+            .success(function(data) {
                 $scope.spaces = data.spaces;
-                $scope.clusters = _.map(data.clusters, function (cluster) {
+                $scope.clusters = _.map(data.clusters, function(cluster) {
                     return {
                         value: cluster._id,
                         label: cluster.name
@@ -1078,28 +1081,29 @@ consoleModule.controller('domainsController', [
                 $scope.caches = _mapCaches(data.caches);
                 $scope.domains = data.domains;
 
-                _.forEach($scope.clusters, function (cluster) {
+                _.forEach($scope.clusters, function(cluster) {
                     $scope.ui.generatedCachesClusters.push(cluster.value);
                 });
 
-                if (!_.isEmpty($scope.caches))
+                if (!_.isEmpty($scope.caches)) {
                     $scope.importActions.push({
                         label: 'Associate with existing cache',
                         shortLabel: 'Associate',
                         value: IMPORT_DM_ASSOCIATE_CACHE
                     });
+                }
 
                 $scope.$watch('importCommon.action', _fillCommonCachesOrTemplates($scope.importCommon), true);
 
                 $scope.importCommon.action = IMPORT_DM_NEW_CACHE;
 
-                if ($state.params.id)
-                    $scope.createItem($state.params.id);
+                if ($state.params.linkId)
+                    $scope.createItem($state.params.linkId);
                 else {
-                    var lastSelectedDomain = angular.fromJson(sessionStorage.lastSelectedDomain);
+                    const lastSelectedDomain = angular.fromJson(sessionStorage.lastSelectedDomain);
 
                     if (lastSelectedDomain) {
-                        var idx = _.findIndex($scope.domains, function (domain) {
+                        const idx = _.findIndex($scope.domains, function(domain) {
                             return domain._id === lastSelectedDomain;
                         });
 
@@ -1116,24 +1120,23 @@ consoleModule.controller('domainsController', [
                 }
 
                 $scope.$watch('ui.inputForm.$valid', function(valid) {
-                    if (valid && __original_value === JSON.stringify($cleanup($scope.backupItem))) {
+                    if (valid && _.isEqual(__original_value, $cleanup($scope.backupItem)))
                         $scope.ui.inputForm.$dirty = false;
-                    }
                 });
 
-                $scope.$watch('backupItem', function (val) {
-                    var form = $scope.ui.inputForm;
+                $scope.$watch('backupItem', function(val) {
+                    const form = $scope.ui.inputForm;
 
-                    if (form.$pristine || (form.$valid && __original_value === JSON.stringify($cleanup(val))))
+                    if (form.$pristine || (form.$valid && _.isEqual(__original_value, $cleanup(val))))
                         form.$setPristine();
                     else
                         form.$setDirty();
                 }, true);
             })
-            .catch(function (errMsg) {
+            .catch(function(errMsg) {
                 $common.showError(errMsg);
             })
-            .finally(function () {
+            .finally(function() {
                 $scope.ui.ready = true;
                 $scope.ui.inputForm.$setPristine();
                 $loading.finish('loadingDomainModelsScreen');
@@ -1143,12 +1146,12 @@ consoleModule.controller('domainsController', [
             ngFormCtrl.$defaults = {};
 
             _.forOwn(ngFormCtrl, (value, key) => {
-                if(value && key !== '$$parentForm' && value.constructor.name === 'FormController') 
-                    clearFormDefaults(value)
+                if (value && key !== '$$parentForm' && value.constructor.name === 'FormController')
+                    clearFormDefaults(value);
             });
         };
 
-        $scope.selectItem = function (item, backup) {
+        $scope.selectItem = function(item, backup) {
             function selectItem() {
                 clearFormDefaults($scope.ui.inputForm);
 
@@ -1175,7 +1178,7 @@ consoleModule.controller('domainsController', [
 
                 $scope.backupItem = angular.merge({}, blank, $scope.backupItem);
 
-                __original_value = JSON.stringify($cleanup($scope.backupItem));
+                __original_value = $cleanup($scope.backupItem);
 
                 if ($common.isDefined($scope.backupItem) && !$common.isDefined($scope.backupItem.queryMetadata))
                     $scope.backupItem.queryMetadata = 'Configuration';
@@ -1190,91 +1193,38 @@ consoleModule.controller('domainsController', [
             $common.confirmUnsavedChanges($scope.ui.inputForm.$dirty, selectItem);
         };
 
-        function prepareNewItem(cacheId) {
-            return {
-                space: $scope.spaces[0]._id,
-                caches: cacheId && _.find($scope.caches, {value: cacheId}) ? [cacheId] :
-                    (!_.isEmpty($scope.caches) ? [$scope.caches[0].value] : []),
-                queryMetadata: 'Configuration'
-            };
-        }
-
         // Add new domain model.
-        $scope.createItem = function (cacheId) {
+        $scope.createItem = function(cacheId) {
             if ($scope.tableReset(true)) {
-                $timeout(function () {
+                $timeout(() => {
                     $common.ensureActivePanel($scope.ui, 'query');
                     $common.ensureActivePanel($scope.ui, 'general', 'keyType');
                 });
 
-                $scope.selectItem(undefined, prepareNewItem(cacheId));
+                $scope.selectItem(null, prepareNewItem(cacheId));
             }
         };
 
-        // Check domain model logical consistency.
-        function validate(item) {
-            var form = $scope.ui.inputForm;
-            var errors = form.$error;
-            var errKeys = Object.keys(errors);
-
-            if (errKeys && errKeys.length > 0) {
-                var firstErrorKey = errKeys[0];
-
-                var firstError = errors[firstErrorKey][0];
-                var actualError = firstError.$error[firstErrorKey][0];
-
-                var errNameFull = actualError.$name;
-                var errNameShort = errNameFull;
-
-                if (errNameShort.endsWith('TextInput'))
-                    errNameShort = errNameShort.substring(0, errNameShort.length - 9);
-
-                var extractErrorMessage = function (errName) {
-                    try {
-                        return errors[firstErrorKey][0].$errorMessages[errName][firstErrorKey];
-                    }
-                    catch(ignored) {
-                        try {
-                            msg = form[firstError.$name].$errorMessages[errName][firstErrorKey];
-                        }
-                        catch(ignited) {
-                            return false;
-                        }
-                    }
-                };
-
-                var msg = extractErrorMessage(errNameFull) || extractErrorMessage(errNameShort) || 'Invalid value!';
-
-                return showPopoverMessage($scope.ui, firstError.$name, errNameFull, msg);
-            }
-
-            if ($common.isEmptyString(item.keyType))
-                return showPopoverMessage($scope.ui, 'general', 'keyType', 'Key type should not be empty');
-            else if (!$common.isValidJavaClass('Key type', item.keyType, true, 'keyType', false, $scope.ui, 'general'))
-                return false;
-
-            if ($common.isEmptyString(item.valueType))
-                return showPopoverMessage($scope.ui, 'general', 'valueType', 'Value type should not be empty');
-            else if (!$common.isValidJavaClass('Value type', item.valueType, false, 'valueType', false, $scope.ui, 'general'))
-                return false;
-
-            var qry = $common.domainForQueryConfigured(item);
-
-            if (item.queryMetadata === 'Configuration' && qry) {
+        function checkQueryConfiguration(item) {
+            if (item.queryMetadata === 'Configuration' && $common.domainForQueryConfigured(item)) {
                 if (_.isEmpty(item.fields))
                     return showPopoverMessage($scope.ui, 'query', 'queryFields', 'Query fields should not be empty');
 
-                var indexes = item.indexes;
+                const indexes = item.indexes;
 
                 if (indexes && indexes.length > 0) {
-                    if (_.find(indexes, function (index, i) {
-                            if (_.isEmpty(index.fields))
-                                return !showPopoverMessage($scope.ui, 'query', 'indexes' + i, 'Index fields are not specified');
-                        }))
+                    if (_.find(indexes, function(index, i) {
+                        if (_.isEmpty(index.fields))
+                            return !showPopoverMessage($scope.ui, 'query', 'indexes' + i, 'Index fields are not specified');
+                    }))
                         return false;
                 }
             }
 
+            return true;
+        }
+
+        function checkStoreConfiguration(item) {
             if ($common.domainForStoreConfigured(item)) {
                 if ($common.isEmptyString(item.databaseSchema))
                     return showPopoverMessage($scope.ui, 'store', 'databaseSchema', 'Database schema should not be empty');
@@ -1291,17 +1241,39 @@ consoleModule.controller('domainsController', [
                 if (_.isEmpty(item.valueFields))
                     return showPopoverMessage($scope.ui, 'store', 'valueFields', 'Value fields are not specified');
             }
-            else if (!qry && item.queryMetadata === 'Configuration') {
+
+            return true;
+        }
+
+        // Check domain model logical consistency.
+        function validate(item) {
+            if (!$common.checkFieldValidators($scope.ui))
+                return false;
+
+            if (!checkQueryConfiguration(item))
+                return false;
+
+            if (!checkStoreConfiguration(item))
+                return false;
+
+            if (!$common.domainForStoreConfigured(item) && !$common.domainForQueryConfigured(item) && item.queryMetadata === 'Configuration')
                 return showPopoverMessage($scope.ui, 'query', 'query-title', 'SQL query domain model should be configured');
-            }
 
             return true;
         }
 
+        function _checkShowValidPresentation() {
+            if (!$scope.ui.showValid) {
+                const validFilter = $filter('domainsValidation');
+
+                $scope.ui.showValid = validFilter($scope.domains, false, true).length === 0;
+            }
+        }
+
         // Save domain models into database.
         function save(item) {
-            var qry = $common.domainForQueryConfigured(item);
-            var str = $common.domainForStoreConfigured(item);
+            const qry = $common.domainForQueryConfigured(item);
+            const str = $common.domainForStoreConfigured(item);
 
             item.kind = 'query';
 
@@ -1311,12 +1283,12 @@ consoleModule.controller('domainsController', [
                 item.kind = 'store';
 
             $http.post('/api/v1/configuration/domains/save', item)
-                .success(function (res) {
+                .success(function(res) {
                     $scope.ui.inputForm.$setPristine();
 
-                    var savedMeta = res.savedDomains[0];
+                    const savedMeta = res.savedDomains[0];
 
-                    var idx = _.findIndex($scope.domains, function (domain) {
+                    const idx = _.findIndex($scope.domains, function(domain) {
                         return domain._id === savedMeta._id;
                     });
 
@@ -1325,31 +1297,38 @@ consoleModule.controller('domainsController', [
                     else
                         $scope.domains.push(savedMeta);
 
+                    _.forEach($scope.caches, (cache) => {
+                        if (_.includes(item.caches, cache.value))
+                            cache.cache.domains = _.union(cache.cache.domains, [savedMeta._id]);
+                        else
+                            _.remove(cache.cache.domains, (id) => id === savedMeta._id);
+                    });
+
                     $scope.selectItem(savedMeta);
 
                     $common.showInfo('Domain model "' + item.valueType + '" saved.');
 
                     _checkShowValidPresentation();
                 })
-                .error(function (errMsg) {
+                .error(function(errMsg) {
                     $common.showError(errMsg);
                 });
         }
 
         // Save domain model.
-        $scope.saveItem = function () {
+        $scope.saveItem = function() {
             if ($scope.tableReset(true)) {
-                var item = $scope.backupItem;
+                const item = $scope.backupItem;
 
                 item.cacheStoreChanges = [];
 
-                _.forEach(item.caches, function (cacheId) {
-                    var cache = _.find($scope.caches, {value: cacheId}).cache;
+                _.forEach(item.caches, function(cacheId) {
+                    const cache = _.find($scope.caches, {value: cacheId}).cache;
 
-                    var change = $common.autoCacheStoreConfiguration(cache, [item]);
+                    const change = $common.autoCacheStoreConfiguration(cache, [item]);
 
                     if (change)
-                        item.cacheStoreChanges.push({cacheId: cacheId, change: change});
+                        item.cacheStoreChanges.push({cacheId, change});
                 });
 
                 if (validate(item))
@@ -1358,7 +1337,7 @@ consoleModule.controller('domainsController', [
         };
 
         function _domainNames() {
-            return _.map($scope.domains, function (domain) {
+            return _.map($scope.domains, function(domain) {
                 return domain.valueType;
             });
         }
@@ -1368,10 +1347,10 @@ consoleModule.controller('domainsController', [
         }
 
         // Save domain model with new name.
-        $scope.cloneItem = function () {
+        $scope.cloneItem = function() {
             if ($scope.tableReset(true) && validate($scope.backupItem)) {
-                $clone.confirm($scope.backupItem.valueType, _domainNames(), _newNameIsValidJavaClass).then(function (newName) {
-                    var item = angular.copy($scope.backupItem);
+                $clone.confirm($scope.backupItem.valueType, _domainNames(), _newNameIsValidJavaClass).then(function(newName) {
+                    const item = angular.copy($scope.backupItem);
 
                     delete item._id;
                     item.valueType = newName;
@@ -1382,22 +1361,22 @@ consoleModule.controller('domainsController', [
         };
 
         // Remove domain model from db.
-        $scope.removeItem = function () {
+        $scope.removeItem = function() {
             $table.tableReset();
 
-            var selectedItem = $scope.selectedItem;
+            const selectedItem = $scope.selectedItem;
 
             $confirm.confirm('Are you sure you want to remove domain model: "' + selectedItem.valueType + '"?')
-                .then(function () {
-                    var _id = selectedItem._id;
+                .then(function() {
+                    const _id = selectedItem._id;
 
-                    $http.post('/api/v1/configuration/domains/remove', {_id: _id})
-                        .success(function () {
+                    $http.post('/api/v1/configuration/domains/remove', {_id})
+                        .success(function() {
                             $common.showInfo('Domain model has been removed: ' + selectedItem.valueType);
 
-                            var domains = $scope.domains;
+                            const domains = $scope.domains;
 
-                            var idx = _.findIndex(domains, function (domain) {
+                            const idx = _.findIndex(domains, function(domain) {
                                 return domain._id === _id;
                             });
 
@@ -1406,56 +1385,55 @@ consoleModule.controller('domainsController', [
 
                                 if (domains.length > 0)
                                     $scope.selectItem(domains[0]);
-                                else
+                                else {
                                     $scope.backupItem = emptyDomain;
+                                    $scope.ui.inputForm.$setPristine();
+                                }
+
+                                _.forEach($scope.caches, (cache) => _.remove(cache.cache.domains, (id) => id === _id));
                             }
 
                             _checkShowValidPresentation();
                         })
-                        .error(function (errMsg) {
+                        .error(function(errMsg) {
                             $common.showError(errMsg);
                         });
                 });
         };
 
-        function _checkShowValidPresentation() {
-            if (!$scope.ui.showValid) {
-                var validFilter = $filter('domainsValidation');
-
-                $scope.ui.showValid = validFilter($scope.domains, false, true).length === 0;
-            }
-        }
-
         // Remove all domain models from db.
-        $scope.removeAllItems = function () {
+        $scope.removeAllItems = function() {
             $table.tableReset();
 
             $confirm.confirm('Are you sure you want to remove all domain models?')
-                .then(function () {
+                .then(function() {
                     $http.post('/api/v1/configuration/domains/remove/all')
-                        .success(function () {
+                        .success(function() {
                             $common.showInfo('All domain models have been removed');
 
                             $scope.domains = [];
+
+                            _.forEach($scope.caches, (cache) => cache.cache.domains = []);
+
                             $scope.ui.inputForm.$setPristine();
                             $scope.backupItem = emptyDomain;
                             $scope.ui.showValid = true;
                         })
-                        .error(function (errMsg) {
+                        .error(function(errMsg) {
                             $common.showError(errMsg);
                         });
                 });
         };
 
-        $scope.toggleValid = function () {
+        $scope.toggleValid = function() {
             $scope.ui.showValid = !$scope.ui.showValid;
 
-            var validFilter = $filter('domainsValidation');
+            const validFilter = $filter('domainsValidation');
 
-            var idx = -1;
+            let idx = -1;
 
             if ($common.isDefined($scope.selectedItem)) {
-                idx = _.findIndex(validFilter($scope.domains, $scope.ui.showValid, true), function (domain) {
+                idx = _.findIndex(validFilter($scope.domains, $scope.ui.showValid, true), function(domain) {
                     return domain._id === $scope.selectedItem._id;
                 });
             }
@@ -1464,7 +1442,7 @@ consoleModule.controller('domainsController', [
                 $scope.backupItem = emptyDomain;
         };
 
-        var pairFields = {
+        const pairFields = {
             fields: {
                 msg: 'Query field class',
                 id: 'QryField',
@@ -1477,16 +1455,16 @@ consoleModule.controller('domainsController', [
             aliases: {id: 'Alias', idPrefix: 'Value', searchCol: 'alias', valueCol: 'value', dupObjName: 'alias'}
         };
 
-        $scope.tablePairValid = function (item, field, index) {
-            var pairField = pairFields[field.model];
+        $scope.tablePairValid = function(item, field, index) {
+            const pairField = pairFields[field.model];
 
-            var pairValue = $table.tablePairValue(field, index);
+            const pairValue = $table.tablePairValue(field, index);
 
             if (pairField) {
-                var model = item[field.model];
+                const model = item[field.model];
 
                 if ($common.isDefined(model)) {
-                    var idx = _.findIndex(model, function (pair) {
+                    const idx = _.findIndex(model, function(pair) {
                         return pair[pairField.searchCol] === pairValue[pairField.valueCol];
                     });
 
@@ -1516,8 +1494,8 @@ consoleModule.controller('domainsController', [
             };
         }
 
-        $scope.tableDbFieldSaveVisible = function (field, index) {
-            var dbFieldValue = tableDbFieldValue(field, index);
+        $scope.tableDbFieldSaveVisible = function(field, index) {
+            const dbFieldValue = tableDbFieldValue(field, index);
 
             return $common.isDefined(dbFieldValue.databaseFieldType) &&
                 $common.isDefined(dbFieldValue.javaFieldType) &&
@@ -1525,26 +1503,26 @@ consoleModule.controller('domainsController', [
                 !$common.isEmptyString(dbFieldValue.javaFieldName);
         };
 
-        var dbFieldTables = {
+        const dbFieldTables = {
             keyFields: {msg: 'Key field', id: 'KeyField'},
             valueFields: {msg: 'Value field', id: 'ValueField'}
         };
 
-        $scope.tableDbFieldSave = function (field, index, stopEdit) {
-            var dbFieldTable = dbFieldTables[field.model];
+        $scope.tableDbFieldSave = function(field, index, stopEdit) {
+            const dbFieldTable = dbFieldTables[field.model];
 
             if (dbFieldTable) {
-                var dbFieldValue = tableDbFieldValue(field, index);
+                const dbFieldValue = tableDbFieldValue(field, index);
 
-                var item = $scope.backupItem;
+                const item = $scope.backupItem;
 
-                var model = item[field.model];
+                let model = item[field.model];
 
                 if (!$common.isValidJavaIdentifier(dbFieldTable.msg + ' java name', dbFieldValue.javaFieldName, $table.tableFieldId(index, 'JavaFieldName' + dbFieldTable.id)))
                     return false;
 
                 if ($common.isDefined(model)) {
-                    var idx = _.findIndex(model, function (dbMeta) {
+                    let idx = _.findIndex(model, function(dbMeta) {
                         return dbMeta.databaseFieldName === dbFieldValue.databaseFieldName;
                     });
 
@@ -1552,7 +1530,7 @@ consoleModule.controller('domainsController', [
                     if (idx >= 0 && index !== idx)
                         return showPopoverMessage($scope.ui, 'store', $table.tableFieldId(index, 'DatabaseFieldName' + dbFieldTable.id), 'Field with such database name already exists!');
 
-                    idx = _.findIndex(model, function (dbMeta) {
+                    idx = _.findIndex(model, function(dbMeta) {
                         return dbMeta.javaFieldName === dbFieldValue.javaFieldName;
                     });
 
@@ -1560,11 +1538,10 @@ consoleModule.controller('domainsController', [
                     if (idx >= 0 && index !== idx)
                         return showPopoverMessage($scope.ui, 'store', $table.tableFieldId(index, 'JavaFieldName' + dbFieldTable.id), 'Field with such java name already exists!');
 
-                    if (index < 0) {
+                    if (index < 0)
                         model.push(dbFieldValue);
-                    }
                     else {
-                        var dbField = model[index];
+                        const dbField = model[index];
 
                         dbField.databaseFieldName = dbFieldValue.databaseFieldName;
                         dbField.databaseFieldType = dbFieldValue.databaseFieldType;
@@ -1601,20 +1578,20 @@ consoleModule.controller('domainsController', [
             return index < 0 ? field.newIndexType : field.curIndexType;
         }
 
-        $scope.tableIndexSaveVisible = function (field, index) {
+        $scope.tableIndexSaveVisible = function(field, index) {
             return !$common.isEmptyString(tableIndexName(field, index)) && $common.isDefined(tableIndexType(field, index));
         };
 
-        $scope.tableIndexSave = function (field, curIdx, stopEdit) {
-            var indexName = tableIndexName(field, curIdx);
-            var indexType = tableIndexType(field, curIdx);
+        $scope.tableIndexSave = function(field, curIdx, stopEdit) {
+            const indexName = tableIndexName(field, curIdx);
+            const indexType = tableIndexType(field, curIdx);
 
-            var item = $scope.backupItem;
+            const item = $scope.backupItem;
 
-            var indexes = item.indexes;
+            const indexes = item.indexes;
 
             if ($common.isDefined(indexes)) {
-                var idx = _.findIndex(indexes, function (index) {
+                const idx = _.findIndex(indexes, function(index) {
                     return index.name === indexName;
                 });
 
@@ -1626,7 +1603,7 @@ consoleModule.controller('domainsController', [
             $table.tableReset();
 
             if (curIdx < 0) {
-                var newIndex = {name: indexName, indexType: indexType};
+                const newIndex = {name: indexName, indexType};
 
                 if (item.indexes)
                     item.indexes.push(newIndex);
@@ -1642,7 +1619,7 @@ consoleModule.controller('domainsController', [
                 if (curIdx < 0)
                     $scope.tableIndexNewItem(field, item.indexes.length - 1);
                 else {
-                    var index = item.indexes[curIdx];
+                    const index = item.indexes[curIdx];
 
                     if (index.fields && index.fields.length > 0)
                         $scope.tableIndexItemStartEdit(field, curIdx, 0);
@@ -1654,9 +1631,9 @@ consoleModule.controller('domainsController', [
             return true;
         };
 
-        $scope.tableIndexNewItem = function (field, indexIdx) {
+        $scope.tableIndexNewItem = function(field, indexIdx) {
             if ($scope.tableReset(true)) {
-                var index = $scope.backupItem.indexes[indexIdx];
+                const index = $scope.backupItem.indexes[indexIdx];
 
                 $table.tableState(field, -1, 'table-index-fields');
                 $table.tableFocusInvalidField(-1, 'FieldName' + (index.indexType === 'SORTED' ? 'S' : '') + indexIdx);
@@ -1667,11 +1644,11 @@ consoleModule.controller('domainsController', [
             }
         };
 
-        $scope.tableIndexNewItemActive = function (field, itemIndex) {
-            var indexes = $scope.backupItem.indexes;
+        $scope.tableIndexNewItemActive = function(field, itemIndex) {
+            const indexes = $scope.backupItem.indexes;
 
             if (indexes) {
-                var index = indexes[itemIndex];
+                const index = indexes[itemIndex];
 
                 if (index)
                     return $table.tableNewItemActive({model: 'table-index-fields'}) && field.indexIdx === itemIndex;
@@ -1680,11 +1657,11 @@ consoleModule.controller('domainsController', [
             return false;
         };
 
-        $scope.tableIndexItemEditing = function (field, itemIndex, curIdx) {
-            var indexes = $scope.backupItem.indexes;
+        $scope.tableIndexItemEditing = function(field, itemIndex, curIdx) {
+            const indexes = $scope.backupItem.indexes;
 
             if (indexes) {
-                var index = indexes[itemIndex];
+                const index = indexes[itemIndex];
 
                 if (index)
                     return $table.tableEditing({model: 'table-index-fields'}, curIdx) && field.indexIdx === itemIndex;
@@ -1703,13 +1680,13 @@ consoleModule.controller('domainsController', [
             };
         }
 
-        $scope.tableIndexItemStartEdit = function (field, indexIdx, curIdx) {
+        $scope.tableIndexItemStartEdit = function(field, indexIdx, curIdx) {
             if ($scope.tableReset(true)) {
-                var index = $scope.backupItem.indexes[indexIdx];
+                const index = $scope.backupItem.indexes[indexIdx];
 
                 $table.tableState(field, curIdx, 'table-index-fields');
 
-                var indexItem = index.fields[curIdx];
+                const indexItem = index.fields[curIdx];
 
                 field.curFieldName = indexItem.name;
                 field.curDirection = indexItem.direction;
@@ -1719,21 +1696,19 @@ consoleModule.controller('domainsController', [
             }
         };
 
-        $scope.tableIndexItemSaveVisible = function (field, index) {
+        $scope.tableIndexItemSaveVisible = function(field, index) {
             return !$common.isEmptyString(tableIndexItemValue(field, index).name);
         };
 
-        $scope.tableIndexItemSave = function (field, indexIdx, curIdx, stopEdit) {
-            var indexItemValue = tableIndexItemValue(field, curIdx);
+        $scope.tableIndexItemSave = function(field, indexIdx, curIdx, stopEdit) {
+            const indexItemValue = tableIndexItemValue(field, curIdx);
 
-            var index = $scope.backupItem.indexes[indexIdx];
+            const index = $scope.backupItem.indexes[indexIdx];
 
-            var fields = index.fields;
+            const fields = index.fields;
 
             if ($common.isDefined(fields)) {
-                var idx = _.findIndex(fields, function (field) {
-                    return field.name === indexItemValue.name;
-                });
+                const idx = _.findIndex(fields, (fld) => fld.name === indexItemValue.name);
 
                 // Found duplicate.
                 if (idx >= 0 && idx !== curIdx)
@@ -1767,17 +1742,17 @@ consoleModule.controller('domainsController', [
             return true;
         };
 
-        $scope.tableRemoveIndexItem = function (index, curIdx) {
+        $scope.tableRemoveIndexItem = function(index, curIdx) {
             $table.tableReset();
 
             index.fields.splice(curIdx, 1);
         };
 
-        $scope.resetAll = function () {
+        $scope.resetAll = function() {
             $table.tableReset();
 
             $confirm.confirm('Are you sure you want to undo all changes for current domain model?')
-                .then(function () {
+                .then(function() {
                     $scope.backupItem = $scope.selectedItem ? angular.copy($scope.selectedItem) : prepareNewItem();
                     $scope.ui.inputForm.$setPristine();
                 });


[44/50] [abbrv] ignite git commit: Ignite Web Console beta2.

Posted by sb...@apache.org.
Ignite Web Console beta2.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/541e17d0
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/541e17d0
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/541e17d0

Branch: refs/heads/ignite-1232
Commit: 541e17d07520e5dac7daec1b188abe6bd12d6aad
Parents: e7ebe0a
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Mon Jun 27 10:17:45 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Jun 27 10:17:46 2016 +0700

----------------------------------------------------------------------
 .../visor/compute/VisorGatewayTask.java         |    3 +-
 modules/schema-import/README.txt                |   12 +-
 modules/web-agent/README.txt                    |   25 +-
 .../web-agent/assembly/release-web-agent.xml    |    2 -
 modules/web-agent/bin/ignite-web-agent.bat      |    2 +-
 modules/web-agent/bin/ignite-web-agent.sh       |    2 +-
 modules/web-agent/pom.xml                       |   22 +-
 .../console/agent/AgentConfiguration.java       |   53 +-
 .../ignite/console/agent/AgentLauncher.java     |   21 +-
 .../ignite/console/demo/AgentClusterDemo.java   |   82 +-
 modules/web-console/README.txt                  |    4 +-
 modules/web-console/src/main/js/.eslintrc       |    7 +-
 .../src/main/js/app/data/getting-started.json   |    2 +-
 .../src/main/js/app/data/pom-dependencies.json  |   20 +
 .../directives/ui-ace-docker/ui-ace-docker.jade |    4 +-
 .../ui-ace-java/ui-ace-java.directive.js        |    4 +-
 .../directives/ui-ace-pojos/ui-ace-pojos.jade   |    4 +-
 .../ui-ace-xml/ui-ace-xml.directive.js          |    4 +-
 .../src/main/js/app/helpers/jade/mixins.jade    |   17 +-
 modules/web-console/src/main/js/app/index.js    |   18 +-
 .../src/main/js/app/modules/Demo/Demo.module.js |   14 +-
 .../QueryNotebooks/QueryNotebooks.provider.js   |  115 -
 .../main/js/app/modules/agent/agent.module.js   |  323 +++
 .../configuration/generator/Pom.service.js      |   46 +-
 .../form/field/input/datalist.directive.js      |    6 +-
 .../modules/form/field/input/text.directive.js  |    9 +-
 .../js/app/modules/form/field/input/text.jade   |    2 +-
 .../app/modules/form/group/group.directive.js   |    6 +-
 .../form/validator/java-keywords.directive.js   |    9 +-
 .../src/main/js/app/modules/loading/loading.css |    2 +-
 .../query-notebooks/query-notebooks.module.js   |  115 +
 .../app/modules/states/configuration.state.js   |   32 +-
 .../states/configuration/caches/general.jade    |    2 +-
 .../states/configuration/caches/store.jade      |   37 +-
 .../clusters/attributes.directive.js            |   27 +
 .../configuration/clusters/attributes.jade      |   58 +
 .../states/configuration/clusters/binary.jade   |   12 +-
 .../clusters/collision.directive.js             |   27 +
 .../configuration/clusters/collision.jade       |   60 +
 .../clusters/collision/custom.directive.js      |   27 +
 .../clusters/collision/custom.jade              |   24 +
 .../clusters/collision/fifo-queue.directive.js  |   27 +
 .../clusters/collision/fifo-queue.jade          |   28 +
 .../collision/job-stealing.directive.js         |   27 +
 .../clusters/collision/job-stealing.jade        |   64 +
 .../collision/priority-queue.directive.js       |   27 +
 .../clusters/collision/priority-queue.jade      |   43 +
 .../configuration/clusters/communication.jade   |   30 +-
 .../configuration/clusters/deployment.jade      |   31 +-
 .../configuration/clusters/discovery.jade       |    4 +-
 .../clusters/failover.directive.js              |   27 +
 .../states/configuration/clusters/failover.jade |   82 +
 .../states/configuration/clusters/general.jade  |   20 +-
 .../clusters/general/discovery/cloud.jade       |    6 +-
 .../clusters/general/discovery/google.jade      |   11 +-
 .../clusters/general/discovery/s3.jade          |    4 +-
 .../clusters/general/discovery/zookeeper.jade   |   21 +-
 .../bounded-exponential-backoff.jade            |    6 +-
 .../discovery/zookeeper/retrypolicy/custom.jade |    6 +-
 .../retrypolicy/exponential-backoff.jade        |    6 +-
 .../zookeeper/retrypolicy/forever.jade          |    2 +-
 .../zookeeper/retrypolicy/n-times.jade          |    2 +-
 .../zookeeper/retrypolicy/one-time.jade         |    2 +-
 .../zookeeper/retrypolicy/until-elapsed.jade    |    4 +-
 .../states/configuration/clusters/igfs.jade     |    4 +-
 .../configuration/clusters/logger.directive.js  |   27 +
 .../states/configuration/clusters/logger.jade   |   65 +
 .../clusters/logger/custom.directive.js         |   27 +
 .../configuration/clusters/logger/custom.jade   |   24 +
 .../clusters/logger/log4j.directive.js          |   27 +
 .../configuration/clusters/logger/log4j.jade    |   49 +
 .../clusters/logger/log4j2.directive.js         |   27 +
 .../configuration/clusters/logger/log4j2.jade   |   38 +
 .../states/configuration/domains/query.jade     |    4 +-
 .../states/configuration/domains/store.jade     |    2 +-
 .../modules/states/configuration/igfs/misc.jade |    2 +-
 .../main/js/app/modules/user/Auth.service.js    |   19 +-
 .../js/app/services/AgentMonitor.service.js     |  337 ---
 .../src/main/js/app/services/cleanup.service.js |    4 +-
 .../src/main/js/build/system.config.js          |   55 +-
 .../src/main/js/controllers/admin-controller.js |   14 +-
 .../main/js/controllers/caches-controller.js    |  336 ++-
 .../main/js/controllers/clusters-controller.js  |  537 +++--
 .../src/main/js/controllers/common-module.js    | 1052 +++++----
 .../main/js/controllers/domains-controller.js   |  847 ++++---
 .../src/main/js/controllers/igfs-controller.js  |  212 +-
 .../main/js/controllers/profile-controller.js   |   60 +-
 .../src/main/js/controllers/sql-controller.js   | 2173 +++++++++---------
 .../src/main/js/generator/generator-common.js   |  151 +-
 .../src/main/js/generator/generator-java.js     |  998 ++++----
 .../src/main/js/generator/generator-optional.js |    2 +-
 .../main/js/generator/generator-properties.js   |   25 +-
 .../src/main/js/generator/generator-readme.js   |    6 +-
 .../src/main/js/generator/generator-xml.js      |  430 +++-
 .../main/js/gulpfile.babel.js/tasks/eslint.js   |    3 +
 .../src/main/js/public/images/cluster.png       |  Bin 29670 -> 29376 bytes
 .../src/main/js/public/images/query-table.png   |  Bin 42253 -> 29189 bytes
 .../src/main/js/public/stylesheets/style.scss   |   28 +
 modules/web-console/src/main/js/serve/agent.js  |  222 +-
 .../web-console/src/main/js/serve/browser.js    |  120 +-
 .../web-console/src/main/js/serve/configure.js  |    1 +
 modules/web-console/src/main/js/serve/mongo.js  |   58 +-
 .../src/main/js/serve/routes/agent.js           |    3 +-
 .../src/main/js/serve/routes/caches.js          |    4 +-
 .../src/main/js/serve/routes/clusters.js        |    8 +-
 .../src/main/js/serve/routes/igfs.js            |    2 +-
 .../src/main/js/serve/routes/profile.js         |   11 +-
 .../src/main/js/serve/routes/public.js          |   35 +-
 .../main/js/views/configuration/clusters.jade   |    4 +
 .../js/views/configuration/domains-import.jade  |  325 +--
 .../src/main/js/views/settings/profile.jade     |   14 +-
 .../web-console/src/main/js/views/signin.jade   |   26 +-
 .../src/main/js/views/sql/cache-metadata.jade   |    2 +-
 .../web-console/src/main/js/views/sql/sql.jade  |  205 +-
 114 files changed, 6087 insertions(+), 4279 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
index c59d299..f1b22ff 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/compute/VisorGatewayTask.java
@@ -355,7 +355,8 @@ public class VisorGatewayTask implements ComputeTask<Object[], Object> {
                 }
             }
 
-            return ignite.compute().execute(taskName, new VisorTaskArgument<>(nids, jobArgs, false));
+            return ignite.compute(ignite.cluster().forNodeIds(nids))
+                .execute(taskName, new VisorTaskArgument<>(nids, jobArgs, false));
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/schema-import/README.txt
----------------------------------------------------------------------
diff --git a/modules/schema-import/README.txt b/modules/schema-import/README.txt
index d4f2dbf..31a8ff0 100644
--- a/modules/schema-import/README.txt
+++ b/modules/schema-import/README.txt
@@ -19,12 +19,12 @@ For example you may use the following script for create sample type 'Person' in
 
 create table PERSON(id integer not null PRIMARY KEY, first_name varchar(50), last_name varchar(50), salary double);
 
-insert into PERSON(id, first_name, first_name, salary) values(1, 'Johannes', 'Kepler', 1000);
-insert into PERSON(id, first_name, first_name, salary) values(2, 'Galileo', 'Galilei', 1200);
-insert into PERSON(id, first_name, first_name, salary) values(3, 'Henry', 'More', 1150);
-insert into PERSON(id, first_name, first_name, salary) values(4, 'Polish', 'Brethren', 2000);
-insert into PERSON(id, first_name, first_name, salary) values(5, 'Robert', 'Boyle', 2500);
-insert into PERSON(id, first_name, first_name, salary) values(6, 'Isaac', 'Newton', 1300);
+insert into PERSON(id, first_name, last_name, salary) values(1, 'Johannes', 'Kepler', 1000);
+insert into PERSON(id, first_name, last_name, salary) values(2, 'Galileo', 'Galilei', 1200);
+insert into PERSON(id, first_name, last_name, salary) values(3, 'Henry', 'More', 1150);
+insert into PERSON(id, first_name, last_name, salary) values(4, 'Polish', 'Brethren', 2000);
+insert into PERSON(id, first_name, last_name, salary) values(5, 'Robert', 'Boyle', 2500);
+insert into PERSON(id, first_name, last_name, salary) values(6, 'Isaac', 'Newton', 1300);
 
 The Ignite Schema Import utility generates the following artifacts:
  # Java POJO key and value classes (enter "org.apache.ignite.schema" package name before generation).

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-agent/README.txt
----------------------------------------------------------------------
diff --git a/modules/web-agent/README.txt b/modules/web-agent/README.txt
index 0d8d4ac..c6e625b 100644
--- a/modules/web-agent/README.txt
+++ b/modules/web-agent/README.txt
@@ -17,22 +17,23 @@ Configuration file:
   Should be a file with simple line-oriented format as described here: http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html#load(java.io.Reader)
 
   Available entries names:
-    token
+    tokens
     server-uri
     node-uri
     driver-folder
 
   Example configuration file:
-    token=1a2b3c4d5f
-    serverURI=http://console.example.com:3001
+    tokens=1a2b3c4d5f,2j1s134d12
+    serverURI=https://console.example.com:3001
 
-Security token:
-  1) By default token will be included into downloaded agent zip.
-  2) You can get/change token in your profile.
+Security tokens:
+  1) By default security token of current user will be included into "default.properties" inside downloaded "ignite-web-agent-x.x.x.zip".
+  2) One can get/reset token in Web Console profile (https://<your_console_address>/settings/profile).
+  3) One may specify several comma separated tokens using configuration file or command line arguments of web agent.
 
 Ignite Web agent requirements:
-  1) Ignite node should be started with REST server (move ignite-rest-http folder from lib/optional/ to lib/).
-  2) Pass Ignite node REST server URI to agent.
+  1) In order to communicate with web agent Ignite node should be started with REST server (move ignite-rest-http folder from lib/optional/ to lib/).
+  2) Configure web agent serverURI property by Ignite node REST server URI.
 
 Options:
   -h, --help
@@ -47,15 +48,15 @@ Options:
   -s, --server-uri
      URI for connect to Ignite Web Console via web-socket protocol, default
      value: http://localhost:3001
-  -t, --token
-     User's security token
+  -t, --tokens
+     User's security tokens
 
 How to build:
   To build from sources run following command in Ignite project root folder:
   mvn clean package -pl :ignite-web-agent -am -P web-console -DskipTests=true
 
 Demo of Ignite Web Agent:
- In order to simplify evaluation demo mode was implemented. To start demo, you need to to click button "Start demo".
+ In order to simplify evaluation demo mode was implemented. To start demo, you need to click button "Start demo".
  New tab will be open with prepared demo data.
 
  1) Demo for import domain model from database.
@@ -73,7 +74,7 @@ Demo of Ignite Web Agent:
      In this mode internal Ignite node will be started. Cache created and populated with data.
        2.1) Click "SQL" in Ignite Web Console top menu.
        2.2) "Demo" notebook with preconfigured queries will be opened.
-       2.3) You can also execute any SQL queries for tables: "Country, Department, Employee", "Parking, Car".
+       2.3) You can also execute any SQL queries for tables: "Country, Department, Employee, Parking, Car".
 
  For example:
    2.4) Enter SQL statement:

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-agent/assembly/release-web-agent.xml
----------------------------------------------------------------------
diff --git a/modules/web-agent/assembly/release-web-agent.xml b/modules/web-agent/assembly/release-web-agent.xml
index eb7da95..aa85b59 100644
--- a/modules/web-agent/assembly/release-web-agent.xml
+++ b/modules/web-agent/assembly/release-web-agent.xml
@@ -42,7 +42,6 @@
         <fileSet>
             <directory>${basedir}/bin</directory>
             <outputDirectory>/</outputDirectory>
-            <filtered>true</filtered>
             <includes>
                 <include>**/*.bat</include>
             </includes>
@@ -50,7 +49,6 @@
         <fileSet>
             <directory>${basedir}/bin</directory>
             <outputDirectory>/</outputDirectory>
-            <filtered>true</filtered>
             <fileMode>0755</fileMode>
             <includes>
                 <include>**/*.sh</include>

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-agent/bin/ignite-web-agent.bat
----------------------------------------------------------------------
diff --git a/modules/web-agent/bin/ignite-web-agent.bat b/modules/web-agent/bin/ignite-web-agent.bat
index 5b3f24c..f16eb35 100644
--- a/modules/web-agent/bin/ignite-web-agent.bat
+++ b/modules/web-agent/bin/ignite-web-agent.bat
@@ -55,7 +55,7 @@ goto error_finish
 ::
 if "%JVM_OPTS%" == "" set JVM_OPTS=-Xms1g -Xmx1g -server -XX:+AggressiveOpts -XX:MaxPermSize=256m
 
-"%JAVA_HOME%\bin\java.exe" %JVM_OPTS% -cp ignite-web-agent-${version}.jar org.apache.ignite.console.agent.AgentLauncher  %*
+"%JAVA_HOME%\bin\java.exe" %JVM_OPTS% -cp "*" org.apache.ignite.console.agent.AgentLauncher  %*
 
 set JAVA_ERRORLEVEL=%ERRORLEVEL%
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-agent/bin/ignite-web-agent.sh
----------------------------------------------------------------------
diff --git a/modules/web-agent/bin/ignite-web-agent.sh b/modules/web-agent/bin/ignite-web-agent.sh
index 6d0a1b5..3f2c2bc 100644
--- a/modules/web-agent/bin/ignite-web-agent.sh
+++ b/modules/web-agent/bin/ignite-web-agent.sh
@@ -84,4 +84,4 @@ if [ -z "$JVM_OPTS" ] ; then
     JVM_OPTS="-Xms1g -Xmx1g -server -XX:+AggressiveOpts -XX:MaxPermSize=256m"
 fi
 
-"$JAVA" ${JVM_OPTS} -cp ignite-web-agent-${version}.jar org.apache.ignite.console.agent.AgentLauncher "$@"
+"$JAVA" ${JVM_OPTS} -cp "*" org.apache.ignite.console.agent.AgentLauncher "$@"

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-agent/pom.xml
----------------------------------------------------------------------
diff --git a/modules/web-agent/pom.xml b/modules/web-agent/pom.xml
index cb55319..d87084f 100644
--- a/modules/web-agent/pom.xml
+++ b/modules/web-agent/pom.xml
@@ -47,7 +47,7 @@
         <dependency>
             <groupId>com.fasterxml.jackson.datatype</groupId>
             <artifactId>jackson-datatype-json-org</artifactId>
-            <version>2.7.1</version>
+            <version>${jackson2.version}</version>
         </dependency>
 
         <dependency>
@@ -88,6 +88,26 @@
 
         <dependency>
             <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-spring</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework</groupId>
+                    <artifactId>spring-aop</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.springframework</groupId>
+                    <artifactId>spring-tx</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.springframework</groupId>
+                    <artifactId>spring-jdbc</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
             <artifactId>ignite-log4j</artifactId>
             <version>${project.version}</version>
         </dependency>

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java b/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
index ffd30a5..d4787cc 100644
--- a/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
+++ b/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
@@ -23,6 +23,8 @@ import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Properties;
 
 /**
@@ -45,11 +47,13 @@ public class AgentConfiguration {
     private static final String DFLT_NODE_URI = "http://localhost:8080";
 
     /** */
-    @Parameter(names = {"-t", "--token"}, description = "User's security token used to establish connection to Ignite Console.")
-    private String tok;
+    @Parameter(names = {"-t", "--tokens"},
+        description = "User's tokens separated by comma used to connect to Ignite Console.")
+    private List<String> tokens;
 
     /** */
-    @Parameter(names = {"-s", "--server-uri"}, description = "URI for connect to Ignite Console via web-socket protocol" +
+    @Parameter(names = {"-s", "--server-uri"},
+        description = "URI for connect to Ignite Console via web-socket protocol" +
         "           " +
         "      Default value: " + DFLT_SERVER_URI)
     private String srvUri;
@@ -80,17 +84,17 @@ public class AgentConfiguration {
     private Boolean help;
 
     /**
-     * @return Token.
+     * @return Tokens.
      */
-    public String token() {
-        return tok;
+    public List<String> tokens() {
+        return tokens;
     }
 
     /**
-     * @param tok Token.
+     * @param tokens Tokens.
      */
-    public void token(String tok) {
-        this.tok = tok;
+    public void tokens(List<String> tokens) {
+        this.tokens = tokens;
     }
 
     /**
@@ -173,10 +177,10 @@ public class AgentConfiguration {
             props.load(reader);
         }
 
-        String val = (String)props.remove("token");
+        String val = (String)props.remove("tokens");
 
         if (val != null)
-            token(val);
+            tokens(Arrays.asList(val.split(",")));
 
         val = (String)props.remove("server-uri");
 
@@ -198,8 +202,8 @@ public class AgentConfiguration {
      * @param cmd Command.
      */
     public void merge(AgentConfiguration cmd) {
-        if (tok == null)
-            token(cmd.token());
+        if (tokens == null)
+            tokens(cmd.tokens());
 
         if (srvUri == null)
             serverUri(cmd.serverUri());
@@ -221,16 +225,25 @@ public class AgentConfiguration {
     @Override public String toString() {
         StringBuilder sb = new StringBuilder();
 
-        if (tok != null && tok.length() > 0) {
-            sb.append("User's security token         : ");
+        if (tokens != null && tokens.size() > 0) {
+            sb.append("User's security tokens        : ");
 
-            if (tok.length() > 4) {
-                sb.append(new String(new char[tok.length() - 4]).replace('\0', '*'));
+            boolean first = true;
 
-                sb.append(tok.substring(tok.length() - 4));
+            for (String tok : tokens) {
+                if (first)
+                    first = false;
+                else
+                    sb.append(",");
+
+                if (tok.length() > 4) {
+                    sb.append(new String(new char[tok.length() - 4]).replace('\0', '*'));
+
+                    sb.append(tok.substring(tok.length() - 4));
+                }
+                else
+                    sb.append(new String(new char[tok.length()]).replace('\0', '*'));
             }
-            else
-                sb.append(new String(new char[tok.length()]).replace('\0', '*'));
 
             sb.append('\n');
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
----------------------------------------------------------------------
diff --git a/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java b/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
index 4b99a92..810fad4 100644
--- a/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
+++ b/modules/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
@@ -26,7 +26,6 @@ import io.socket.emitter.Emitter;
 import java.io.File;
 import java.io.IOException;
 import java.net.ConnectException;
-import java.net.SocketException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
@@ -73,6 +72,9 @@ public class AgentLauncher {
     private static final String EVENT_SCHEMA_IMPORT_METADATA = "schemaImport:metadata";
 
     /** */
+    private static final String EVENT_AGENT_WARNING = "agent:warning";
+
+    /** */
     private static final String EVENT_AGENT_CLOSE = "agent:close";
 
     /** */
@@ -138,7 +140,7 @@ public class AgentLauncher {
      */
     private static final Emitter.Listener onDisconnect = new Emitter.Listener() {
         @Override public void call(Object... args) {
-            log.error(String.format("Connection closed: %s.", args[0]));
+            log.error(String.format("Connection closed: %s.", args));
         }
     };
 
@@ -198,7 +200,7 @@ public class AgentLauncher {
         System.out.println(cfg);
         System.out.println();
 
-        if (cfg.token() == null) {
+        if (cfg.tokens() == null) {
             String webHost;
 
             try {
@@ -213,9 +215,9 @@ public class AgentLauncher {
             System.out.println("Security token is required to establish connection to the web console.");
             System.out.println(String.format("It is available on the Profile page: https://%s/profile", webHost));
 
-            System.out.print("Enter security token: ");
+            System.out.print("Enter security tokens separated by comma: ");
 
-            cfg.token(System.console().readLine().trim());
+            cfg.tokens(Arrays.asList(System.console().readLine().trim().split(",")));
         }
 
         final RestHandler restHnd = new RestHandler(cfg);
@@ -258,7 +260,7 @@ public class AgentLauncher {
                         JSONObject authMsg = new JSONObject();
 
                         try {
-                            authMsg.put("token", cfg.token());
+                            authMsg.put("tokens", cfg.tokens());
 
                             String clsName = AgentLauncher.class.getSimpleName() + ".class";
 
@@ -280,7 +282,7 @@ public class AgentLauncher {
                                 @Override public void call(Object... args) {
                                     // Authentication failed if response contains args.
                                     if (args != null && args.length > 0) {
-                                        onDisconnect.call("Authentication failed: " + args[0]);
+                                        onDisconnect.call(args);
 
                                         System.exit(1);
                                     }
@@ -312,6 +314,11 @@ public class AgentLauncher {
                     .on(EVENT_SCHEMA_IMPORT_METADATA, dbHnd.metadataListener())
                     .on(EVENT_ERROR, onError)
                     .on(EVENT_DISCONNECT, onDisconnect)
+                    .on(EVENT_AGENT_WARNING, new Emitter.Listener() {
+                        @Override public void call(Object... args) {
+                            log.warn(args[0]);
+                        }
+                    })
                     .on(EVENT_AGENT_CLOSE, new Emitter.Listener() {
                         @Override public void call(Object... args) {
                             onDisconnect.call(args);

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java
----------------------------------------------------------------------
diff --git a/modules/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java b/modules/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java
index d09e5c7..bf0903a 100644
--- a/modules/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java
+++ b/modules/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java
@@ -18,10 +18,13 @@
 package org.apache.ignite.console.demo;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.Random;
+import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -55,6 +58,8 @@ import org.apache.ignite.transactions.Transaction;
 import org.apache.log4j.Logger;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_PERFORMANCE_SUGGESTIONS_DISABLED;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_UPDATE_NOTIFIER;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_JETTY_PORT;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_NO_ASCII;
 import static org.apache.ignite.events.EventType.EVTS_DISCOVERY;
@@ -80,16 +85,24 @@ public class AgentClusterDemo {
 
     /** */
     private static final String COUNTRY_CACHE_NAME = "CountryCache";
+
     /** */
     private static final String DEPARTMENT_CACHE_NAME = "DepartmentCache";
+
     /** */
     private static final String EMPLOYEE_CACHE_NAME = "EmployeeCache";
+
     /** */
     private static final String PARKING_CACHE_NAME = "ParkingCache";
+
     /** */
     private static final String CAR_CACHE_NAME = "CarCache";
 
     /** */
+    private static final Set<String> DEMO_CACHES = new HashSet<>(Arrays.asList(COUNTRY_CACHE_NAME,
+        DEPARTMENT_CACHE_NAME, EMPLOYEE_CACHE_NAME, PARKING_CACHE_NAME, CAR_CACHE_NAME));
+
+    /** */
     private static final Random rnd = new Random();
 
     /** Countries count. */
@@ -320,9 +333,7 @@ public class AgentClusterDemo {
         IgniteConfiguration cfg = new IgniteConfiguration();
 
         cfg.setGridName((client ? "demo-server-" : "demo-client-") + gridIdx);
-
         cfg.setLocalHost("127.0.0.1");
-
         cfg.setIncludeEventTypes(EVTS_DISCOVERY);
 
         TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder();
@@ -333,7 +344,6 @@ public class AgentClusterDemo {
         TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
 
         discoSpi.setLocalPort(60900);
-
         discoSpi.setIpFinder(ipFinder);
 
         cfg.setDiscoverySpi(discoSpi);
@@ -341,21 +351,17 @@ public class AgentClusterDemo {
         TcpCommunicationSpi commSpi = new TcpCommunicationSpi();
 
         commSpi.setSharedMemoryPort(-1);
-
         commSpi.setLocalPort(60800);
 
         cfg.setCommunicationSpi(commSpi);
-
         cfg.setGridLogger(new Log4JLogger(log));
-
         cfg.setMetricsLogFrequency(0);
-
         cfg.getConnectorConfiguration().setPort(60700);
 
         if (client)
             cfg.setClientMode(true);
-        else
-            cfg.setCacheConfiguration(cacheCountry(), cacheDepartment(), cacheEmployee(), cacheParking(), cacheCar());
+
+        cfg.setCacheConfiguration(cacheCountry(), cacheDepartment(), cacheEmployee(), cacheParking(), cacheCar());
 
         return cfg;
     }
@@ -477,7 +483,6 @@ public class AgentClusterDemo {
         final long diff = new java.util.Date().getTime();
 
         populateCacheEmployee(ignite, diff);
-
         populateCacheCar(ignite);
 
         ScheduledExecutorService cachePool = newScheduledThreadPool(2, "demo-sql-load-cache-tasks");
@@ -485,32 +490,49 @@ public class AgentClusterDemo {
         cachePool.scheduleWithFixedDelay(new Runnable() {
             @Override public void run() {
                 try {
+                    for (String cacheName : ignite.cacheNames()) {
+                        if (!DEMO_CACHES.contains(cacheName)) {
+                            IgniteCache<Integer, String> otherCache = ignite.cache(cacheName);
+
+                            if (otherCache != null) {
+                                for (int i = 0, n = 1; i < cnt; i++, n++) {
+                                    Integer key = rnd.nextInt(1000);
+
+                                    String val = otherCache.get(key);
+
+                                    if (val == null)
+                                        otherCache.put(key, "other-" + key);
+                                    else if (rnd.nextInt(100) < 30)
+                                        otherCache.remove(key);
+                                }
+                            }
+                        }
+                    }
+
                     IgniteCache<Integer, Employee> cacheEmployee = ignite.cache(EMPLOYEE_CACHE_NAME);
 
-                    if (cacheEmployee == null)
-                        return;
+                    if (cacheEmployee != null)
+                        try(Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {
+                            for (int i = 0, n = 1; i < cnt; i++, n++) {
+                                Integer id = rnd.nextInt(EMPL_CNT);
 
-                    try(Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {
-                        for (int i = 0, n = 1; i < cnt; i++, n++) {
-                            Integer id = rnd.nextInt(EMPL_CNT);
+                                Integer depId = rnd.nextInt(DEP_CNT);
 
-                            Integer depId = rnd.nextInt(DEP_CNT);
+                                double r = rnd.nextDouble();
 
-                            double r = rnd.nextDouble();
+                                cacheEmployee.put(id, new Employee(id, depId, depId, "First name employee #" + n,
+                                    "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n,
+                                    new java.sql.Date((long)(r * diff)), "Job employee #" + n, 500 + round(r * 2000, 2)));
 
-                            cacheEmployee.put(id, new Employee(id, depId, depId, "First name employee #" + n,
-                                "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n,
-                                new java.sql.Date((long)(r * diff)), "Job employee #" + n, 500 + round(r * 2000, 2)));
+                                if (rnd.nextBoolean())
+                                    cacheEmployee.remove(rnd.nextInt(EMPL_CNT));
 
-                            if (rnd.nextBoolean())
-                                cacheEmployee.remove(rnd.nextInt(EMPL_CNT));
+                                cacheEmployee.get(rnd.nextInt(EMPL_CNT));
+                            }
 
-                            cacheEmployee.get(rnd.nextInt(EMPL_CNT));
+                            if (rnd.nextInt(100) > 20)
+                                tx.commit();
                         }
-
-                        if (rnd.nextInt(100) > 20)
-                            tx.commit();
-                    }
                 }
                 catch (Throwable e) {
                     if (!e.getMessage().contains("cache is stopped"))
@@ -553,6 +575,8 @@ public class AgentClusterDemo {
             log.info("DEMO: Starting embedded nodes for demo...");
 
             System.setProperty(IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE, "1");
+            System.setProperty(IGNITE_PERFORMANCE_SUGGESTIONS_DISABLED, "true");
+            System.setProperty(IGNITE_UPDATE_NOTIFIER, "false");
 
             System.setProperty(IGNITE_JETTY_PORT, "60800");
             System.setProperty(IGNITE_NO_ASCII, "true");
@@ -598,12 +622,12 @@ public class AgentClusterDemo {
 
                 acfg.demoNodeUri(String.format("http://%s:%d", host, port));
 
-                log.info("DEMO: Embedded nodes for sql test-drive successfully started");
+                log.info("DEMO: Embedded nodes for sql and monitoring demo successfully started");
 
                 startLoad(ignite, 20);
             }
             catch (Exception e) {
-                log.error("DEMO: Failed to start embedded node for sql test-drive!", e);
+                log.error("DEMO: Failed to start embedded node for sql and monitoring demo!", e);
 
                 return false;
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/README.txt
----------------------------------------------------------------------
diff --git a/modules/web-console/README.txt b/modules/web-console/README.txt
index ae509d6..286082c 100644
--- a/modules/web-console/README.txt
+++ b/modules/web-console/README.txt
@@ -7,7 +7,7 @@ The Apache Ignite Web Console includes an interactive configuration wizard which
  on your in-memory cache as well as view execution plans, in-memory schema, and streaming charts.
 
 In order to simplify evaluation of Web Console demo mode was implemented.
- To start demo, you need to to click button "Start demo". New tab will be open with prepared demo data on each screen.
+ To start demo, you need to click button "Start demo". New tab will be open with prepared demo data on each screen.
 
  Demo for import domain model from database.
   In this mode an in-memory H2 database will be started.
@@ -24,7 +24,7 @@ In order to simplify evaluation of Web Console demo mode was implemented.
     In this mode internal Ignite node will be started. Cache created and populated with data.
      1) Click "SQL" in Ignite Web Console top menu.
      2) "Demo" notebook with preconfigured queries will be opened.
-     3) You can also execute any SQL queries for tables: "Country, Department, Employee", "Parking, Car".
+     3) You can also execute any SQL queries for tables: "Country, Department, Employee, Parking, Car".
 
  For example:
   1) Enter SQL statement:

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/.eslintrc
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/.eslintrc b/modules/web-console/src/main/js/.eslintrc
index 00fa0ad..1882b44 100644
--- a/modules/web-console/src/main/js/.eslintrc
+++ b/modules/web-console/src/main/js/.eslintrc
@@ -20,6 +20,8 @@ ecmaFeatures:
 
 globals:
     _: true
+    $: true
+    d3: true
     io: true
     window: true
     global: true
@@ -123,7 +125,7 @@ rules:
     no-multiple-empty-lines: [0, {"max": 2}]
     no-native-reassign: 2
     no-negated-in-lhs: 2
-    no-nested-ternary: 2
+    no-nested-ternary: 0
     no-new: 2
     no-new-func: 2
     no-new-object: 2
@@ -195,3 +197,6 @@ rules:
     wrap-iife: 0
     wrap-regex: 0
     yoda: [2, "never"]
+
+parserOptions:
+    sourceType: module

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/data/getting-started.json
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/data/getting-started.json b/modules/web-console/src/main/js/app/data/getting-started.json
index 7aff0b4..1b435ab 100644
--- a/modules/web-console/src/main/js/app/data/getting-started.json
+++ b/modules/web-console/src/main/js/app/data/getting-started.json
@@ -81,7 +81,7 @@
           "</div>",
           "<div class='col-xs-5'>",
           " <ul>",
-          "  <li>Preview XML Configuration</li>",
+          "  <li>Preview XML configuration</li>",
           "  <li>Preview code configuration</li>",
           "  <li>Preview Docker file</li>",
           "  <li>Preview POM dependencies</li>",

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/data/pom-dependencies.json
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/data/pom-dependencies.json b/modules/web-console/src/main/js/app/data/pom-dependencies.json
new file mode 100644
index 0000000..7ab6c1b
--- /dev/null
+++ b/modules/web-console/src/main/js/app/data/pom-dependencies.json
@@ -0,0 +1,20 @@
+{
+    "Cloud": {"artifactId": "ignite-cloud"},
+    "S3": {"artifactId": "ignite-aws"},
+    "GoogleStorage": {"artifactId": "ignite-gce"},
+    "ZooKeeper": {"artifactId": "ignite-zookeeper"},
+
+    "Log4j": {"artifactId": "ignite-log4j"},
+    "Log4j2": {"artifactId": "ignite-log4j2"},
+    "JCL": {"artifactId": "ignite-jcl"},
+    "HadoopIgfsJcl": {"artifactId": "ignite-hadoop"},
+    "SLF4J": {"artifactId": "ignite-slf4j"},
+
+    "Generic": {"groupId": "com.mchange", "artifactId": "c3p0", "version": "0.9.5.1"},
+    "MySQL": {"groupId": "mysql", "artifactId": "mysql-connector-java", "version": "5.1.37"},
+    "PostgreSQL": {"groupId": "org.postgresql", "artifactId": "postgresql", "version": "9.4-1204-jdbc42"},
+    "H2": {"groupId": "com.h2database", "artifactId": "h2", "version": "1.3.175"},
+    "Oracle": {"groupId": "oracle", "artifactId": "jdbc", "version": "11.2", "jar": "ojdbc6.jar"},
+    "DB2": {"groupId": "ibm", "artifactId": "jdbc", "version": "4.19.26", "jar": "db2jcc4.jar"},
+    "SQLServer": {"groupId": "microsoft", "artifactId": "jdbc", "version": "4.1", "jar": "sqljdbc41.jar"}
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/directives/ui-ace-docker/ui-ace-docker.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/directives/ui-ace-docker/ui-ace-docker.jade b/modules/web-console/src/main/js/app/directives/ui-ace-docker/ui-ace-docker.jade
index f634aed..3b0e7b8 100644
--- a/modules/web-console/src/main/js/app/directives/ui-ace-docker/ui-ace-docker.jade
+++ b/modules/web-console/src/main/js/app/directives/ui-ace-docker/ui-ace-docker.jade
@@ -17,7 +17,7 @@
 mixin hard-link(ref, txt)
     a(style='color:#ec1c24' href=ref target='_blank') #{txt}
 
-div
+.panel-details-noborder
     .details-row
         p
             +hard-link('https://docs.docker.com/reference/builder', 'Docker')
@@ -28,4 +28,4 @@ div
             | . For more information about using Ignite with Docker please read&nbsp;
             +hard-link('http://apacheignite.readme.io/docs/docker-deployment', 'documentation')
             |.
-    div(ng-if='ctrl.data' ignite-ace='{onLoad: onLoad, mode: "dockerfile"}' ng-model='ctrl.data')
+    .details-row(ng-if='ctrl.data' ignite-ace='{onLoad: onLoad, mode: "dockerfile"}' ng-model='ctrl.data')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js b/modules/web-console/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js
index 948f82c..cdce0fc 100644
--- a/modules/web-console/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js
+++ b/modules/web-console/src/main/js/app/directives/ui-ace-java/ui-ace-java.directive.js
@@ -95,9 +95,9 @@ export default ['igniteUiAceJava', ['GeneratorJava', (generator) => {
             }
         }
 
-        if (typeof attrs.clusterCfg !== 'undefined') {
+        if (!_.isUndefined(attrs.clusterCfg)) {
             scope.$watch('cfg', (cfg) => {
-                if (typeof cfg !== 'undefined')
+                if (!_.isUndefined(cfg))
                     return;
 
                 scope.cfg = {};

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/directives/ui-ace-pojos/ui-ace-pojos.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/directives/ui-ace-pojos/ui-ace-pojos.jade b/modules/web-console/src/main/js/app/directives/ui-ace-pojos/ui-ace-pojos.jade
index 3e82f12..ed1432b 100644
--- a/modules/web-console/src/main/js/app/directives/ui-ace-pojos/ui-ace-pojos.jade
+++ b/modules/web-console/src/main/js/app/directives/ui-ace-pojos/ui-ace-pojos.jade
@@ -17,7 +17,7 @@
 mixin check-tooltip(message)
     i.tipLabel.fa.fa-question-circle(bs-tooltip='"#{message}"')
 
-div
+.panel-details-noborder
     .details-row
         .col-xs-2.col-sm-2.col-md-2
             label POJO class:
@@ -37,4 +37,4 @@ div
                 input(type='checkbox' ng-model='ctrl.includeKeyFields')
                 | Include key fields
             +check-tooltip("Generate key fields in POJO value class")
-    div(ng-if='ctrl.data' ignite-ace='{onLoad: onLoad, mode: "java"}' ng-model='ctrl.data')
+    .details-row(ng-if='ctrl.data' ignite-ace='{onLoad: onLoad, mode: "java"}' ng-model='ctrl.data')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js b/modules/web-console/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js
index 79787a2..1e913fb 100644
--- a/modules/web-console/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js
+++ b/modules/web-console/src/main/js/app/directives/ui-ace-xml/ui-ace-xml.directive.js
@@ -95,9 +95,9 @@ export default ['igniteUiAceXml', ['GeneratorXml', (generator) => {
             }
         }
 
-        if (typeof attrs.clusterCfg !== 'undefined') {
+        if (!_.isUndefined(attrs.clusterCfg)) {
             scope.$watch('cfg', (cfg) => {
-                if (typeof cfg !== 'undefined')
+                if (!_.isUndefined(cfg))
                     return;
 
                 scope.cfg = {};

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/helpers/jade/mixins.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/helpers/jade/mixins.jade b/modules/web-console/src/main/js/app/helpers/jade/mixins.jade
index 341d351..2b8b282 100644
--- a/modules/web-console/src/main/js/app/helpers/jade/mixins.jade
+++ b/modules/web-console/src/main/js/app/helpers/jade/mixins.jade
@@ -353,7 +353,7 @@ mixin table-text-field(field, items, valid, save, placeholder, newItem)
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
-        data-name=field
+        data-name='#{field}{{ $index || "" }}'
         data-ng-model=field
         data-ng-required='true'
         data-placeholder=placeholder
@@ -376,7 +376,7 @@ mixin table-java-class-field(lbl, field, items, valid, save, newItem)
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
-        data-name=field
+        data-name='#{field}{{ $index || "" }}'
         data-ng-model=field
         data-ng-required='true'
         data-ignite-unique=items
@@ -411,7 +411,7 @@ mixin table-java-package-field(field, items, valid, save, newItem)
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
-        data-name=field
+        data-name='#{field}{{ $index || "" }}'
         data-ng-model=field
         data-ng-required='true'
         data-placeholder='Enter package name'
@@ -436,7 +436,7 @@ mixin table-address-field(field, items, valid, save, newItem, portRange)
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
-        data-name=field
+        data-name='#{field}{{ $index || "" }}'
         data-ng-model=field
         data-ng-required='true'
         data-placeholder='IP address:port'
@@ -466,8 +466,9 @@ mixin table-save-button(valid, save, newItem)
 //- Mixin for table remove button.
 mixin table-remove-conditional-button(items, show, tip)
     i.tipField.fa.fa-remove(
-        ng-show='#{show} && !field.edit'
-        bs-tooltip='"#{tip}"'
+        ng-hide='!#{show} || field.edit'
+        bs-tooltip
+        data-title=tip
         ng-click='#{items}.splice(#{items}.indexOf(model), 1)'
     )
 
@@ -519,12 +520,12 @@ mixin evictionPolicy(model, name, enabled, required, tip)
 
 //- Mixin for clusters dropdown.
 mixin clusters(model, tip)
-    +dropdown-multiple('<span>Clusters:</span>' + '<a ui-sref="base.configuration.clusters({id: ' + model + '._id})"> (add)</a>',
+    +dropdown-multiple('<span>Clusters:</span>' + '<a ui-sref="base.configuration.clusters({linkId: linkId()})"> (add)</a>',
         model + '.clusters', 'clusters', 'true', 'Choose clusters', 'No clusters configured', 'clusters', tip)
 
 //- Mixin for caches dropdown.
 mixin caches(model, tip)
-    +dropdown-multiple('<span>Caches:</span>' + '<a ui-sref="base.configuration.caches({id: ' + model + '._id})"> (add)</a>',
+    +dropdown-multiple('<span>Caches:</span>' + '<a ui-sref="base.configuration.caches({linkId: linkId()})"> (add)</a>',
         model + '.caches', 'caches', 'true', 'Choose caches', 'No caches configured', 'caches', tip)
 
 //- Mixin for XML and Java preview.

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/index.js b/modules/web-console/src/main/js/app/index.js
index a8bd741..397d25f 100644
--- a/modules/web-console/src/main/js/app/index.js
+++ b/modules/web-console/src/main/js/app/index.js
@@ -56,10 +56,11 @@ import 'angular-motion/dist/angular-motion.css!';
 import './decorator/select';
 import './decorator/tooltip';
 
-import './modules/Demo/Demo.module';
-import './modules/form/form.module';
 import './services/JavaTypes.service.js';
-import './modules/QueryNotebooks/QueryNotebooks.provider';
+import './modules/form/form.module';
+import './modules/agent/agent.module.js';
+import './modules/query-notebooks/query-notebooks.module';
+import './modules/Demo/Demo.module.js';
 
 import './modules/states/signin.state';
 import './modules/states/logout.state';
@@ -100,7 +101,6 @@ import confirm from './services/confirm.service';
 import IgniteInetAddress from './services/InetAddress.service';
 import IgniteCountries from './services/Countries.service';
 import IgniteChartColors from './services/ChartColors.service';
-import IgniteAgentMonitor from './services/AgentMonitor.service';
 import JavaTypes from './services/JavaTypes.service';
 
 // Providers.
@@ -149,13 +149,14 @@ angular
     'ui.router',
     'gridster',
     // Base modules.
+    'ignite-console.ace',
+    'ignite-console.Form',
     'ignite-console.user',
     'ignite-console.branding',
-    'ignite-console.Form',
-    'ignite-console.QueryNotebooks',
-    'ignite-console.ace',
-    'ignite-console.demo',
     'ignite-console.socket',
+    'ignite-console.agent',
+    'ignite-console.query-notebooks',
+    'ignite-console.demo',
     // States.
     'ignite-console.states.login',
     'ignite-console.states.logout',
@@ -193,7 +194,6 @@ angular
 .service(...IgniteInetAddress)
 .service(...IgniteCountries)
 .service(...IgniteChartColors)
-.service(...IgniteAgentMonitor)
 .service(...JavaTypes)
 // Providers.
 // Filters.

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/Demo/Demo.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/Demo/Demo.module.js b/modules/web-console/src/main/js/app/modules/Demo/Demo.module.js
index adf5a82..f08d84c 100644
--- a/modules/web-console/src/main/js/app/modules/Demo/Demo.module.js
+++ b/modules/web-console/src/main/js/app/modules/Demo/Demo.module.js
@@ -111,9 +111,11 @@ angular
         return items;
     }];
 }])
-.service('DemoInfo', ['$rootScope', '$modal', '$state', 'igniteDemoInfo', 'IgniteAgentMonitor', ($rootScope, $modal, $state, igniteDemoInfo, agentMonitor) => {
+.service('DemoInfo', ['$rootScope', '$modal', '$state', '$q', 'igniteDemoInfo', 'IgniteAgentMonitor', ($rootScope, $modal, $state, $q, igniteDemoInfo, agentMonitor) => {
     const scope = $rootScope.$new();
 
+    let closePromise = null;
+
     function _fillPage() {
         const model = igniteDemoInfo;
 
@@ -131,10 +133,8 @@ angular
 
     scope.close = () => {
         dialog.hide();
-    };
 
-    scope.gotoConfiguration = () => {
-        scope.$$postDigest(() => $state.go('base.configuration.clusters'));
+        closePromise && closePromise.resolve();
     };
 
     scope.downloadAgent = () => {
@@ -154,11 +154,13 @@ angular
 
     return {
         show: () => {
+            closePromise = $q.defer();
+
             _fillPage();
 
-            dialog.$promise
+            return dialog.$promise
                 .then(dialog.show)
-                .then(() => agentMonitor.awaitAgent())
+                .then(() => Promise.race([agentMonitor.awaitAgent(), closePromise.promise]))
                 .then(() => scope.hasAgents = true);
         }
     };

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/QueryNotebooks/QueryNotebooks.provider.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/QueryNotebooks/QueryNotebooks.provider.js b/modules/web-console/src/main/js/app/modules/QueryNotebooks/QueryNotebooks.provider.js
deleted file mode 100644
index 7e4e523..0000000
--- a/modules/web-console/src/main/js/app/modules/QueryNotebooks/QueryNotebooks.provider.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.
- */
-
-import angular from 'angular';
-
-angular
-    .module('ignite-console.QueryNotebooks', [
-
-    ])
-    .provider('QueryNotebooks', function() {
-        const _demoNotebook = {
-            name: 'SQL demo',
-            paragraphs: [
-                {
-                    name: 'Query with refresh rate',
-                    cacheName: 'CarCache',
-                    pageSize: 50,
-                    query: 'SELECT count(*)\nFROM "CarCache".Car',
-                    result: 'bar',
-                    timeLineSpan: '1',
-                    rate: {
-                        value: 3,
-                        unit: 1000,
-                        installed: true
-                    }
-                },
-                {
-                    name: 'Simple query',
-                    cacheName: 'CarCache',
-                    pageSize: 50,
-                    query: 'SELECT * FROM "CarCache".Car',
-                    result: 'table',
-                    timeLineSpan: '1',
-                    rate: {
-                        value: 30,
-                        unit: 1000,
-                        installed: false
-                    }
-                },
-                {
-                    name: 'Query with aggregates',
-                    cacheName: 'CarCache',
-                    pageSize: 50,
-                    query: 'SELECT p.name, count(*) AS cnt\nFROM "ParkingCache".Parking p\nINNER JOIN "CarCache".Car c\n  ON (p.id) = (c.parkingId)\nGROUP BY P.NAME',
-                    result: 'table',
-                    timeLineSpan: '1',
-                    rate: {
-                        value: 30,
-                        unit: 1000,
-                        installed: false
-                    }
-                }
-            ],
-            expandedParagraphs: [0, 1, 2]
-        };
-
-        this.$get = ['$q', '$http', '$rootScope', ($q, $http, $root) => {
-            return {
-                read(noteId) {
-                    if ($root.IgniteDemoMode)
-                        return $q.when(angular.copy(_demoNotebook));
-
-                    return $http.post('/api/v1/notebooks/get', {noteId})
-                        .then(({data}) => data)
-                        .catch(({data}) => $q.reject(data));
-                },
-                save(notebook) {
-                    if ($root.IgniteDemoMode)
-                        return $q.when();
-
-                    return $http.post('/api/v1/notebooks/save', notebook)
-                        .then(({data}) => data)
-                        .catch(({data}) => $q.reject(data));
-                },
-                remove(notebook) {
-                    if ($root.IgniteDemoMode)
-                        return $q.reject(`Removing "${notebook.name}" notebook is not supported.`);
-
-                    return $http.post('/api/v1/notebooks/remove', {_id: notebook._id})
-                        .then(() => {
-                            const idx = _.findIndex($root.notebooks, (item) => {
-                                return item._id === notebook._id;
-                            });
-
-                            if (idx >= 0) {
-                                $root.notebooks.splice(idx, 1);
-
-                                $root.rebuildDropdown();
-
-                                if (idx < $root.notebooks.length)
-                                    return $root.notebooks[idx];
-                            }
-
-                            if ($root.notebooks.length > 0)
-                                return $root.notebooks[$root.notebooks.length - 1];
-                        })
-                        .catch(({data}) => $q.reject(data));
-                }
-            };
-        }];
-    });

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/agent/agent.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/agent/agent.module.js b/modules/web-console/src/main/js/app/modules/agent/agent.module.js
new file mode 100644
index 0000000..4e3f7ef
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/agent/agent.module.js
@@ -0,0 +1,323 @@
+/*
+ * 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.
+ */
+
+import angular from 'angular';
+import io from 'socket.io-client'; // eslint-disable-line no-unused-vars
+
+class IgniteAgentMonitor {
+    constructor(socketFactory, $root, $q, $state, $modal, $common) {
+        this._scope = $root.$new();
+
+        $root.$watch('user', () => {
+            this._scope.user = $root.user;
+        });
+
+        $root.$on('$stateChangeStart', () => {
+            this.stopWatch();
+        });
+
+        // Pre-fetch modal dialogs.
+        this._downloadAgentModal = $modal({
+            scope: this._scope,
+            templateUrl: '/templates/agent-download.html',
+            show: false,
+            backdrop: 'static',
+            keyboard: false
+        });
+
+        const _modalHide = this._downloadAgentModal.hide;
+
+        /**
+         * Special dialog hide function.
+         */
+        this._downloadAgentModal.hide = () => {
+            $common.hideAlert();
+
+            _modalHide();
+        };
+
+        /**
+         * Close dialog and go by specified link.
+         */
+        this._scope.back = () => {
+            this.stopWatch();
+
+            if (this._scope.backState)
+                this._scope.$$postDigest(() => $state.go(this._scope.backState));
+        };
+
+        this._scope.downloadAgent = () => {
+            const lnk = document.createElement('a');
+
+            lnk.setAttribute('href', '/api/v1/agent/download/zip');
+            lnk.setAttribute('target', '_self');
+            lnk.setAttribute('download', null);
+            lnk.style.display = 'none';
+
+            document.body.appendChild(lnk);
+
+            lnk.click();
+
+            document.body.removeChild(lnk);
+        };
+
+        this._scope.hasAgents = null;
+        this._scope.showModal = false;
+
+        /**
+         * @type {Socket}
+         */
+        this._socket = null;
+
+        this._socketFactory = socketFactory;
+
+        this._$q = $q;
+
+        this._$common = $common;
+    }
+
+    /**
+     * @private
+     */
+    checkModal() {
+        if (this._scope.showModal && !this._scope.hasAgents)
+            this._downloadAgentModal.$promise.then(this._downloadAgentModal.show);
+        else if ((this._scope.hasAgents || !this._scope.showModal) && this._downloadAgentModal.$isShown)
+            this._downloadAgentModal.hide();
+    }
+
+    /**
+     * @returns {Promise}
+     */
+    awaitAgent() {
+        if (this._scope.hasAgents)
+            return this._$q.when();
+
+        const latch = this._$q.defer();
+
+        const offConnected = this._scope.$on('agent:watch', (event, state) => {
+            if (state !== 'DISCONNECTED')
+                offConnected();
+
+            if (state === 'CONNECTED')
+                return latch.resolve();
+
+            if (state === 'STOPPED')
+                return latch.reject('Agent watch stopped.');
+        });
+
+        return latch.promise;
+    }
+
+    init() {
+        this._socket = this._socketFactory();
+
+        const disconnectFn = () => {
+            this._scope.hasAgents = false;
+
+            this.checkModal();
+
+            this._scope.$broadcast('agent:watch', 'DISCONNECTED');
+        };
+
+        this._socket.on('connect_error', disconnectFn);
+        this._socket.on('disconnect', disconnectFn);
+
+        this._socket.on('agent:count', ({count}) => {
+            this._scope.hasAgents = count > 0;
+
+            this.checkModal();
+
+            this._scope.$broadcast('agent:watch', this._scope.hasAgents ? 'CONNECTED' : 'DISCONNECTED');
+        });
+    }
+
+    /**
+     * @param {Object} back
+     * @returns {Promise}
+     */
+    startWatch(back) {
+        this._scope.backState = back.state;
+        this._scope.backText = back.text;
+
+        this._scope.agentGoal = back.goal;
+
+        if (back.onDisconnect) {
+            this._scope.offDisconnect = this._scope.$on('agent:watch', (e, state) =>
+                state === 'DISCONNECTED' && back.onDisconnect());
+        }
+
+        this._scope.showModal = true;
+
+        // Remove blinking on init.
+        if (this._scope.hasAgents !== null)
+            this.checkModal();
+
+        return this.awaitAgent();
+    }
+
+    /**
+     *
+     * @param {String} event
+     * @param {Object} [args]
+     * @returns {Promise}
+     * @private
+     */
+    _emit(event, ...args) {
+        if (!this._socket)
+            return this._$q.reject('Failed to connect to server');
+
+        const latch = this._$q.defer();
+
+        const onDisconnect = () => {
+            this._socket.removeListener('disconnect', onDisconnect);
+
+            latch.reject('Connection to server was closed');
+        };
+
+        this._socket.on('disconnect', onDisconnect);
+
+        args.push((err, res) => {
+            this._socket.removeListener('disconnect', onDisconnect);
+
+            if (err)
+                latch.reject(err);
+
+            latch.resolve(res);
+        });
+
+        this._socket.emit(event, ...args);
+
+        return latch.promise;
+    }
+
+    drivers() {
+        return this._emit('schemaImport:drivers');
+    }
+
+    /**
+     *
+     * @param {Object} preset
+     * @returns {Promise}
+     */
+    schemas(preset) {
+        return this._emit('schemaImport:schemas', preset);
+    }
+
+    /**
+     *
+     * @param {Object} preset
+     * @returns {Promise}
+     */
+    tables(preset) {
+        return this._emit('schemaImport:tables', preset);
+    }
+
+    /**
+     * @param {Object} err
+     */
+    showNodeError(err) {
+        if (this._scope.showModal) {
+            this._downloadAgentModal.$promise.then(this._downloadAgentModal.show);
+
+            this._$common.showError(err);
+        }
+    }
+
+    /**
+     *
+     * @param {String} event
+     * @param {Object} [args]
+     * @returns {Promise}
+     * @private
+     */
+    _rest(event, ...args) {
+        return this._downloadAgentModal.$promise
+            .then(() => this._emit(event, ...args));
+    }
+
+    /**
+     * @param {Boolean} [attr]
+     * @param {Boolean} [mtr]
+     * @returns {Promise}
+     */
+    topology(attr, mtr) {
+        return this._rest('node:topology', !!attr, !!mtr);
+    }
+
+    /**
+     * @param {int} [queryId]
+     * @returns {Promise}
+     */
+    queryClose(queryId) {
+        return this._rest('node:query:close', queryId);
+    }
+
+    /**
+     * @param {String} cacheName Cache name.
+     * @param {int} pageSize
+     * @param {String} [query] Query if null then scan query.
+     * @returns {Promise}
+     */
+    query(cacheName, pageSize, query) {
+        return this._rest('node:query', _.isEmpty(cacheName) ? null : cacheName, pageSize, query);
+    }
+
+    /**
+     * @param {String} cacheName Cache name.
+     * @param {String} [query] Query if null then scan query.
+     * @returns {Promise}
+     */
+    queryGetAll(cacheName, query) {
+        return this._rest('node:query:getAll', _.isEmpty(cacheName) ? null : cacheName, query);
+    }
+
+    /**
+     * @param {String} [cacheName] Cache name.
+     * @returns {Promise}
+     */
+    metadata(cacheName) {
+        return this._rest('node:cache:metadata', _.isEmpty(cacheName) ? null : cacheName);
+    }
+
+    /**
+     * @param {int} queryId
+     * @param {int} pageSize
+     * @returns {Promise}
+     */
+    next(queryId, pageSize) {
+        return this._rest('node:query:fetch', queryId, pageSize);
+    }
+
+    stopWatch() {
+        this._scope.showModal = false;
+
+        this.checkModal();
+
+        this._scope.offDisconnect && this._scope.offDisconnect();
+
+        this._scope.$broadcast('agent:watch', 'STOPPED');
+    }
+}
+
+IgniteAgentMonitor.$inject = ['igniteSocketFactory', '$rootScope', '$q', '$state', '$modal', '$common'];
+
+angular
+    .module('ignite-console.agent', [
+
+    ])
+    .service('IgniteAgentMonitor', IgniteAgentMonitor);

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/configuration/generator/Pom.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/configuration/generator/Pom.service.js b/modules/web-console/src/main/js/app/modules/configuration/generator/Pom.service.js
index cf266e1..3508e59 100644
--- a/modules/web-console/src/main/js/app/modules/configuration/generator/Pom.service.js
+++ b/modules/web-console/src/main/js/app/modules/configuration/generator/Pom.service.js
@@ -15,6 +15,9 @@
  * limitations under the License.
  */
 
+// Java built-in class names.
+import POM_DEPENDENCIES from 'app/data/pom-dependencies.json!';
+
 /**
  * Pom file generation entry point.
  */
@@ -31,7 +34,8 @@ class GeneratorPom {
     }
 
     addDependency(deps, groupId, artifactId, version, jar) {
-        deps.push({groupId, artifactId, version, jar});
+        if (!_.find(deps, (dep) => dep.groupId === groupId && dep.artifactId === artifactId))
+            deps.push({groupId, artifactId, version, jar});
     }
 
     addResource(res, dir, exclude) {
@@ -132,8 +136,8 @@ class GeneratorPom {
      */
     generate(cluster, igniteVersion, res) {
         const caches = cluster.caches;
-        const dialect = {};
         const deps = [];
+        const storeDeps = [];
         const excludeGroupIds = ['org.apache.ignite'];
 
         const blobStoreFactory = {cacheStoreFactory: {kind: 'CacheHibernateBlobStoreFactory'}};
@@ -145,8 +149,11 @@ class GeneratorPom {
             if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) {
                 const storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind];
 
-                if (storeFactory.dialect && (!storeFactory.connectVia || storeFactory.connectVia === 'DataSource'))
-                    dialect[storeFactory.dialect] = true;
+                if (storeFactory.dialect && (!storeFactory.connectVia || storeFactory.connectVia === 'DataSource')) {
+                    const dep = POM_DEPENDENCIES[storeFactory.dialect];
+
+                    this.addDependency(storeDeps, dep.groupId, dep.artifactId, dep.version, dep.jar);
+                }
             }
         });
 
@@ -172,14 +179,10 @@ class GeneratorPom {
         this.addDependency(deps, 'org.apache.ignite', 'ignite-indexing', igniteVersion);
         this.addDependency(deps, 'org.apache.ignite', 'ignite-rest-http', igniteVersion);
 
-        if (cluster.discovery.kind === 'Cloud')
-            this.addDependency(deps, 'org.apache.ignite', 'ignite-cloud', igniteVersion);
-        else if (cluster.discovery.kind === 'S3')
-            this.addDependency(deps, 'org.apache.ignite', 'ignite-aws', igniteVersion);
-        else if (cluster.discovery.kind === 'GoogleStorage')
-            this.addDependency(deps, 'org.apache.ignite', 'ignite-gce', igniteVersion);
-        else if (cluster.discovery.kind === 'ZooKeeper')
-            this.addDependency(deps, 'org.apache.ignite', 'ignite-zookeeper', igniteVersion);
+        let dep = POM_DEPENDENCIES[cluster.discovery.kind];
+
+        if (dep)
+            this.addDependency(deps, 'org.apache.ignite', dep.artifactId, igniteVersion);
 
         if (_.find(cluster.igfss, (igfs) => igfs.secondaryFileSystemEnabled))
             this.addDependency(deps, 'org.apache.ignite', 'ignite-hadoop', igniteVersion);
@@ -187,21 +190,14 @@ class GeneratorPom {
         if (_.find(caches, blobStoreFactory))
             this.addDependency(deps, 'org.apache.ignite', 'ignite-hibernate', igniteVersion);
 
-        dialect.Generic && this.addDependency(deps, 'com.mchange', 'c3p0', '0.9.5.1');
-
-        dialect.MySQL && this.addDependency(deps, 'mysql', 'mysql-connector-java', '5.1.37');
-
-        dialect.PostgreSQL && this.addDependency(deps, 'org.postgresql', 'postgresql', '9.4-1204-jdbc42');
+        if (cluster.logger && cluster.logger.kind) {
+            dep = POM_DEPENDENCIES[cluster.logger.kind];
 
-        dialect.H2 && this.addDependency(deps, 'com.h2database', 'h2', '1.3.175');
-
-        dialect.Oracle && this.addDependency(deps, 'oracle', 'jdbc', '11.2', 'ojdbc6.jar');
-
-        dialect.DB2 && this.addDependency(deps, 'ibm', 'jdbc', '4.19.26', 'db2jcc4.jar');
-
-        dialect.SQLServer && this.addDependency(deps, 'microsoft', 'jdbc', '4.1', 'sqljdbc41.jar');
+            if (dep)
+                this.addDependency(deps, 'org.apache.ignite', dep.artifactId, igniteVersion);
+        }
 
-        this.dependencies(res, cluster, deps);
+        this.dependencies(res, cluster, deps.concat(storeDeps));
 
         res.needEmptyLine = true;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/form/field/input/datalist.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/form/field/input/datalist.directive.js b/modules/web-console/src/main/js/app/modules/form/field/input/datalist.directive.js
index 0cd9d69..ce67897 100644
--- a/modules/web-console/src/main/js/app/modules/form/field/input/datalist.directive.js
+++ b/modules/web-console/src/main/js/app/modules/form/field/input/datalist.directive.js
@@ -74,10 +74,10 @@ export default ['igniteFormFieldInputDatalist', ['IgniteFormGUID', '$table', (gu
         scope.ngChange = () => {
             ngModel.$setViewValue(scope.value);
 
-            if (JSON.stringify(scope.value) !== JSON.stringify(form.$defaults[name]))
-                ngModel.$setDirty();
-            else
+            if (_.isEqual(scope.value, form.$defaults[name]))
                 ngModel.$setPristine();
+            else
+                ngModel.$setDirty();
 
             setTimeout(checkValid, 100); // Use setTimeout() workaround of problem of two controllers.
         };

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/form/field/input/text.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/form/field/input/text.directive.js b/modules/web-console/src/main/js/app/modules/form/field/input/text.directive.js
index ba4407f..adcc179 100644
--- a/modules/web-console/src/main/js/app/modules/form/field/input/text.directive.js
+++ b/modules/web-console/src/main/js/app/modules/form/field/input/text.directive.js
@@ -37,11 +37,14 @@ export default ['igniteFormFieldInputText', ['IgniteFormGUID', '$table', (guid,
             label.for = scope.id;
 
             scope.label = label;
+            scope.labelName = label.name;
 
             scope.$watch('required', (required) => {
                 label.required = required || false;
             });
         }
+        else
+            scope.labelName = attrs.igniteLabelName || 'Value';
 
         form.$defaults = form.$defaults || {};
 
@@ -75,10 +78,10 @@ export default ['igniteFormFieldInputText', ['IgniteFormGUID', '$table', (guid,
         scope.ngChange = () => {
             ngModel.$setViewValue(scope.value);
 
-            if (JSON.stringify(scope.value) !== JSON.stringify(form.$defaults[name]))
-                ngModel.$setDirty();
-            else
+            if (_.isEqual(scope.value, form.$defaults[name]))
                 ngModel.$setPristine();
+            else
+                ngModel.$setDirty();
 
             setTimeout(checkValid, 100); // Use setTimeout() workaround of problem of two controllers.
         };

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/form/field/input/text.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/form/field/input/text.jade b/modules/web-console/src/main/js/app/modules/form/field/input/text.jade
index 40aef79..8a1dfc2 100644
--- a/modules/web-console/src/main/js/app/modules/form/field/input/text.jade
+++ b/modules/web-console/src/main/js/app/modules/form/field/input/text.jade
@@ -43,6 +43,6 @@ mixin feedback(isCheckPristine, error, errorMessage)
         data-ng-focus='tableReset()'
     )
 
-    +feedback(true, 'required', '{{ label.name }} could not be empty!')
+    +feedback(true, 'required', '{{ labelName }} could not be empty!')
 
     span.transclude-here

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/form/group/group.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/form/group/group.directive.js b/modules/web-console/src/main/js/app/modules/form/group/group.directive.js
index 5039d6f..0971d44 100644
--- a/modules/web-console/src/main/js/app/modules/form/group/group.directive.js
+++ b/modules/web-console/src/main/js/app/modules/form/group/group.directive.js
@@ -50,10 +50,10 @@ export default ['igniteFormGroup', [() => {
         };
 
         const setAsDirty = () => {
-            if (JSON.stringify(scope.ngModel) !== JSON.stringify(parentFormCtrl.$defaults[name]))
-                ngModelCtrl.$setDirty();
-            else
+            if (_.isEqual(scope.ngModel, parentFormCtrl.$defaults[name]))
                 ngModelCtrl.$setPristine();
+            else
+                ngModelCtrl.$setDirty();
         };
 
         scope.$watch(() => parentFormCtrl.$pristine, setAsDefault);

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/form/validator/java-keywords.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/form/validator/java-keywords.directive.js b/modules/web-console/src/main/js/app/modules/form/validator/java-keywords.directive.js
index 841c48b..d97e59a 100644
--- a/modules/web-console/src/main/js/app/modules/form/validator/java-keywords.directive.js
+++ b/modules/web-console/src/main/js/app/modules/form/validator/java-keywords.directive.js
@@ -20,15 +20,14 @@ export default ['javaKeywords', ['JavaTypes', (JavaTypes) => {
         if (_.isUndefined(attrs.javaKeywords) || !attrs.javaKeywords)
             return;
 
+        const packageOnly = attrs.javaPackageName === 'package-only';
+
         ngModel.$validators.javaKeywords = (value) => {
             if (value) {
-                if (!JavaTypes.validIdentifier(value) || !JavaTypes.packageSpecified(value))
+                if (!JavaTypes.validIdentifier(value) || (!packageOnly && !JavaTypes.packageSpecified(value)))
                     return true;
 
-                for (const item of value.split('.')) {
-                    if (JavaTypes.isKeywords(item))
-                        return false;
-                }
+                return _.findIndex(value.split('.'), JavaTypes.isKeywords) < 0;
             }
 
             return true;

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/loading/loading.css
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/loading/loading.css b/modules/web-console/src/main/js/app/modules/loading/loading.css
index fac7517..87bbc6a 100644
--- a/modules/web-console/src/main/js/app/modules/loading/loading.css
+++ b/modules/web-console/src/main/js/app/modules/loading/loading.css
@@ -25,7 +25,7 @@
     left: 0;
     right: 0;
     top: 0;
-    z-index: 1002;
+    z-index: 1001;
     opacity: 0;
     visibility: hidden;
     background-color: white;

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/query-notebooks/query-notebooks.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/query-notebooks/query-notebooks.module.js b/modules/web-console/src/main/js/app/modules/query-notebooks/query-notebooks.module.js
new file mode 100644
index 0000000..5999948
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/query-notebooks/query-notebooks.module.js
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+import angular from 'angular';
+
+angular
+    .module('ignite-console.query-notebooks', [
+
+    ])
+    .provider('QueryNotebooks', function() {
+        const _demoNotebook = {
+            name: 'SQL demo',
+            paragraphs: [
+                {
+                    name: 'Query with refresh rate',
+                    cacheName: 'CarCache',
+                    pageSize: 50,
+                    query: 'SELECT count(*)\nFROM "CarCache".Car',
+                    result: 'bar',
+                    timeLineSpan: '1',
+                    rate: {
+                        value: 3,
+                        unit: 1000,
+                        installed: true
+                    }
+                },
+                {
+                    name: 'Simple query',
+                    cacheName: 'CarCache',
+                    pageSize: 50,
+                    query: 'SELECT * FROM "CarCache".Car',
+                    result: 'table',
+                    timeLineSpan: '1',
+                    rate: {
+                        value: 30,
+                        unit: 1000,
+                        installed: false
+                    }
+                },
+                {
+                    name: 'Query with aggregates',
+                    cacheName: 'CarCache',
+                    pageSize: 50,
+                    query: 'SELECT p.name, count(*) AS cnt\nFROM "ParkingCache".Parking p\nINNER JOIN "CarCache".Car c\n  ON (p.id) = (c.parkingId)\nGROUP BY P.NAME',
+                    result: 'table',
+                    timeLineSpan: '1',
+                    rate: {
+                        value: 30,
+                        unit: 1000,
+                        installed: false
+                    }
+                }
+            ],
+            expandedParagraphs: [0, 1, 2]
+        };
+
+        this.$get = ['$q', '$http', '$rootScope', ($q, $http, $root) => {
+            return {
+                read(noteId) {
+                    if ($root.IgniteDemoMode)
+                        return $q.when(angular.copy(_demoNotebook));
+
+                    return $http.post('/api/v1/notebooks/get', {noteId})
+                        .then(({data}) => data)
+                        .catch(({data}) => $q.reject(data));
+                },
+                save(notebook) {
+                    if ($root.IgniteDemoMode)
+                        return $q.when();
+
+                    return $http.post('/api/v1/notebooks/save', notebook)
+                        .then(({data}) => data)
+                        .catch(({data}) => $q.reject(data));
+                },
+                remove(notebook) {
+                    if ($root.IgniteDemoMode)
+                        return $q.reject(`Removing "${notebook.name}" notebook is not supported.`);
+
+                    return $http.post('/api/v1/notebooks/remove', {_id: notebook._id})
+                        .then(() => {
+                            const idx = _.findIndex($root.notebooks, (item) => {
+                                return item._id === notebook._id;
+                            });
+
+                            if (idx >= 0) {
+                                $root.notebooks.splice(idx, 1);
+
+                                $root.rebuildDropdown();
+
+                                if (idx < $root.notebooks.length)
+                                    return $root.notebooks[idx];
+                            }
+
+                            if ($root.notebooks.length > 0)
+                                return $root.notebooks[$root.notebooks.length - 1];
+                        })
+                        .catch(({data}) => $q.reject(data));
+                }
+            };
+        }];
+    });

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration.state.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration.state.js b/modules/web-console/src/main/js/app/modules/states/configuration.state.js
index 4a0578c..7e5e95e 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration.state.js
+++ b/modules/web-console/src/main/js/app/modules/states/configuration.state.js
@@ -55,6 +55,19 @@ import clustersSwap from './configuration/clusters/swap.directive';
 import clustersTime from './configuration/clusters/time.directive';
 import clustersThread from './configuration/clusters/thread.directive';
 import clustersTransactions from './configuration/clusters/transactions.directive';
+import clustersUserAttributes from './configuration/clusters/attributes.directive';
+import clustersCollision from './configuration/clusters/collision.directive';
+import clustersFailover from './configuration/clusters/failover.directive';
+import clustersLogger from './configuration/clusters/logger.directive';
+
+import clustersCollisionJobStealing from './configuration/clusters/collision/job-stealing.directive';
+import clustersCollisionFifoQueue from './configuration/clusters/collision/fifo-queue.directive';
+import clustersCollisionPriorityQueue from './configuration/clusters/collision/priority-queue.directive';
+import clustersCollisionCustom from './configuration/clusters/collision/custom.directive';
+
+import clustersLoggerLog4j2 from './configuration/clusters/logger/log4j2.directive';
+import clustersLoggerLog4j from './configuration/clusters/logger/log4j.directive';
+import clustersLoggerCustom from './configuration/clusters/logger/custom.directive';
 
 // Domains screen.
 import domainsGeneral from './configuration/domains/general.directive';
@@ -87,6 +100,17 @@ import summaryTabs from './configuration/summary/summary-tabs.directive';
 angular.module('ignite-console.states.configuration', ['ui.router'])
     // Clusters screen.
     .directive(...previewPanel)
+    .directive(...clustersLoggerCustom)
+    .directive(...clustersLoggerLog4j)
+    .directive(...clustersLoggerLog4j2)
+    .directive(...clustersLogger)
+    .directive(...clustersFailover)
+    .directive(...clustersCollisionCustom)
+    .directive(...clustersCollisionPriorityQueue)
+    .directive(...clustersCollisionFifoQueue)
+    .directive(...clustersCollisionJobStealing)
+    .directive(...clustersCollision)
+    .directive(...clustersUserAttributes)
     .directive(...clustersTransactions)
     .directive(...clustersThread)
     .directive(...clustersTime)
@@ -154,7 +178,7 @@ angular.module('ignite-console.states.configuration', ['ui.router'])
                 url: '/clusters',
                 templateUrl: '/configuration/clusters.html',
                 params: {
-                    id: null
+                    linkId: null
                 },
                 metaTags: {
                     title: 'Configure Clusters'
@@ -164,7 +188,7 @@ angular.module('ignite-console.states.configuration', ['ui.router'])
                 url: '/caches',
                 templateUrl: '/configuration/caches.html',
                 params: {
-                    id: null
+                    linkId: null
                 },
                 metaTags: {
                     title: 'Configure Caches'
@@ -174,7 +198,7 @@ angular.module('ignite-console.states.configuration', ['ui.router'])
                 url: '/domains',
                 templateUrl: '/configuration/domains.html',
                 params: {
-                    id: null
+                    linkId: null
                 },
                 metaTags: {
                     title: 'Configure Domain Model'
@@ -184,7 +208,7 @@ angular.module('ignite-console.states.configuration', ['ui.router'])
                 url: '/igfs',
                 templateUrl: '/configuration/igfs.html',
                 params: {
-                    id: null
+                    linkId: null
                 },
                 metaTags: {
                     title: 'Configure IGFS'

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/caches/general.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/caches/general.jade b/modules/web-console/src/main/js/app/modules/states/configuration/caches/general.jade
index 2285825..b5e0797 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/caches/general.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/caches/general.jade
@@ -31,7 +31,7 @@ form.panel.panel-default(name='general' novalidate)
                 .settings-row
                     +clusters(model, 'Associate clusters with the current cache')
                 .settings-row
-                    +dropdown-multiple('<span>Domain models:</span><a ui-sref="base.configuration.domains({id: ' + model + '._id})"> (add)</a>',
+                    +dropdown-multiple('<span>Domain models:</span><a ui-sref="base.configuration.domains({linkId: linkId()})"> (add)</a>',
                         model + '.domains', 'domains', 'true', 'Choose domain models', 'No domain models configured', 'domains',
                         'Select domain models to describe types in cache')
                 .settings-row


[20/50] [abbrv] ignite git commit: IGNITE-3353: IGFS: Fixed "out-of-space" handling.

Posted by sb...@apache.org.
IGNITE-3353: IGFS: Fixed "out-of-space" handling.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/212dc068
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/212dc068
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/212dc068

Branch: refs/heads/ignite-1232
Commit: 212dc068f807a055ae3755a9eebf55fe7722c574
Parents: 8e6473a
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Wed Jun 22 16:40:49 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Wed Jun 22 16:54:47 2016 +0300

----------------------------------------------------------------------
 .../internal/processors/cache/GridCacheAdapter.java | 16 +++-------------
 .../internal/processors/igfs/IgfsDataManager.java   | 14 ++------------
 .../processors/igfs/IgfsOutputStreamImpl.java       | 10 ++++++++--
 .../processors/igfs/IgfsDataManagerSelfTest.java    |  6 +++---
 4 files changed, 16 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/212dc068/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
index 3dbd0f9..944a6b0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
@@ -340,19 +340,9 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
                         igfsDataSpaceMax = igfsCfg.getMaxSpaceSize();
 
-                        if (igfsDataSpaceMax == 0) {
-                            long maxMem = Runtime.getRuntime().maxMemory();
-
-                            // We leave JVM at least 500M of memory for correct operation.
-                            long jvmFreeSize = (maxMem - 512 * 1024 * 1024);
-
-                            if (jvmFreeSize <= 0)
-                                jvmFreeSize = maxMem / 2;
-
-                            long dfltMaxSize = (long)(0.8f * maxMem);
-
-                            igfsDataSpaceMax = Math.min(dfltMaxSize, jvmFreeSize);
-                        }
+                        // Do we have limits?
+                        if (igfsDataSpaceMax <= 0)
+                            igfsDataSpaceMax = Long.MAX_VALUE;
                     }
 
                     break;

http://git-wip-us.apache.org/repos/asf/ignite/blob/212dc068/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsDataManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsDataManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsDataManager.java
index ca8a3af..1397e4e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsDataManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsDataManager.java
@@ -465,23 +465,13 @@ public class IgfsDataManager extends IgfsManager {
      * Notifies data manager that no further writes will be performed on stream.
      *
      * @param fileId File ID.
-     * @param await Await completion.
      * @throws IgniteCheckedException If failed.
      */
-    public void writeClose(IgniteUuid fileId, boolean await) throws IgniteCheckedException {
+    public void writeClose(IgniteUuid fileId) throws IgniteCheckedException {
         WriteCompletionFuture fut = pendingWrites.get(fileId);
 
-        if (fut != null) {
+        if (fut != null)
             fut.markWaitingLastAck();
-
-            if (await)
-                fut.get();
-        }
-        else {
-            if (log.isDebugEnabled())
-                log.debug("Failed to find write completion future for file in pending write map (most likely it was " +
-                    "failed): " + fileId);
-        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/212dc068/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsOutputStreamImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsOutputStreamImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsOutputStreamImpl.java
index 7741a25..f6b1104 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsOutputStreamImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsOutputStreamImpl.java
@@ -23,6 +23,7 @@ import org.apache.ignite.igfs.IgfsException;
 import org.apache.ignite.igfs.IgfsMode;
 import org.apache.ignite.igfs.IgfsOutputStream;
 import org.apache.ignite.igfs.IgfsPath;
+import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.managers.eventstorage.GridEventStorageManager;
 import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.S;
@@ -64,6 +65,9 @@ class IgfsOutputStreamImpl extends IgfsOutputStream {
     /** Mutex for synchronization. */
     private final Object mux = new Object();
 
+    /** Write completion future. */
+    private final IgniteInternalFuture<Boolean> writeFut;
+
     /** Flag for this stream open/closed state. */
     private boolean closed;
 
@@ -120,7 +124,7 @@ class IgfsOutputStreamImpl extends IgfsOutputStream {
 
             streamRange = initialStreamRange(fileInfo);
 
-            igfsCtx.data().writeStart(fileInfo.id());
+            writeFut = igfsCtx.data().writeStart(fileInfo.id());
         }
 
         igfsCtx.igfs().localMetrics().incrementFilesOpenedForWrite();
@@ -300,7 +304,9 @@ class IgfsOutputStreamImpl extends IgfsOutputStream {
 
                 flushRemainder();
 
-                igfsCtx.data().writeClose(fileInfo.id(), true);
+                igfsCtx.data().writeClose(fileInfo.id());
+
+                writeFut.get();
 
                 flushSuccess = true;
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/212dc068/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDataManagerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDataManagerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDataManagerSelfTest.java
index 0d1a66f..70d6b99 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDataManagerSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsDataManagerSelfTest.java
@@ -195,7 +195,7 @@ public class IgfsDataManagerSelfTest extends IgfsCommonAbstractTest {
 
             assert remainder == null;
 
-            mgr.writeClose(info.id(), false);
+            mgr.writeClose(info.id());
 
             fut.get(3000);
 
@@ -287,7 +287,7 @@ public class IgfsDataManagerSelfTest extends IgfsCommonAbstractTest {
 
             assert left2 == null;
 
-            mgr.writeClose(info.id(), false);
+            mgr.writeClose(info.id());
 
             fut.get(3000);
 
@@ -369,7 +369,7 @@ public class IgfsDataManagerSelfTest extends IgfsCommonAbstractTest {
                 assert left == null : "No remainder should be returned if flush is true: " + Arrays.toString(left);
             }
 
-            mgr.writeClose(info.id(), false);
+            mgr.writeClose(info.id());
 
             assertTrue(range.regionEqual(new IgfsFileAffinityRange(0, writesCnt * chunkSize - 1, null)));
 


[03/50] [abbrv] ignite git commit: IGNITE-3277 Replaced outdated json-lib 2.4 to modern Jackson 2.7.5.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheConfiguration.java
index 5d27a8a..869a12c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheConfiguration.java
@@ -27,6 +27,7 @@ import org.apache.ignite.cache.CacheWriteSynchronizationMode;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
 import org.apache.ignite.lang.IgniteProductVersion;
@@ -36,7 +37,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.compactClass;
 /**
  * Data transfer object for cache configuration properties.
  */
-public class VisorCacheConfiguration implements Serializable {
+public class VisorCacheConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheDefaultConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheDefaultConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheDefaultConfiguration.java
index efebfe5..03b5020 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheDefaultConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheDefaultConfiguration.java
@@ -19,12 +19,13 @@ package org.apache.ignite.internal.visor.cache;
 
 import java.io.Serializable;
 import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for default cache configuration properties.
  */
-public class VisorCacheDefaultConfiguration implements Serializable {
+public class VisorCacheDefaultConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -54,4 +55,4 @@ public class VisorCacheDefaultConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorCacheDefaultConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheEvictionConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheEvictionConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheEvictionConfiguration.java
index db216e0..05d5c38 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheEvictionConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheEvictionConfiguration.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.visor.cache;
 import java.io.Serializable;
 import org.apache.ignite.cache.eviction.EvictionPolicy;
 import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
 
@@ -29,7 +30,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.evictionPolic
 /**
  * Data transfer object for eviction configuration properties.
  */
-public class VisorCacheEvictionConfiguration implements Serializable {
+public class VisorCacheEvictionConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -138,4 +139,4 @@ public class VisorCacheEvictionConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorCacheEvictionConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheMetrics.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheMetrics.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheMetrics.java
index c658871..1204cbc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheMetrics.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheMetrics.java
@@ -22,13 +22,14 @@ import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.CacheMetrics;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.processors.cache.GridCacheProcessor;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for {@link CacheMetrics}.
  */
-public class VisorCacheMetrics implements Serializable {
+public class VisorCacheMetrics implements Serializable, LessNamingBean {
     /** */
     private static final float MICROSECONDS_IN_SECOND = 1_000_000;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheNearConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheNearConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheNearConfiguration.java
index 23195e6..8771da4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheNearConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheNearConfiguration.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.visor.cache;
 import java.io.Serializable;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.processors.cache.GridCacheUtils;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
@@ -30,7 +31,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.evictionPolic
 /**
  * Data transfer object for near cache configuration properties.
  */
-public class VisorCacheNearConfiguration implements Serializable {
+public class VisorCacheNearConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -98,4 +99,4 @@ public class VisorCacheNearConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorCacheNearConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCachePartition.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCachePartition.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCachePartition.java
index 5909c1a..a6c0839 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCachePartition.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCachePartition.java
@@ -18,12 +18,13 @@
 package org.apache.ignite.internal.visor.cache;
 
 import java.io.Serializable;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for information about keys in cache partition.
  */
-public class VisorCachePartition implements Serializable {
+public class VisorCachePartition implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCachePartitions.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCachePartitions.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCachePartitions.java
index 4634fa6..af48825 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCachePartitions.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCachePartitions.java
@@ -20,12 +20,13 @@ package org.apache.ignite.internal.visor.cache;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for information about cache partitions.
  */
-public class VisorCachePartitions implements Serializable {
+public class VisorCachePartitions implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheQueryConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheQueryConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheQueryConfiguration.java
index 73088bc..e0d1e72 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheQueryConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheQueryConfiguration.java
@@ -19,12 +19,13 @@ package org.apache.ignite.internal.visor.cache;
 
 import java.io.Serializable;
 import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.U;
 
 /**
  * Data transfer object for cache query configuration data.
  */
-public class VisorCacheQueryConfiguration implements Serializable {
+public class VisorCacheQueryConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheQueryMetrics.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheQueryMetrics.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheQueryMetrics.java
index ffbe585..a3d77e5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheQueryMetrics.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheQueryMetrics.java
@@ -19,12 +19,13 @@ package org.apache.ignite.internal.visor.cache;
 
 import java.io.Serializable;
 import org.apache.ignite.cache.query.QueryMetrics;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for cache query metrics.
  */
-public class VisorCacheQueryMetrics implements Serializable {
+public class VisorCacheQueryMetrics implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -98,4 +99,4 @@ public class VisorCacheQueryMetrics implements Serializable {
     @Override public String toString() {
         return S.toString(VisorCacheQueryMetrics.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheRebalanceConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheRebalanceConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheRebalanceConfiguration.java
index d2dd32e..4c28d00 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheRebalanceConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheRebalanceConfiguration.java
@@ -20,12 +20,13 @@ package org.apache.ignite.internal.visor.cache;
 import java.io.Serializable;
 import org.apache.ignite.cache.CacheRebalanceMode;
 import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for cache rebalance configuration properties.
  */
-public class VisorCacheRebalanceConfiguration implements Serializable {
+public class VisorCacheRebalanceConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -110,4 +111,4 @@ public class VisorCacheRebalanceConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorCacheRebalanceConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStoreConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStoreConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStoreConfiguration.java
index 2ba1b57..5d3e1e1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStoreConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStoreConfiguration.java
@@ -22,6 +22,7 @@ import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.cache.store.jdbc.CacheAbstractJdbcStore;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.processors.cache.IgniteCacheProxy;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
@@ -31,7 +32,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.compactClass;
 /**
  * Data transfer object for cache store configuration properties.
  */
-public class VisorCacheStoreConfiguration implements Serializable {
+public class VisorCacheStoreConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeFieldMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeFieldMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeFieldMetadata.java
index 323e536..f3dffd6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeFieldMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeFieldMetadata.java
@@ -19,12 +19,13 @@ package org.apache.ignite.internal.visor.cache;
 
 import java.io.Serializable;
 import org.apache.ignite.cache.CacheTypeFieldMetadata;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.U;
 
 /**
  * Data transfer object for {@link CacheTypeFieldMetadata}.
  */
-public class VisorCacheTypeFieldMetadata implements Serializable {
+public class VisorCacheTypeFieldMetadata implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeMetadata.java
index ec7a114..4e38d81 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeMetadata.java
@@ -30,6 +30,7 @@ import org.apache.ignite.cache.QueryIndex;
 import org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory;
 import org.apache.ignite.cache.store.jdbc.JdbcType;
 import org.apache.ignite.cache.store.jdbc.JdbcTypeField;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiTuple;
@@ -39,7 +40,7 @@ import javax.cache.configuration.Factory;
 /**
  * Data transfer object for {@link CacheTypeMetadata}.
  */
-public class VisorCacheTypeMetadata implements Serializable {
+public class VisorCacheTypeMetadata implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheV4.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheV4.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheV4.java
new file mode 100644
index 0000000..81dbacb
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheV4.java
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal.visor.cache;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
+import org.apache.ignite.internal.processors.cache.GridCacheSwapManager;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Data transfer object for {@link IgniteCache}.
+ */
+public class VisorCacheV4 extends VisorCacheV2 {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Number of primary entries in offheap. */
+    private int offHeapPrimaryEntriesCnt;
+
+    /** Number of backup entries in offheap. */
+    private int offHeapBackupEntriesCnt;
+
+    /** Number of primary entries in swap. */
+    private int swapPrimaryEntriesCnt;
+
+    /** Number of backup entries in swap. */
+    private int swapBackupEntriesCnt;
+
+    /** {@inheritDoc} */
+    @Override public VisorCache from(IgniteEx ignite, String cacheName, int sample) throws IgniteCheckedException {
+        VisorCache c = super.from(ignite, cacheName, sample);
+
+        if (c != null && c instanceof VisorCacheV4) {
+            VisorCacheV4 cacheV4 = (VisorCacheV4)c;
+
+            GridCacheAdapter ca = ignite.context().cache().internalCache(cacheName);
+
+            // Process only started caches.
+            if (ca != null && ca.context().started()) {
+                GridCacheSwapManager swap = ca.context().swap();
+
+                cacheV4.offHeapPrimaryEntriesCnt = swap.offheapEntriesCount(true, false, AffinityTopologyVersion.NONE);
+                cacheV4.offHeapBackupEntriesCnt = swap.offheapEntriesCount(false, true, AffinityTopologyVersion.NONE);
+
+                cacheV4.swapPrimaryEntriesCnt = swap.swapEntriesCount(true, false, AffinityTopologyVersion.NONE);
+                cacheV4.swapBackupEntriesCnt = swap.swapEntriesCount(false, true, AffinityTopologyVersion.NONE);
+            }
+        }
+
+        return c;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected VisorCache initHistory(VisorCache c) {
+        super.initHistory(c);
+
+        if (c instanceof VisorCacheV4) {
+            VisorCacheV4 cacheV4 = (VisorCacheV4)c;
+
+            cacheV4.offHeapPrimaryEntriesCnt = offHeapPrimaryEntriesCnt;
+            cacheV4.offHeapBackupEntriesCnt = offHeapBackupEntriesCnt;
+            cacheV4.swapPrimaryEntriesCnt = swapPrimaryEntriesCnt;
+            cacheV4.swapBackupEntriesCnt = swapBackupEntriesCnt;
+        }
+
+        return c;
+    }
+
+    /** {@inheritDoc} */
+    @Override public VisorCache history() {
+        return initHistory(new VisorCacheV3());
+    }
+
+    /**
+     * @return Off-heap heap primary entries count.
+     */
+    public int offHeapPrimaryEntriesCount() {
+        return offHeapPrimaryEntriesCnt;
+    }
+
+    /**
+     * @return Off-heap heap backup entries count.
+     */
+    public int offHeapBackupEntriesCount() {
+        return offHeapBackupEntriesCnt;
+    }
+
+    /**
+     * @return Swap primary entries count.
+     */
+    public int swapPrimaryEntriesCount() {
+        return swapPrimaryEntriesCnt;
+    }
+
+    /**
+     * @return Swap backup entries count.
+     */
+    public int swapBackupEntriesCount() {
+        return swapBackupEntriesCnt;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(VisorCacheV4.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/debug/VisorThreadInfo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/debug/VisorThreadInfo.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/debug/VisorThreadInfo.java
index 3671bcd..d656ad1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/debug/VisorThreadInfo.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/debug/VisorThreadInfo.java
@@ -19,11 +19,12 @@ package org.apache.ignite.internal.visor.debug;
 
 import java.io.Serializable;
 import java.lang.management.ThreadInfo;
+import org.apache.ignite.internal.LessNamingBean;
 
 /**
  * Data transfer object for Visor {@link ThreadInfo}.
  */
-public class VisorThreadInfo implements Serializable {
+public class VisorThreadInfo implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -326,4 +327,4 @@ public class VisorThreadInfo implements Serializable {
 
         return sb.toString();
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/debug/VisorThreadLockInfo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/debug/VisorThreadLockInfo.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/debug/VisorThreadLockInfo.java
index 13c81cc..0fdd95f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/debug/VisorThreadLockInfo.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/debug/VisorThreadLockInfo.java
@@ -19,11 +19,12 @@ package org.apache.ignite.internal.visor.debug;
 
 import java.io.Serializable;
 import java.lang.management.LockInfo;
+import org.apache.ignite.internal.LessNamingBean;
 
 /**
  * Data transfer object for {@link LockInfo}.
  */
-public class VisorThreadLockInfo implements Serializable {
+public class VisorThreadLockInfo implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -70,4 +71,4 @@ public class VisorThreadLockInfo implements Serializable {
     @Override public String toString() {
         return clsName + '@' + Integer.toHexString(identityHashCode);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/event/VisorGridEvent.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/event/VisorGridEvent.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/event/VisorGridEvent.java
index 8a26bddc..b24e860 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/event/VisorGridEvent.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/event/VisorGridEvent.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.visor.event;
 
 import java.io.Serializable;
 import java.util.UUID;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.lang.IgniteUuid;
 import org.jetbrains.annotations.Nullable;
@@ -26,7 +27,7 @@ import org.jetbrains.annotations.Nullable;
 /**
  * Base class for lightweight counterpart for various {@link org.apache.ignite.events.Event}.
  */
-public class VisorGridEvent implements Serializable {
+public class VisorGridEvent implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -126,4 +127,4 @@ public class VisorGridEvent implements Serializable {
     @Override public String toString() {
         return S.toString(VisorGridEvent.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/file/VisorFileBlock.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/file/VisorFileBlock.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/file/VisorFileBlock.java
index f82c703..dba7037 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/file/VisorFileBlock.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/file/VisorFileBlock.java
@@ -18,12 +18,13 @@
 package org.apache.ignite.internal.visor.file;
 
 import java.io.Serializable;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Represents block of bytes from a file, could be optionally zipped.
  */
-public class VisorFileBlock implements Serializable {
+public class VisorFileBlock implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -110,4 +111,4 @@ public class VisorFileBlock implements Serializable {
     @Override public String toString() {
         return S.toString(VisorFileBlock.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfs.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfs.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfs.java
index 847975a..29c79fe 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfs.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfs.java
@@ -20,12 +20,13 @@ package org.apache.ignite.internal.visor.igfs;
 import java.io.Serializable;
 import org.apache.ignite.IgniteFileSystem;
 import org.apache.ignite.igfs.IgfsMode;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for {@link org.apache.ignite.IgniteFileSystem}.
  */
-public class VisorIgfs implements Serializable {
+public class VisorIgfs implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -108,4 +109,4 @@ public class VisorIgfs implements Serializable {
     @Override public String toString() {
         return S.toString(VisorIgfs.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsEndpoint.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsEndpoint.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsEndpoint.java
index b6d7f43..c2178cb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsEndpoint.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsEndpoint.java
@@ -18,13 +18,14 @@
 package org.apache.ignite.internal.visor.igfs;
 
 import java.io.Serializable;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
 
 /**
  * IGFS endpoint descriptor.
  */
-public class VisorIgfsEndpoint implements Serializable {
+public class VisorIgfsEndpoint implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -103,4 +104,4 @@ public class VisorIgfsEndpoint implements Serializable {
     @Override public String toString() {
         return S.toString(VisorIgfsEndpoint.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsMetrics.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsMetrics.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsMetrics.java
index 47738eb..af7af06 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsMetrics.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsMetrics.java
@@ -19,12 +19,13 @@ package org.apache.ignite.internal.visor.igfs;
 
 import java.io.Serializable;
 import org.apache.ignite.igfs.IgfsMetrics;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for {@link IgfsMetrics}.
  */
-public class VisorIgfsMetrics implements Serializable {
+public class VisorIgfsMetrics implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -248,4 +249,4 @@ public class VisorIgfsMetrics implements Serializable {
     @Override public String toString() {
         return S.toString(VisorIgfsMetrics.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsProfilerEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsProfilerEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsProfilerEntry.java
index 2ceea60..b157296 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsProfilerEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsProfilerEntry.java
@@ -20,12 +20,13 @@ package org.apache.ignite.internal.visor.igfs;
 import java.io.Serializable;
 import java.util.Comparator;
 import org.apache.ignite.igfs.IgfsMode;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Visor IGFS profiler information about one file.
  */
-public class VisorIgfsProfilerEntry implements Serializable {
+public class VisorIgfsProfilerEntry implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -234,4 +235,4 @@ public class VisorIgfsProfilerEntry implements Serializable {
     @Override public String toString() {
         return S.toString(VisorIgfsProfilerEntry.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsProfilerUniformityCounters.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsProfilerUniformityCounters.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsProfilerUniformityCounters.java
index 55244c2..9184ce3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsProfilerUniformityCounters.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/igfs/VisorIgfsProfilerUniformityCounters.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.visor.igfs;
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.F;
 
 import static org.apache.ignite.internal.visor.igfs.VisorIgfsProfiler.UNIFORMITY_BLOCKS;
@@ -31,7 +32,7 @@ import static org.apache.ignite.internal.visor.igfs.VisorIgfsProfiler.UNIFORMITY
  * </p>
  * Count read frequency for each file and compare with ideal uniform distribution.
  */
-public class VisorIgfsProfilerUniformityCounters implements Serializable {
+public class VisorIgfsProfilerUniformityCounters implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -198,4 +199,4 @@ public class VisorIgfsProfilerUniformityCounters implements Serializable {
             return 1.0 - sigma;
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/log/VisorLogSearchResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/log/VisorLogSearchResult.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/log/VisorLogSearchResult.java
index a492516..35ace13 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/log/VisorLogSearchResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/log/VisorLogSearchResult.java
@@ -19,13 +19,14 @@ package org.apache.ignite.internal.visor.log;
 
 import java.io.Serializable;
 import java.util.UUID;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Result for log search operation.
  * Contains found line and several lines before and after, plus other info.
  */
-public class VisorLogSearchResult implements Serializable {
+public class VisorLogSearchResult implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -152,4 +153,4 @@ public class VisorLogSearchResult implements Serializable {
     @Override public String toString() {
         return S.toString(VisorLogSearchResult.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorAtomicConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorAtomicConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorAtomicConfiguration.java
index 6966dbb..a6d8c4c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorAtomicConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorAtomicConfiguration.java
@@ -20,12 +20,13 @@ package org.apache.ignite.internal.visor.node;
 import java.io.Serializable;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.configuration.AtomicConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for configuration of atomic data structures.
  */
-public class VisorAtomicConfiguration implements Serializable {
+public class VisorAtomicConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -79,4 +80,4 @@ public class VisorAtomicConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorAtomicConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorBasicConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorBasicConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorBasicConfiguration.java
index 84095b6..9d46064 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorBasicConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorBasicConfiguration.java
@@ -21,6 +21,7 @@ import java.io.Serializable;
 import java.util.UUID;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
 
@@ -42,7 +43,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.compactObject
 /**
  * Data transfer object for node basic configuration properties.
  */
-public class VisorBasicConfiguration implements Serializable {
+public class VisorBasicConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -293,4 +294,4 @@ public class VisorBasicConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorBasicConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorExecutorServiceConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorExecutorServiceConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorExecutorServiceConfiguration.java
index 14a8dcc..df083f5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorExecutorServiceConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorExecutorServiceConfiguration.java
@@ -20,12 +20,13 @@ package org.apache.ignite.internal.visor.node;
 import java.io.Serializable;
 import org.apache.ignite.configuration.ConnectorConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for node executors configuration properties.
  */
-public class VisorExecutorServiceConfiguration implements Serializable {
+public class VisorExecutorServiceConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -114,4 +115,4 @@ public class VisorExecutorServiceConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorExecutorServiceConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorGridConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorGridConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorGridConfiguration.java
index d6c7fab..913c450 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorGridConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorGridConfiguration.java
@@ -24,6 +24,7 @@ import java.util.Properties;
 import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 import static org.apache.ignite.internal.visor.util.VisorTaskUtils.compactArray;
@@ -31,7 +32,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.compactArray;
 /**
  * Data transfer object for node configuration data.
  */
-public class VisorGridConfiguration implements Serializable {
+public class VisorGridConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -228,4 +229,4 @@ public class VisorGridConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorGridConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorIgfsConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorIgfsConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorIgfsConfiguration.java
index 50917eb..9f7652b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorIgfsConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorIgfsConfiguration.java
@@ -26,6 +26,7 @@ import org.apache.ignite.configuration.FileSystemConfiguration;
 import org.apache.ignite.igfs.IgfsIpcEndpointConfiguration;
 import org.apache.ignite.igfs.IgfsMode;
 import org.apache.ignite.igfs.secondary.IgfsSecondaryFileSystem;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
 
@@ -34,7 +35,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.compactClass;
 /**
  * Data transfer object for IGFS configuration properties.
  */
-public class VisorIgfsConfiguration implements Serializable {
+public class VisorIgfsConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorLifecycleConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorLifecycleConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorLifecycleConfiguration.java
index 396c7f0..838a6cc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorLifecycleConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorLifecycleConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.visor.node;
 
 import java.io.Serializable;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
 
@@ -27,7 +28,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.compactArray;
 /**
  * Data transfer object for node lifecycle configuration properties.
  */
-public class VisorLifecycleConfiguration implements Serializable {
+public class VisorLifecycleConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -57,4 +58,4 @@ public class VisorLifecycleConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorLifecycleConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorMetricsConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorMetricsConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorMetricsConfiguration.java
index c5ff882..4e812b7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorMetricsConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorMetricsConfiguration.java
@@ -19,12 +19,13 @@ package org.apache.ignite.internal.visor.node;
 
 import java.io.Serializable;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for node metrics configuration properties.
  */
-public class VisorMetricsConfiguration implements Serializable {
+public class VisorMetricsConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -76,4 +77,4 @@ public class VisorMetricsConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorMetricsConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorJob.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorJob.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorJob.java
index 79760ef..9a9b1cd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorJob.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorJob.java
@@ -31,6 +31,7 @@ import org.apache.ignite.internal.visor.VisorJob;
 import org.apache.ignite.internal.visor.cache.VisorCache;
 import org.apache.ignite.internal.visor.cache.VisorCacheV2;
 import org.apache.ignite.internal.visor.cache.VisorCacheV3;
+import org.apache.ignite.internal.visor.cache.VisorCacheV4;
 import org.apache.ignite.internal.visor.compute.VisorComputeMonitoringHolder;
 import org.apache.ignite.internal.visor.igfs.VisorIgfs;
 import org.apache.ignite.internal.visor.igfs.VisorIgfsEndpoint;
@@ -57,6 +58,9 @@ public class VisorNodeDataCollectorJob extends VisorJob<VisorNodeDataCollectorTa
     /** */
     private static final IgniteProductVersion VER_1_5_9 = IgniteProductVersion.fromString("1.5.9");
 
+    /** */
+    private static final IgniteProductVersion VER_1_5_26 = IgniteProductVersion.fromString("1.5.26");
+
     /**
      * Create job with given argument.
      *
@@ -125,7 +129,7 @@ public class VisorNodeDataCollectorJob extends VisorJob<VisorNodeDataCollectorTa
 
     /**
      * @param ver Version to check.
-     * @return {@code true} if compatible.
+     * @return {@code true} if found at least one compatible node with specified version.
      */
     private boolean compatibleWith(IgniteProductVersion ver) {
         for (ClusterNode node : ignite.cluster().nodes())
@@ -136,6 +140,22 @@ public class VisorNodeDataCollectorJob extends VisorJob<VisorNodeDataCollectorTa
     }
 
     /**
+     * @return Compatible {@link VisorCache} instance.
+     */
+    private VisorCache createVisorCache() {
+        if (compatibleWith(VER_1_4_1))
+            return new VisorCache();
+
+        if (compatibleWith(VER_1_5_9))
+            return new VisorCacheV2();
+
+        if (compatibleWith(VER_1_5_26))
+            return new VisorCacheV3();
+
+        return new VisorCacheV4();
+    }
+
+    /**
      * Collect caches.
      *
      * @param res Job result.
@@ -152,9 +172,7 @@ public class VisorNodeDataCollectorJob extends VisorJob<VisorNodeDataCollectorTa
                     long start0 = U.currentTimeMillis();
 
                     try {
-                        VisorCache cache = (compatibleWith(VER_1_4_1) ? new VisorCache() :
-                                compatibleWith(VER_1_5_9) ? new VisorCacheV2() : new VisorCacheV3())
-                                    .from(ignite, cacheName, arg.sample());
+                        VisorCache cache = createVisorCache().from(ignite, cacheName, arg.sample());
 
                         if (cache != null)
                             res.caches().add(cache);

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorTaskResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorTaskResult.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorTaskResult.java
index 9ca1232..baab350 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorTaskResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorTaskResult.java
@@ -24,6 +24,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.visor.cache.VisorCache;
 import org.apache.ignite.internal.visor.event.VisorGridEvent;
 import org.apache.ignite.internal.visor.igfs.VisorIgfs;
@@ -33,7 +34,7 @@ import org.apache.ignite.internal.visor.util.VisorExceptionWrapper;
 /**
  * Data collector task result.
  */
-public class VisorNodeDataCollectorTaskResult implements Serializable {
+public class VisorNodeDataCollectorTaskResult implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -174,4 +175,4 @@ public class VisorNodeDataCollectorTaskResult implements Serializable {
     public Map<UUID, Long> errorCounts() {
         return errCnts;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorPeerToPeerConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorPeerToPeerConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorPeerToPeerConfiguration.java
index 622aa6d..93177fd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorPeerToPeerConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorPeerToPeerConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.visor.node;
 
 import java.io.Serializable;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
 
@@ -27,7 +28,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.compactArray;
 /**
  * Data transfer object for node P2P configuration properties.
  */
-public class VisorPeerToPeerConfiguration implements Serializable {
+public class VisorPeerToPeerConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -79,4 +80,4 @@ public class VisorPeerToPeerConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorPeerToPeerConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorRestConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorRestConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorRestConfiguration.java
index c5ab55a..78a54b3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorRestConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorRestConfiguration.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.visor.node;
 import java.io.Serializable;
 import org.apache.ignite.configuration.ConnectorConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
 
@@ -32,7 +33,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.intValue;
 /**
  * Create data transfer object for node REST configuration properties.
  */
-public class VisorRestConfiguration implements Serializable {
+public class VisorRestConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -156,4 +157,4 @@ public class VisorRestConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorRestConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorSegmentationConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorSegmentationConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorSegmentationConfiguration.java
index 84365dc..44909fc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorSegmentationConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorSegmentationConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.visor.node;
 
 import java.io.Serializable;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.plugin.segmentation.SegmentationPolicy;
 import org.jetbrains.annotations.Nullable;
@@ -28,7 +29,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.compactArray;
 /**
  * Data transfer object for node segmentation configuration properties.
  */
-public class VisorSegmentationConfiguration implements Serializable {
+public class VisorSegmentationConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -102,4 +103,4 @@ public class VisorSegmentationConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorSegmentationConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorSpisConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorSpisConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorSpisConfiguration.java
index c576426..bd59690 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorSpisConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorSpisConfiguration.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Map;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.lang.IgniteBiTuple;
@@ -35,7 +36,7 @@ import static org.apache.ignite.internal.visor.util.VisorTaskUtils.compactObject
 /**
  * Data transfer object for node SPIs configuration properties.
  */
-public class VisorSpisConfiguration implements Serializable {
+public class VisorSpisConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -233,4 +234,4 @@ public class VisorSpisConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorSpisConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorTransactionConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorTransactionConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorTransactionConfiguration.java
index 419350d..6855c43 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorTransactionConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorTransactionConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.visor.node;
 
 import java.io.Serializable;
 import org.apache.ignite.configuration.TransactionConfiguration;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.transactions.TransactionConcurrency;
 import org.apache.ignite.transactions.TransactionIsolation;
@@ -26,7 +27,7 @@ import org.apache.ignite.transactions.TransactionIsolation;
 /**
  * Data transfer object for transaction configuration.
  */
-public class VisorTransactionConfiguration implements Serializable {
+public class VisorTransactionConfiguration implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -113,4 +114,4 @@ public class VisorTransactionConfiguration implements Serializable {
     @Override public String toString() {
         return S.toString(VisorTransactionConfiguration.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryField.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryField.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryField.java
index 3191e56..18b0d71 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryField.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryField.java
@@ -18,13 +18,14 @@
 package org.apache.ignite.internal.visor.query;
 
 import java.io.Serializable;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Data transfer object for query field type description.
  */
-public class VisorQueryField implements Serializable {
+public class VisorQueryField implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -102,4 +103,4 @@ public class VisorQueryField implements Serializable {
     @Override public String toString() {
         return S.toString(VisorQueryField.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResult.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResult.java
index b086f7c..21d1ed7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryResult.java
@@ -19,12 +19,13 @@ package org.apache.ignite.internal.visor.query;
 
 import java.io.Serializable;
 import java.util.List;
+import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * Result for cache query tasks.
  */
-public class VisorQueryResult implements Serializable {
+public class VisorQueryResult implements Serializable, LessNamingBean {
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -75,4 +76,4 @@ public class VisorQueryResult implements Serializable {
     @Override public String toString() {
         return S.toString(VisorQueryResult.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSet.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSet.java b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSet.java
index eecc169..9961501 100644
--- a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSet.java
+++ b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermissionSet.java
@@ -20,6 +20,7 @@ package org.apache.ignite.plugin.security;
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.Map;
+import org.apache.ignite.internal.LessNamingBean;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -31,7 +32,7 @@ import org.jetbrains.annotations.Nullable;
  * Property {@link #defaultAllowAll()} specifies whether to allow or deny
  * cache and task operations if they were not explicitly specified.
  */
-public interface SecurityPermissionSet extends Serializable {
+public interface SecurityPermissionSet extends Serializable, LessNamingBean {
     /**
      * Flag indicating whether to allow or deny cache and task operations
      * if they were not explicitly specified.
@@ -63,4 +64,4 @@ public interface SecurityPermissionSet extends Serializable {
      * @return Collection of system-wide permissions.
      */
     @Nullable public Collection<SecurityPermission> systemPermissions();
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/core/src/main/java/org/apache/ignite/plugin/security/SecuritySubject.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecuritySubject.java b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecuritySubject.java
index 1cf403a..b4005ea 100644
--- a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecuritySubject.java
+++ b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecuritySubject.java
@@ -20,11 +20,12 @@ package org.apache.ignite.plugin.security;
 import java.io.Serializable;
 import java.net.InetSocketAddress;
 import java.util.UUID;
+import org.apache.ignite.internal.LessNamingBean;
 
 /**
  * Security subject representing authenticated node with a set of permissions.
  */
-public interface SecuritySubject extends Serializable {
+public interface SecuritySubject extends Serializable, LessNamingBean {
     /**
      * Gets subject ID.
      *
@@ -59,4 +60,4 @@ public interface SecuritySubject extends Serializable {
      * @return Authorized permission set for the subject.
      */
     public SecurityPermissionSet permissions();
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/rest-http/pom.xml
----------------------------------------------------------------------
diff --git a/modules/rest-http/pom.xml b/modules/rest-http/pom.xml
index c97d670..860c64d 100644
--- a/modules/rest-http/pom.xml
+++ b/modules/rest-http/pom.xml
@@ -97,28 +97,21 @@
         </dependency>
 
         <dependency>
-            <groupId>net.sf.json-lib</groupId>
-            <artifactId>json-lib</artifactId>
-            <version>${jsonlib.version}</version>
-            <classifier>jdk15</classifier>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>${jackson2.version}</version>
         </dependency>
 
         <dependency>
-            <groupId>net.sf.ezmorph</groupId>
-            <artifactId>ezmorph</artifactId>
-            <version>${ezmorph.version}</version>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>${jackson2.version}</version>
         </dependency>
 
         <dependency>
-            <groupId>commons-collections</groupId>
-            <artifactId>commons-collections</artifactId>
-            <version>${commons.collections.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-beanutils</groupId>
-            <artifactId>commons-beanutils</artifactId>
-            <version>${commons.beanutils.version}</version>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${jackson2.version}</version>
         </dependency>
 
         <dependency>

http://git-wip-us.apache.org/repos/asf/ignite/blob/f177d431/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java
----------------------------------------------------------------------
diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java
deleted file mode 100644
index c2795a4..0000000
--- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.ignite.internal.processors.rest.protocols.http.jetty;
-
-import java.lang.reflect.Method;
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import net.sf.json.JSONObject;
-import net.sf.json.JsonConfig;
-import net.sf.json.processors.JsonBeanProcessor;
-import net.sf.json.processors.JsonBeanProcessorMatcher;
-import net.sf.json.processors.JsonValueProcessor;
-import net.sf.json.processors.JsonValueProcessorMatcher;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.processors.cache.query.GridCacheSqlIndexMetadata;
-import org.apache.ignite.internal.processors.cache.query.GridCacheSqlMetadata;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.internal.visor.cache.VisorCache;
-import org.apache.ignite.lang.IgniteBiTuple;
-import org.apache.ignite.lang.IgniteUuid;
-
-/**
- * Jetty protocol json configuration.
- */
-class GridJettyJsonConfig extends JsonConfig {
-    /** Logger. */
-    private final IgniteLogger log;
-
-    /**
-     * Class for finding a matching JsonBeanProcessor.
-     */
-    private static final JsonBeanProcessorMatcher LESS_NAMING_BEAN_MATCHER = new JsonBeanProcessorMatcher() {
-        /** {@inheritDoc} */
-        @Override public Object getMatch(Class target, Set keys) {
-            return GridJettyJsonConfig.getMatch(target, keys);
-        }
-    };
-
-    /**
-     * Class for finding a matching JsonValueProcessor.
-     */
-    private static final JsonValueProcessorMatcher LESS_NAMING_VALUE_MATCHER = new JsonValueProcessorMatcher() {
-        /** {@inheritDoc} */
-        @Override public Object getMatch(Class target, Set keys) {
-            return GridJettyJsonConfig.getMatch(target, keys);
-        }
-    };
-
-    /**
-     * Helper class for simple to-string conversion for {@link UUID}.
-     */
-    private static JsonValueProcessor UUID_PROCESSOR = new JsonValueProcessor() {
-        /** {@inheritDoc} */
-        @Override public Object processArrayValue(Object val, JsonConfig jsonCfg) {
-            if (val == null)
-                return new JSONObject(true);
-
-            if (val instanceof UUID)
-                return val.toString();
-
-            throw new UnsupportedOperationException("Serialize value to json is not supported: " + val);
-        }
-
-        /** {@inheritDoc} */
-        @Override public Object processObjectValue(String key, Object val, JsonConfig jsonCfg) {
-            return processArrayValue(val, jsonCfg);
-        }
-    };
-
-    /**
-     * Helper class for simple to-string conversion for {@link UUID}.
-     */
-    private static JsonValueProcessor IGNITE_BI_TUPLE_PROCESSOR = new JsonValueProcessor() {
-        /** {@inheritDoc} */
-        @Override public Object processArrayValue(Object val, JsonConfig jsonCfg) {
-            if (val == null)
-                return new JSONObject(true);
-
-            if (val instanceof IgniteBiTuple) {
-                IgniteBiTuple t2 = (IgniteBiTuple)val;
-
-                final JSONObject ret = new JSONObject();
-
-                ret.element("key", t2.getKey(), jsonCfg);
-                ret.element("value", t2.getValue(), jsonCfg);
-
-                return ret;
-            }
-
-            throw new UnsupportedOperationException("Serialize value to json is not supported: " + val);
-        }
-
-        /** {@inheritDoc} */
-        @Override public Object processObjectValue(String key, Object val, JsonConfig jsonCfg) {
-            return processArrayValue(val, jsonCfg);
-        }
-    };
-
-    /**
-     * Helper class for simple to-string conversion for {@link IgniteUuid}.
-     */
-    private static JsonValueProcessor IGNITE_UUID_PROCESSOR = new JsonValueProcessor() {
-        /** {@inheritDoc} */
-        @Override public Object processArrayValue(Object val, JsonConfig jsonCfg) {
-            if (val == null)
-                return new JSONObject(true);
-
-            if (val instanceof IgniteUuid)
-                return val.toString();
-
-            throw new UnsupportedOperationException("Serialize value to json is not supported: " + val);
-        }
-
-        /** {@inheritDoc} */
-        @Override public Object processObjectValue(String key, Object val, JsonConfig jsonCfg) {
-            return processArrayValue(val, jsonCfg);
-        }
-    };
-
-    /**
-     * Helper class for simple to-string conversion for {@link Date}.
-     */
-    private static JsonValueProcessor DATE_PROCESSOR = new JsonValueProcessor() {
-        /** Thread local US date format. */
-        private final ThreadLocal<DateFormat> dateFmt = new ThreadLocal<DateFormat>() {
-            @Override protected DateFormat initialValue() {
-                return DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US);
-            }
-        };
-
-        /** {@inheritDoc} */
-        @Override public synchronized Object processArrayValue(Object val, JsonConfig jsonCfg) {
-            if (val == null)
-                return new JSONObject(true);
-
-            if (val instanceof Date)
-                return dateFmt.get().format(val);
-
-            throw new UnsupportedOperationException("Serialize value to json is not supported: " + val);
-        }
-
-        /** {@inheritDoc} */
-        @Override public synchronized Object processObjectValue(String key, Object val, JsonConfig jsonCfg) {
-            return processArrayValue(val, jsonCfg);
-        }
-    };
-
-    /**
-     * Constructs default jetty json config.
-     */
-    GridJettyJsonConfig(IgniteLogger log) {
-        this.log = log;
-
-        setAllowNonStringKeys(true);
-
-        registerJsonValueProcessor(IgniteBiTuple.class, IGNITE_BI_TUPLE_PROCESSOR);
-        registerJsonValueProcessor(UUID.class, UUID_PROCESSOR);
-        registerJsonValueProcessor(IgniteUuid.class, IGNITE_UUID_PROCESSOR);
-        registerJsonValueProcessor(Date.class, DATE_PROCESSOR);
-        registerJsonValueProcessor(java.sql.Date.class, DATE_PROCESSOR);
-
-        final LessNamingProcessor lessNamingProcessor = new LessNamingProcessor();
-
-        registerJsonBeanProcessor(LessNamingProcessor.class, lessNamingProcessor);
-        registerJsonValueProcessor(LessNamingProcessor.class, lessNamingProcessor);
-
-        setJsonBeanProcessorMatcher(LESS_NAMING_BEAN_MATCHER);
-        setJsonValueProcessorMatcher(LESS_NAMING_VALUE_MATCHER);
-    }
-
-    /**
-     * Returns the matching class calculated with the target class and the provided set. Matches the target class with
-     * instanceOf, for Visor classes return custom processor class.
-     *
-     * @param target the target class to match
-     * @param keys a set of possible matches
-     */
-    private static Object getMatch(Class target, Set keys) {
-        if (target == null || keys == null)
-            return null;
-
-        if (target.getSimpleName().startsWith("Visor") ||
-            GridCacheSqlMetadata.class.isAssignableFrom(target) ||
-            GridCacheSqlIndexMetadata.class.isAssignableFrom(target))
-            return LessNamingProcessor.class;
-
-        if (keys.contains(target))
-            return target;
-
-        for (Object key : keys) {
-            Class<?> clazz = (Class<?>)key;
-
-            if (clazz.isAssignableFrom(target))
-                return key;
-        }
-
-        return null;
-    }
-
-    /**
-     * Helper class for simple to-json conversion for Visor classes.
-     */
-    private class LessNamingProcessor implements JsonBeanProcessor, JsonValueProcessor {
-        /** Methods to exclude. */
-        private final Collection<String> exclMtds = Arrays.asList("toString", "hashCode", "clone", "getClass");
-
-        /** */
-        private final Map<Class<?>, Collection<Method>> clsCache = new HashMap<>();
-
-        /** */
-        private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
-
-        /** {@inheritDoc} */
-        @Override public JSONObject processBean(Object bean, JsonConfig jsonCfg) {
-            if (bean == null)
-                return new JSONObject(true);
-
-            final JSONObject ret = new JSONObject();
-
-            Collection<Method> methods;
-
-            Class<?> cls = bean.getClass();
-
-            // Get descriptor from cache.
-            rwLock.readLock().lock();
-
-            try {
-                methods = clsCache.get(cls);
-            }
-            finally {
-                rwLock.readLock().unlock();
-            }
-
-            // If missing in cache - build descriptor
-            if (methods == null) {
-                Method[] publicMtds = cls.getMethods();
-
-                methods = new ArrayList<>(publicMtds.length);
-
-                for (Method mtd : publicMtds) {
-                    Class retType = mtd.getReturnType();
-
-                    if (mtd.getParameterTypes().length != 0 ||
-                        retType == void.class ||
-                        retType == cls ||
-                        exclMtds.contains(mtd.getName()) ||
-                        (retType == VisorCache.class && mtd.getName().equals("history")))
-                        continue;
-
-                    mtd.setAccessible(true);
-
-                    methods.add(mtd);
-                }
-
-                /*
-                 * Allow multiple puts for the same class - they will simply override.
-                 */
-                rwLock.writeLock().lock();
-
-                try {
-                    clsCache.put(cls, methods);
-                }
-                finally {
-                    rwLock.writeLock().unlock();
-                }
-            }
-
-            // Extract fields values using descriptor and build JSONObject.
-            for (Method mtd : methods) {
-                try {
-                    ret.element(mtd.getName(), mtd.invoke(bean), jsonCfg);
-                }
-                catch (Exception e) {
-                    U.error(log, "Failed to read object property [type= " + cls.getName()
-                        + ", property=" + mtd.getName() + "]", e);
-                }
-            }
-
-            return ret;
-        }
-
-        /** {@inheritDoc} */
-        @Override public Object processArrayValue(Object val, JsonConfig jsonCfg) {
-            return processBean(val, jsonCfg);
-        }
-
-        /** {@inheritDoc} */
-        @Override public Object processObjectValue(String key, Object val, JsonConfig jsonCfg) {
-            return processArrayValue(val, jsonCfg);
-        }
-    }
-}


[12/50] [abbrv] ignite git commit: IGNITE-3341: Hadoop: Added ability to link user-define native libraries to HadoopClassLoader.

Posted by sb...@apache.org.
IGNITE-3341: Hadoop: Added ability to link user-define native libraries to HadoopClassLoader.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/68b25df3
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/68b25df3
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/68b25df3

Branch: refs/heads/ignite-1232
Commit: 68b25df3b3e1979c0972d75675f2c9aa2b48d9a7
Parents: a527bf8
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Tue Jun 21 16:57:28 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Tue Jun 21 17:11:22 2016 +0300

----------------------------------------------------------------------
 .../configuration/HadoopConfiguration.java      | 35 ++++++++++++++++++++
 .../processors/hadoop/HadoopJobInfo.java        |  3 +-
 .../processors/hadoop/HadoopClassLoader.java    | 26 +++++++++++++--
 .../processors/hadoop/HadoopDefaultJobInfo.java |  8 ++---
 .../hadoop/jobtracker/HadoopJobTracker.java     | 14 ++++++--
 .../child/HadoopChildProcessRunner.java         |  2 +-
 .../processors/hadoop/v2/HadoopV2Job.java       | 14 ++++++--
 .../hadoop/HadoopClassLoaderTest.java           |  2 +-
 .../processors/hadoop/HadoopSnappyTest.java     |  2 +-
 .../processors/hadoop/HadoopTasksV1Test.java    |  2 +-
 .../processors/hadoop/HadoopTasksV2Test.java    |  2 +-
 .../processors/hadoop/HadoopV2JobSelfTest.java  |  2 +-
 .../collections/HadoopAbstractMapTest.java      |  6 ++--
 13 files changed, 96 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/core/src/main/java/org/apache/ignite/configuration/HadoopConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/HadoopConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/HadoopConfiguration.java
index 95ce9d3..5f68c84 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/HadoopConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/HadoopConfiguration.java
@@ -17,8 +17,10 @@
 
 package org.apache.ignite.configuration;
 
+import org.apache.ignite.lifecycle.LifecycleBean;
 import org.apache.ignite.internal.processors.hadoop.HadoopMapReducePlanner;
 import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * Ignite Hadoop Accelerator configuration.
@@ -51,6 +53,9 @@ public class HadoopConfiguration {
     /** */
     private int maxTaskQueueSize = DFLT_MAX_TASK_QUEUE_SIZE;
 
+    /** Library names. */
+    private String[] libNames;
+
     /**
      * Default constructor.
      */
@@ -71,6 +76,7 @@ public class HadoopConfiguration {
         planner = cfg.getMapReducePlanner();
         maxParallelTasks = cfg.getMaxParallelTasks();
         maxTaskQueueSize = cfg.getMaxTaskQueueSize();
+        libNames = cfg.getNativeLibraryNames();
     }
 
     /**
@@ -169,6 +175,35 @@ public class HadoopConfiguration {
         this.planner = planner;
     }
 
+    /**
+     * Get native library names.
+     * <p>
+     * Ignite Hadoop Accelerator executes all Hadoop jobs and tasks in the same process, isolating them with help
+     * of classloaders. If Hadoop job or task loads a native library, it might lead to exception, because Java do
+     * not allow to load the same library multiple times from different classloaders. To overcome the problem,
+     * you should to the following:
+     * <ul>
+     *     <li>Load necessary libraries in advance from base classloader; {@link LifecycleBean} is a good candidate
+     *     for this;</li>
+     *     <li>Add names of loaded libraries to this property, so that Hadoop engine is able to link them;</li>
+     *     <li>Remove {@link System#load(String)} and {@link System#loadLibrary(String)} calls from your job/task.</li>     *
+     * </ul>
+     *
+     * @return Native library names.
+     */
+    @Nullable public String[] getNativeLibraryNames() {
+        return libNames;
+    }
+
+    /**
+     * Set native library names. See {@link #getNativeLibraryNames()} for more information.
+     *
+     * @param libNames Native library names.
+     */
+    public void setNativeLibraryNames(@Nullable String... libNames) {
+        this.libNames = libNames;
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(HadoopConfiguration.class, this, super.toString());

http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/core/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopJobInfo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopJobInfo.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopJobInfo.java
index eda8e97..a3b1bb6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopJobInfo.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopJobInfo.java
@@ -58,11 +58,12 @@ public interface HadoopJobInfo extends Serializable {
      * @param jobCls The job class.
      * @param jobId Job ID.
      * @param log Logger.
+     * @param libNames Optional additional native library names.
      * @return Job.
      * @throws IgniteCheckedException If failed.
      */
     public HadoopJob createJob(Class<? extends HadoopJob> jobCls,
-        HadoopJobId jobId, IgniteLogger log) throws IgniteCheckedException;
+        HadoopJobId jobId, IgniteLogger log, @Nullable String[] libNames) throws IgniteCheckedException;
 
     /**
      * @return Number of reducers configured for job.

http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopClassLoader.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopClassLoader.java b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopClassLoader.java
index 4448b2d..340b35b 100644
--- a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopClassLoader.java
+++ b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopClassLoader.java
@@ -99,6 +99,9 @@ public class HadoopClassLoader extends URLClassLoader implements ClassCache {
     @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
     private final String name;
 
+    /** Native library names. */
+    private final String[] libNames;
+
     /**
      * Gets name for Job class loader. The name is specific for local node id.
      * @param locNodeId The local node id.
@@ -122,14 +125,19 @@ public class HadoopClassLoader extends URLClassLoader implements ClassCache {
     }
 
     /**
+     * Constructor.
+     *
      * @param urls Urls.
+     * @param name Classloader name.
+     * @param libNames Optional additional native library names to be linked from parent classloader.
      */
-    public HadoopClassLoader(URL[] urls, String name) {
+    public HadoopClassLoader(URL[] urls, String name, @Nullable String[] libNames) {
         super(addHadoopUrls(urls), APP_CLS_LDR);
 
         assert !(getParent() instanceof HadoopClassLoader);
 
         this.name = name;
+        this.libNames = libNames;
 
         initializeNativeLibraries();
     }
@@ -159,9 +167,21 @@ public class HadoopClassLoader extends URLClassLoader implements ClassCache {
                 Vector vector = U.field(ldr, "nativeLibraries");
 
                 for (Object lib : vector) {
-                    String libName = U.field(lib, "name");
+                    String name = U.field(lib, "name");
+
+                    boolean add = name.contains(LIBHADOOP);
+
+                    if (!add && libNames != null) {
+                        for (String libName : libNames) {
+                            if (libName != null && name.contains(libName)) {
+                                add = true;
+
+                                break;
+                            }
+                        }
+                    }
 
-                    if (libName.contains(LIBHADOOP)) {
+                    if (add) {
                         curVector.add(lib);
 
                         return;

http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopDefaultJobInfo.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopDefaultJobInfo.java b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopDefaultJobInfo.java
index fe125fe..be2d9ca 100644
--- a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopDefaultJobInfo.java
+++ b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/HadoopDefaultJobInfo.java
@@ -82,15 +82,15 @@ public class HadoopDefaultJobInfo implements HadoopJobInfo, Externalizable {
     }
 
     /** {@inheritDoc} */
-    @Override public HadoopJob createJob(Class<? extends HadoopJob> jobCls,
-            HadoopJobId jobId, IgniteLogger log) throws IgniteCheckedException {
+    @Override public HadoopJob createJob(Class<? extends HadoopJob> jobCls, HadoopJobId jobId, IgniteLogger log,
+        @Nullable String[] libNames) throws IgniteCheckedException {
         assert jobCls != null;
 
         try {
             Constructor<? extends HadoopJob> constructor = jobCls.getConstructor(HadoopJobId.class,
-                HadoopDefaultJobInfo.class, IgniteLogger.class);
+                HadoopDefaultJobInfo.class, IgniteLogger.class, String[].class);
 
-            return constructor.newInstance(jobId, this, log);
+            return constructor.newInstance(jobId, this, log, libNames);
         }
         // NB: java.lang.NoClassDefFoundError may be thrown from Class#getConstructor() call.
         catch (Throwable t) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/jobtracker/HadoopJobTracker.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/jobtracker/HadoopJobTracker.java b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/jobtracker/HadoopJobTracker.java
index cdd8103..f3e17f3 100644
--- a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/jobtracker/HadoopJobTracker.java
+++ b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/jobtracker/HadoopJobTracker.java
@@ -157,7 +157,12 @@ public class HadoopJobTracker extends HadoopComponent {
 
         assert jobCls == null;
 
-        HadoopClassLoader ldr = new HadoopClassLoader(null, HadoopClassLoader.nameForJob(nodeId));
+        String[] libNames = null;
+
+        if (ctx.configuration() != null)
+            libNames = ctx.configuration().getNativeLibraryNames();
+
+        HadoopClassLoader ldr = new HadoopClassLoader(null, HadoopClassLoader.nameForJob(nodeId), libNames);
 
         try {
             jobCls = (Class<HadoopV2Job>)ldr.loadClass(HadoopV2Job.class.getName());
@@ -727,6 +732,7 @@ public class HadoopJobTracker extends HadoopComponent {
      * @param jobId  Job ID.
      * @param plan Map-reduce plan.
      */
+    @SuppressWarnings({"unused", "ConstantConditions" })
     private void printPlan(HadoopJobId jobId, HadoopMapReducePlan plan) {
         log.info("Plan for " + jobId);
 
@@ -886,6 +892,8 @@ public class HadoopJobTracker extends HadoopComponent {
                     finishFut.onDone(jobId, meta.failCause());
                 }
 
+                assert job != null;
+
                 if (ctx.jobUpdateLeader())
                     job.cleanupStagingDirectory();
 
@@ -1052,7 +1060,7 @@ public class HadoopJobTracker extends HadoopComponent {
                 jobInfo = meta.jobInfo();
             }
 
-            job = jobInfo.createJob(jobCls, jobId, log);
+            job = jobInfo.createJob(jobCls, jobId, log, ctx.configuration().getNativeLibraryNames());
 
             job.initialize(false, ctx.localNodeId());
 
@@ -1667,7 +1675,7 @@ public class HadoopJobTracker extends HadoopComponent {
             if (val != null)
                 e.setValue(val);
             else
-                e.remove();;
+                e.remove();
 
             return null;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/taskexecutor/external/child/HadoopChildProcessRunner.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/taskexecutor/external/child/HadoopChildProcessRunner.java b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/taskexecutor/external/child/HadoopChildProcessRunner.java
index a949141..4a946e9 100644
--- a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/taskexecutor/external/child/HadoopChildProcessRunner.java
+++ b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/taskexecutor/external/child/HadoopChildProcessRunner.java
@@ -134,7 +134,7 @@ public class HadoopChildProcessRunner {
 
                 assert job == null;
 
-                job = req.jobInfo().createJob(HadoopV2Job.class, req.jobId(), log);
+                job = req.jobInfo().createJob(HadoopV2Job.class, req.jobId(), log, null);
 
                 job.initialize(true, nodeDesc.processId());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/v2/HadoopV2Job.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/v2/HadoopV2Job.java b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/v2/HadoopV2Job.java
index b69447d..8804e29 100644
--- a/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/v2/HadoopV2Job.java
+++ b/modules/hadoop/src/main/java/org/apache/ignite/internal/processors/hadoop/v2/HadoopV2Job.java
@@ -93,6 +93,9 @@ public class HadoopV2Job implements HadoopJob {
     /** Job info. */
     protected final HadoopJobInfo jobInfo;
 
+    /** Native library names. */
+    private final String[] libNames;
+
     /** */
     private final JobID hadoopJobID;
 
@@ -119,16 +122,21 @@ public class HadoopV2Job implements HadoopJob {
     private volatile byte[] jobConfData;
 
     /**
+     * Constructor.
+     *
      * @param jobId Job ID.
      * @param jobInfo Job info.
      * @param log Logger.
+     * @param libNames Optional additional native library names.
      */
-    public HadoopV2Job(HadoopJobId jobId, final HadoopDefaultJobInfo jobInfo, IgniteLogger log) {
+    public HadoopV2Job(HadoopJobId jobId, final HadoopDefaultJobInfo jobInfo, IgniteLogger log,
+        @Nullable String[] libNames) {
         assert jobId != null;
         assert jobInfo != null;
 
         this.jobId = jobId;
         this.jobInfo = jobInfo;
+        this.libNames = libNames;
 
         hadoopJobID = new JobID(jobId.globalId().toString(), jobId.localId());
 
@@ -220,7 +228,7 @@ public class HadoopV2Job implements HadoopJob {
     }
 
     /** {@inheritDoc} */
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings({"unchecked", "MismatchedQueryAndUpdateOfCollection" })
     @Override public HadoopTaskContext getTaskContext(HadoopTaskInfo info) throws IgniteCheckedException {
         T2<HadoopTaskType, Integer> locTaskId = new T2<>(info.type(),  info.taskNumber());
 
@@ -242,7 +250,7 @@ public class HadoopV2Job implements HadoopJob {
                 // Note that the classloader identified by the task it was initially created for,
                 // but later it may be reused for other tasks.
                 HadoopClassLoader ldr = new HadoopClassLoader(rsrcMgr.classPath(),
-                    HadoopClassLoader.nameForTask(info, false));
+                    HadoopClassLoader.nameForTask(info, false), libNames);
 
                 cls = (Class<? extends HadoopTaskContext>)ldr.loadClass(HadoopV2TaskContext.class.getName());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopClassLoaderTest.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopClassLoaderTest.java b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopClassLoaderTest.java
index 55fac2c..02d98d0 100644
--- a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopClassLoaderTest.java
+++ b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopClassLoaderTest.java
@@ -49,7 +49,7 @@ import org.apache.ignite.internal.processors.hadoop.deps.Without;
  */
 public class HadoopClassLoaderTest extends TestCase {
     /** */
-    final HadoopClassLoader ldr = new HadoopClassLoader(null, "test");
+    final HadoopClassLoader ldr = new HadoopClassLoader(null, "test", null);
 
     /**
      * @throws Exception If failed.

http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopSnappyTest.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopSnappyTest.java b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopSnappyTest.java
index 014ff1e..b4e3dc2 100644
--- a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopSnappyTest.java
+++ b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopSnappyTest.java
@@ -49,7 +49,7 @@ public class HadoopSnappyTest extends GridCommonAbstractTest {
 
         // Run the same in several more class loaders simulating jobs and tasks:
         for (int i = 0; i < 2; i++) {
-            ClassLoader hadoopClsLdr = new HadoopClassLoader(null, "cl-" + i);
+            ClassLoader hadoopClsLdr = new HadoopClassLoader(null, "cl-" + i, null);
 
             Class<?> cls = (Class)Class.forName(HadoopSnappyTest.class.getName(), true, hadoopClsLdr);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopTasksV1Test.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopTasksV1Test.java b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopTasksV1Test.java
index 6ba9686..27d7fc2 100644
--- a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopTasksV1Test.java
+++ b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopTasksV1Test.java
@@ -48,7 +48,7 @@ public class HadoopTasksV1Test extends HadoopTasksAllVersionsTest {
 
         HadoopJobId jobId = new HadoopJobId(uuid, 0);
 
-        return jobInfo.createJob(HadoopV2Job.class, jobId, log);
+        return jobInfo.createJob(HadoopV2Job.class, jobId, log, null);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopTasksV2Test.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopTasksV2Test.java b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopTasksV2Test.java
index d125deb..30cf50c 100644
--- a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopTasksV2Test.java
+++ b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopTasksV2Test.java
@@ -67,7 +67,7 @@ public class HadoopTasksV2Test extends HadoopTasksAllVersionsTest {
 
         HadoopJobId jobId = new HadoopJobId(uuid, 0);
 
-        return jobInfo.createJob(HadoopV2Job.class, jobId, log);
+        return jobInfo.createJob(HadoopV2Job.class, jobId, log, null);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopV2JobSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopV2JobSelfTest.java b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopV2JobSelfTest.java
index 1e9ffbc..ae2c00d 100644
--- a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopV2JobSelfTest.java
+++ b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/HadoopV2JobSelfTest.java
@@ -78,7 +78,7 @@ public class HadoopV2JobSelfTest extends HadoopAbstractSelfTest {
 
         HadoopJobId id = new HadoopJobId(uuid, 1);
 
-        HadoopJob job = info.createJob(HadoopV2Job.class, id, log);
+        HadoopJob job = info.createJob(HadoopV2Job.class, id, log, null);
 
         HadoopTaskContext taskCtx = job.getTaskContext(new HadoopTaskInfo(HadoopTaskType.MAP, null, 0, 0,
             null));

http://git-wip-us.apache.org/repos/asf/ignite/blob/68b25df3/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/shuffle/collections/HadoopAbstractMapTest.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/shuffle/collections/HadoopAbstractMapTest.java b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/shuffle/collections/HadoopAbstractMapTest.java
index 493098f..5266875 100644
--- a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/shuffle/collections/HadoopAbstractMapTest.java
+++ b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/shuffle/collections/HadoopAbstractMapTest.java
@@ -77,11 +77,13 @@ public abstract class HadoopAbstractMapTest extends GridCommonAbstractTest {
         }
 
         /** {@inheritDoc} */
+        @SuppressWarnings("unchecked")
         @Override public Comparator<Object> sortComparator() {
             return ComparableComparator.getInstance();
         }
 
         /** {@inheritDoc} */
+        @SuppressWarnings("unchecked")
         @Override public Comparator<Object> groupComparator() {
             return ComparableComparator.getInstance();
         }
@@ -141,8 +143,8 @@ public abstract class HadoopAbstractMapTest extends GridCommonAbstractTest {
         }
 
         /** {@inheritDoc} */
-        @Override public HadoopJob createJob(Class<? extends HadoopJob> jobCls,
-                HadoopJobId jobId, IgniteLogger log) throws IgniteCheckedException {
+        @Override public HadoopJob createJob(Class<? extends HadoopJob> jobCls, HadoopJobId jobId, IgniteLogger log,
+            @Nullable String[] libNames) throws IgniteCheckedException {
             assert false;
 
             return null;


[37/50] [abbrv] ignite git commit: Ignite Web Console beta2.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/controllers/sql-controller.js b/modules/web-console/src/main/js/controllers/sql-controller.js
index 4bc39e2..a8058ff 100644
--- a/modules/web-console/src/main/js/controllers/sql-controller.js
+++ b/modules/web-console/src/main/js/controllers/sql-controller.js
@@ -19,18 +19,26 @@
 import consoleModule from 'controllers/common-module';
 
 consoleModule.controller('sqlController', [
-    '$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', '$animate', '$location', '$anchorScroll', '$state', '$modal', '$popover', '$loading', '$common', '$confirm', 'IgniteAgentMonitor', 'IgniteChartColors', 'QueryNotebooks', 'uiGridExporterConstants',
-    function ($root, $scope, $http, $q, $timeout, $interval, $animate, $location, $anchorScroll, $state, $modal, $popover, $loading, $common, $confirm, agentMonitor, IgniteChartColors, QueryNotebooks, uiGridExporterConstants) {
-        var stopTopology = null;
+    '$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', '$animate', '$location', '$anchorScroll', '$state', '$modal', '$popover', '$loading', '$common', '$confirm', 'IgniteAgentMonitor', 'IgniteChartColors', 'QueryNotebooks', 'uiGridConstants', 'uiGridExporterConstants',
+    function($root, $scope, $http, $q, $timeout, $interval, $animate, $location, $anchorScroll, $state, $modal, $popover, $loading, $common, $confirm, agentMonitor, IgniteChartColors, QueryNotebooks, uiGridConstants, uiGridExporterConstants) {
+        let stopTopology = null;
 
-        $scope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
+        const _tryStopRefresh = function(paragraph) {
+            if (paragraph.rate && paragraph.rate.stopTime) {
+                $interval.cancel(paragraph.rate.stopTime);
+
+                delete paragraph.rate.stopTime;
+            }
+        };
+
+        const _stopTopologyRefresh = () => {
             $interval.cancel(stopTopology);
 
             if ($scope.notebook && $scope.notebook.paragraphs)
-                $scope.notebook.paragraphs.forEach(function (paragraph) {
-                    _tryStopRefresh(paragraph);
-                });
-        });
+                $scope.notebook.paragraphs.forEach((paragraph) => _tryStopRefresh(paragraph));
+        };
+
+        $scope.$on('$stateChangeStart', _stopTopologyRefresh);
 
         $scope.caches = [];
 
@@ -51,14 +59,14 @@ consoleModule.controller('sqlController', [
         ];
 
         $scope.exportDropdown = [
-            { 'text': 'Export all', 'click': 'exportCsvAll(paragraph)' }
-            //{ 'text': 'Export all to CSV', 'click': 'exportCsvAll(paragraph)' },
-            //{ 'text': 'Export all to PDF', 'click': 'exportPdfAll(paragraph)' }
+            { text: 'Export all', click: 'exportCsvAll(paragraph)' }
+            // { 'text': 'Export all to CSV', 'click': 'exportCsvAll(paragraph)' },
+            // { 'text': 'Export all to PDF', 'click': 'exportPdfAll(paragraph)' }
         ];
 
         $scope.metadata = [];
 
-        $scope.metaFilter = "";
+        $scope.metaFilter = '';
 
         $scope.metaOptions = {
             nodeChildren: 'children',
@@ -69,1429 +77,1451 @@ consoleModule.controller('sqlController', [
             }
         };
 
-        $scope.maskCacheName = (cacheName) => _.isEmpty(cacheName) ? "&lt;default&gt;" : cacheName;
+        $scope.maskCacheName = (cacheName) => _.isEmpty(cacheName) ? '<default>' : cacheName;
 
-        var _handleException = function(err) {
+        const _handleException = function(err) {
             $common.showError(err);
         };
 
         // Time line X axis descriptor.
-        var TIME_LINE = {value: -1, type: 'java.sql.Date', label: 'TIME_LINE'};
+        const TIME_LINE = {value: -1, type: 'java.sql.Date', label: 'TIME_LINE'};
 
         // Row index X axis descriptor.
-        var ROW_IDX = {value: -2, type: 'java.lang.Integer', label: 'ROW_IDX'};
+        const ROW_IDX = {value: -2, type: 'java.lang.Integer', label: 'ROW_IDX'};
 
         // We need max 1800 items to hold history for 30 mins in case of refresh every second.
-        var HISTORY_LENGTH = 1800;
+        const HISTORY_LENGTH = 1800;
 
-        var MAX_VAL_COLS = IgniteChartColors.length;
+        const MAX_VAL_COLS = IgniteChartColors.length;
 
         $anchorScroll.yOffset = 55;
 
         $scope.chartColor = function(index) {
-            return {"color": "white", "background-color": IgniteChartColors[index]};
+            return {color: 'white', 'background-color': IgniteChartColors[index]};
         };
 
-        $scope.chartRemoveKeyColumn = function (paragraph, index) {
-            paragraph.chartKeyCols.splice(index, 1);
+        function _chartNumber(arr, idx, dflt) {
+            if (idx >= 0 && arr && arr.length > idx && _.isNumber(arr[idx]))
+                return arr[idx];
 
-            _chartApplySettings(paragraph, true);
-        };
+            return dflt;
+        }
 
-        $scope.chartRemoveValColumn = function (paragraph, index) {
-            paragraph.chartValCols.splice(index, 1);
+        function _min(rows, idx, dflt) {
+            let min = _chartNumber(rows[0], idx, dflt);
 
-            _chartApplySettings(paragraph, true);
-        };
+            _.forEach(rows, (row) => {
+                const v = _chartNumber(row, idx, dflt);
 
-        $scope.chartAcceptKeyColumn = function(paragraph, item) {
-            var accepted = _.findIndex(paragraph.chartKeyCols, item) < 0;
+                if (v < min)
+                    min = v;
+            });
 
-            if (accepted) {
-                paragraph.chartKeyCols = [item];
+            return min;
+        }
 
-                _chartApplySettings(paragraph, true);
-            }
+        function _max(rows, idx, dflt) {
+            let max = _chartNumber(rows[0], idx, dflt);
 
-            return false;
-        };
+            _.forEach(rows, (row) => {
+                const v = _chartNumber(row, idx, dflt);
 
-        $scope.chartAcceptValColumn = function(paragraph, item) {
-            var valCols = paragraph.chartValCols;
+                if (v > max)
+                    max = v;
+            });
 
-            var accepted = _.findIndex(valCols, item) < 0 && item.value >= 0 && _numberType(item.type);
+            return max;
+        }
 
-            if (accepted) {
-                if (valCols.length == MAX_VAL_COLS - 1)
-                    valCols.shift();
+        function _sum(rows, idx) {
+            let sum = 0;
 
-                valCols.push(item);
+            _.forEach(rows, (row) => sum += _chartNumber(row, idx, 0));
 
-                _chartApplySettings(paragraph, true);
-            }
+            return sum;
+        }
 
-            return false;
-        };
+        function _aggregate(rows, aggFx, idx, dflt) {
+            const len = rows.length;
 
-        $scope.scrollParagraphs = [];
+            switch (aggFx) {
+                case 'FIRST':
+                    return _chartNumber(rows[0], idx, dflt);
 
-        $scope.rebuildScrollParagraphs = function () {
-            $scope.scrollParagraphs = $scope.notebook.paragraphs.map(function (paragraph) {
-                return {
-                    "text": paragraph.name,
-                    "click": 'scrollToParagraph("' + paragraph.id + '")'
-                };
-            });
-        };
+                case 'LAST':
+                    return _chartNumber(rows[len - 1], idx, dflt);
 
-        $scope.scrollToParagraph = function (paragraphId) {
-            var idx = _.findIndex($scope.notebook.paragraphs, {id: paragraphId});
+                case 'MIN':
+                    return _min(rows, idx, dflt);
 
-            if (idx >= 0) {
-                if (!_.includes($scope.notebook.expandedParagraphs, idx))
-                    $scope.notebook.expandedParagraphs.push(idx);
+                case 'MAX':
+                    return _max(rows, idx, dflt);
 
-                setTimeout(function () {
-                    $scope.notebook.paragraphs[idx].ace.focus();
-                });
-            }
+                case 'SUM':
+                    return _sum(rows, idx);
 
-            $location.hash(paragraphId);
+                case 'AVG':
+                    return len > 0 ? _sum(rows, idx) / len : 0;
 
-            $anchorScroll();
-        };
+                case 'COUNT':
+                    return len;
 
-        const _hideColumn = (col) => col.fieldName !== '_KEY' && col.fieldName !== '_VAL';
+                default:
+            }
 
-        const _allColumn = () => true;
+            return 0;
+        }
 
-        var paragraphId = 0;
+        function _chartLabel(arr, idx, dflt) {
+            if (arr && arr.length > idx && _.isString(arr[idx]))
+                return arr[idx];
 
-        function enhanceParagraph(paragraph) {
-            paragraph.nonEmpty = function () {
-                return this.rows && this.rows.length > 0;
-            };
+            return dflt;
+        }
 
-            paragraph.chart = function () {
-                return this.result != 'table' && this.result != 'none';
-            };
+        function _chartDatum(paragraph) {
+            let datum = [];
 
-            paragraph.queryExecuted = () =>
-                paragraph.queryArgs && paragraph.queryArgs.query && !paragraph.queryArgs.query.startsWith('EXPLAIN ');
+            if (paragraph.chartColumnsConfigured()) {
+                paragraph.chartValCols.forEach(function(valCol) {
+                    let index = 0;
+                    let values = [];
+                    const colIdx = valCol.value;
 
-            paragraph.table = function () {
-                return this.result == 'table';
-            };
+                    if (paragraph.chartTimeLineEnabled()) {
+                        const aggFx = valCol.aggFx;
+                        const colLbl = valCol.label + ' [' + aggFx + ']';
 
-            paragraph.chartColumnsConfigured = function () {
-                return !_.isEmpty(this.chartKeyCols) && !_.isEmpty(this.chartValCols);
-            };
+                        if (paragraph.charts && paragraph.charts.length === 1)
+                            datum = paragraph.charts[0].data;
 
-            paragraph.chartTimeLineEnabled = function () {
-                return !_.isEmpty(this.chartKeyCols) && angular.equals(this.chartKeyCols[0], TIME_LINE);
-            };
+                        const chartData = _.find(datum, {series: valCol.label});
 
-            paragraph.timeLineSupported = function () {
-                return this.result != 'pie';
-            };
+                        const leftBound = new Date();
+                        leftBound.setMinutes(leftBound.getMinutes() - parseInt(paragraph.timeLineSpan, 10));
 
-            paragraph.refreshExecuting = function () {
-                return paragraph.rate && paragraph.rate.stopTime
-            };
+                        if (chartData) {
+                            const lastItem = _.last(paragraph.chartHistory);
 
-            Object.defineProperty(paragraph, 'gridOptions', { value: {
-                onRegisterApi: function(api) {
-                    $animate.enabled(api.grid.element, false);
+                            values = chartData.values;
 
-                    this.api = api;
-                },
-                enableGridMenu: false,
-                enableColumnMenus: false,
-                setRows: function(rows) {
-                    this.height = Math.min(rows.length, 15) * 30 + 42 + 'px';
+                            values.push({
+                                x: lastItem.tm,
+                                y: _aggregate(lastItem.rows, aggFx, colIdx, index++)
+                            });
 
-                    this.data = rows;
-                }
-            }});
+                            while (values.length > 0 && values[0].x < leftBound)
+                                values.shift();
+                        }
+                        else {
+                            _.forEach(paragraph.chartHistory, (history) => {
+                                if (history.tm >= leftBound) {
+                                    values.push({
+                                        x: history.tm,
+                                        y: _aggregate(history.rows, aggFx, colIdx, index++)
+                                    });
+                                }
+                            });
 
-            Object.defineProperty(paragraph, 'chartHistory', {value: []});
-        }
+                            datum.push({series: valCol.label, key: colLbl, values});
+                        }
+                    }
+                    else {
+                        index = paragraph.total;
 
-        $scope.aceInit = function (paragraph) {
-            return function (editor) {
-                editor.setAutoScrollEditorIntoView(true);
-                editor.$blockScrolling = Infinity;
+                        values = _.map(paragraph.rows, function(row) {
+                            const xCol = paragraph.chartKeyCols[0].value;
 
-                var renderer = editor.renderer;
+                            const v = {
+                                x: _chartNumber(row, xCol, index),
+                                xLbl: _chartLabel(row, xCol, null),
+                                y: _chartNumber(row, colIdx, index)
+                            };
 
-                renderer.setHighlightGutterLine(false);
-                renderer.setShowPrintMargin(false);
-                renderer.setOption('fontFamily', 'monospace');
-                renderer.setOption('fontSize', '14px');
-                renderer.setOption('minLines', '5');
-                renderer.setOption('maxLines', '15');
+                            index++;
 
-                editor.setTheme('ace/theme/chrome');
+                            return v;
+                        });
 
-                Object.defineProperty(paragraph, 'ace', { value: editor });
+                        datum.push({series: valCol.label, key: valCol.label, values});
+                    }
+                });
             }
-        };
 
-        var _setActiveCache = function () {
-            if ($scope.caches.length > 0)
-                _.forEach($scope.notebook.paragraphs, function (paragraph) {
-                    if (!_.find($scope.caches, {name: paragraph.cacheName}))
-                        paragraph.cacheName = $scope.caches[0].name;
-                });
-        };
+            return datum;
+        }
 
-        const _refreshFn = () =>
-            agentMonitor.topology()
-                .then((clusters) => {
-                    agentMonitor.checkModal();
+        function _xX(d) {
+            return d.x;
+        }
 
-                    const caches = _.flattenDeep(clusters.map((cluster) => cluster.caches));
+        function _yY(d) {
+            return d.y;
+        }
 
-                    $scope.caches = _.sortBy(_.uniqBy(_.reject(caches, { mode: 'LOCAL' }), 'name'), 'name');
+        function _xAxisTimeFormat(d) {
+            return d3.time.format('%X')(new Date(d));
+        }
 
-                    _setActiveCache();
-                })
-                .catch((err) => {
-                    if (err.code === 2)
-                        return agentMonitor.showNodeError('Agent is failed to authenticate in grid. Please check agent\'s login and password.');
+        const _intClasses = ['java.lang.Byte', 'java.lang.Integer', 'java.lang.Long', 'java.lang.Short'];
 
-                    agentMonitor.showNodeError(err.message)}
-                );
+        function _intType(cls) {
+            return _.includes(_intClasses, cls);
+        }
 
-        var loadNotebook = function (notebook) {
-            $scope.notebook = notebook;
+        const _xAxisWithLabelFormat = function(paragraph) {
+            return function(d) {
+                const values = paragraph.charts[0].data[0].values;
 
-            $scope.notebook_name = notebook.name;
+                const fmt = _intType(paragraph.chartKeyCols[0].type) ? 'd' : ',.2f';
 
-            if (!$scope.notebook.expandedParagraphs)
-                $scope.notebook.expandedParagraphs = [];
+                const dx = values[d];
 
-            if (!$scope.notebook.paragraphs)
-                $scope.notebook.paragraphs = [];
+                if (!dx)
+                    return d3.format(fmt)(d);
 
-            _.forEach(notebook.paragraphs, function (paragraph) {
-                paragraph.id = 'paragraph-' + paragraphId++;
+                const lbl = dx.xLbl;
 
-                enhanceParagraph(paragraph);
-            });
+                return lbl ? lbl : d3.format(fmt)(d);
+            };
+        };
 
-            if (!notebook.paragraphs || notebook.paragraphs.length == 0)
-                $scope.addParagraph();
-            else
-                $scope.rebuildScrollParagraphs();
+        function _xAxisLabel(paragraph) {
+            return _.isEmpty(paragraph.chartKeyCols) ? 'X' : paragraph.chartKeyCols[0].label;
+        }
 
-            agentMonitor.startWatch({
-                    state: 'base.configuration.clusters',
-                    text: 'Back to Configuration',
-                    goal: 'execute sql statements'
-                })
-                .then(() => {
-                    $loading.start('sqlLoading');
+        const _yAxisFormat = function(d) {
+            const fmt = d < 1000 ? ',.2f' : '.3s';
 
-                    _refreshFn()
-                        .finally(() => {
-                            if ($root.IgniteDemoMode)
-                                _.forEach($scope.notebook.paragraphs, $scope.execute);
+            return d3.format(fmt)(d);
+        };
 
-                            $loading.finish('sqlLoading');
+        function _updateCharts(paragraph) {
+            $timeout(() => _.forEach(paragraph.charts, (chart) => chart.api.update()), 100);
+        }
 
-                            stopTopology = $interval(_refreshFn, 5000, 0, false);
-                        });
-                });
-        };
+        function _updateChartsWithData(paragraph, newDatum) {
+            $timeout(() => {
+                if (!paragraph.chartTimeLineEnabled()) {
+                    const chartDatum = paragraph.charts[0].data;
 
-        QueryNotebooks.read($state.params.noteId)
-            .then(loadNotebook)
-            .catch(function() {
-                $scope.notebookLoadFailed = true;
+                    chartDatum.length = 0;
 
-                $loading.finish('sqlLoading');
+                    _.forEach(newDatum, (series) => chartDatum.push(series));
+                }
+
+                paragraph.charts[0].api.update();
             });
+        }
 
-        $scope.renameNotebook = function (name) {
-            if (!name)
-                return;
+        function _yAxisLabel(paragraph) {
+            const cols = paragraph.chartValCols;
 
-            if ($scope.notebook.name != name) {
-                $scope.notebook.name = name;
+            const tml = paragraph.chartTimeLineEnabled();
 
-                QueryNotebooks.save($scope.notebook)
-                    .then(function() {
-                        var idx = _.findIndex($root.notebooks, function (item) {
-                            return item._id == $scope.notebook._id;
-                        });
+            return _.isEmpty(cols) ? 'Y' : _.map(cols, function(col) {
+                let lbl = col.label;
 
-                        if (idx >= 0) {
-                            $root.notebooks[idx].name = name;
+                if (tml)
+                    lbl += ' [' + col.aggFx + ']';
 
-                            $root.rebuildDropdown();
-                        }
+                return lbl;
+            }).join(', ');
+        }
 
-                        $scope.notebook.edit = false;
-                    })
-                    .catch(_handleException);
-            }
-            else
-                $scope.notebook.edit = false
-        };
+        function _barChart(paragraph) {
+            const datum = _chartDatum(paragraph);
 
-        $scope.removeNotebook = function () {
-            $confirm.confirm('Are you sure you want to remove: "' + $scope.notebook.name + '"?')
-                .then(function () {
-                    return QueryNotebooks.remove($scope.notebook);
-                })
-                .then(function (notebook) {
-                    if (notebook)
-                        $state.go('base.sql.notebook', {noteId: notebook._id});
-                    else
-                        $state.go('base.configuration.clusters');
-                })
-                .catch(_handleException);
-        };
-
-        $scope.renameParagraph = function (paragraph, newName) {
-            if (!newName)
-                return;
+            if (_.isEmpty(paragraph.charts)) {
+                const stacked = paragraph.chartsOptions && paragraph.chartsOptions.barChart
+                    ? paragraph.chartsOptions.barChart.stacked
+                    : true;
 
-            if (paragraph.name != newName) {
-                paragraph.name = newName;
+                const options = {
+                    chart: {
+                        type: 'multiBarChart',
+                        height: 400,
+                        margin: {left: 70},
+                        duration: 0,
+                        x: _xX,
+                        y: _yY,
+                        xAxis: {
+                            axisLabel: _xAxisLabel(paragraph),
+                            tickFormat: paragraph.chartTimeLineEnabled() ? _xAxisTimeFormat : _xAxisWithLabelFormat(paragraph),
+                            showMaxMin: false
+                        },
+                        yAxis: {
+                            axisLabel: _yAxisLabel(paragraph),
+                            tickFormat: _yAxisFormat
+                        },
+                        color: IgniteChartColors,
+                        stacked,
+                        showControls: true,
+                        legend: {
+                            vers: 'furious',
+                            margin: {right: -25}
+                        }
+                    }
+                };
 
-                $scope.rebuildScrollParagraphs();
+                paragraph.charts = [{options, data: datum}];
 
-                QueryNotebooks.save($scope.notebook)
-                    .then(function () { paragraph.edit = false; })
-                    .catch(_handleException);
+                _updateCharts(paragraph);
             }
             else
-                paragraph.edit = false
-        };
+                _updateChartsWithData(paragraph, datum);
+        }
 
-        $scope.addParagraph = function () {
-            var sz = $scope.notebook.paragraphs.length;
+        function _pieChartDatum(paragraph) {
+            const datum = [];
 
-            var paragraph = {
-                id: 'paragraph-' + paragraphId++,
-                name: 'Query' + (sz ==0 ? '' : sz),
-                query: '',
-                pageSize: $scope.pageSizes[0],
-                timeLineSpan: $scope.timeLineSpans[0],
-                result: 'none',
-                rate: {
-                    value: 1,
-                    unit: 60000,
-                    installed: false
-                }
-            };
+            if (paragraph.chartColumnsConfigured() && !paragraph.chartTimeLineEnabled()) {
+                paragraph.chartValCols.forEach(function(valCol) {
+                    let index = paragraph.total;
 
-            enhanceParagraph(paragraph);
+                    const values = _.map(paragraph.rows, (row) => {
+                        const xCol = paragraph.chartKeyCols[0].value;
 
-            if ($scope.caches && $scope.caches.length > 0)
-                paragraph.cacheName = $scope.caches[0].name;
+                        const v = {
+                            x: xCol < 0 ? index : row[xCol],
+                            y: _chartNumber(row, valCol.value, index)
+                        };
 
-            $scope.notebook.paragraphs.push(paragraph);
+                        // Workaround for known problem with zero values on Pie chart.
+                        if (v.y === 0)
+                            v.y = 0.0001;
 
-            $scope.notebook.expandedParagraphs.push(sz);
+                        index++;
 
-            $scope.rebuildScrollParagraphs();
+                        return v;
+                    });
 
-            $location.hash(paragraph.id);
+                    datum.push({series: paragraph.chartKeyCols[0].label, key: valCol.label, values});
+                });
+            }
 
-            $anchorScroll();
+            return datum;
+        }
 
-            setTimeout(function () {
-                paragraph.ace.focus();
+        function _pieChart(paragraph) {
+            let datum = _pieChartDatum(paragraph);
+
+            if (datum.length === 0)
+                datum = [{values: []}];
+
+            paragraph.charts = _.map(datum, function(data) {
+                return {
+                    options: {
+                        chart: {
+                            type: 'pieChart',
+                            height: 400,
+                            duration: 0,
+                            x: _xX,
+                            y: _yY,
+                            showLabels: true,
+                            labelThreshold: 0.05,
+                            labelType: 'percent',
+                            donut: true,
+                            donutRatio: 0.35,
+                            legend: {
+                                vers: 'furious',
+                                margin: {
+                                    right: -25
+                                }
+                            }
+                        },
+                        title: {
+                            enable: true,
+                            text: data.key
+                        }
+                    },
+                    data: data.values
+                };
             });
-        };
 
-        $scope.setResult = function (paragraph, new_result) {
-            if (paragraph.result === new_result)
-                return;
+            _updateCharts(paragraph);
+        }
 
-            _saveChartSettings(paragraph);
+        function _lineChart(paragraph) {
+            const datum = _chartDatum(paragraph);
 
-            paragraph.result = new_result;
+            if (_.isEmpty(paragraph.charts)) {
+                const options = {
+                    chart: {
+                        type: 'lineChart',
+                        height: 400,
+                        margin: { left: 70 },
+                        duration: 0,
+                        x: _xX,
+                        y: _yY,
+                        xAxis: {
+                            axisLabel: _xAxisLabel(paragraph),
+                            tickFormat: paragraph.chartTimeLineEnabled() ? _xAxisTimeFormat : _xAxisWithLabelFormat(paragraph),
+                            showMaxMin: false
+                        },
+                        yAxis: {
+                            axisLabel: _yAxisLabel(paragraph),
+                            tickFormat: _yAxisFormat
+                        },
+                        color: IgniteChartColors,
+                        useInteractiveGuideline: true,
+                        legend: {
+                            vers: 'furious',
+                            margin: {
+                                right: -25
+                            }
+                        }
+                    }
+                };
 
-            if (paragraph.chart())
-                _chartApplySettings(paragraph, true);
-        };
+                paragraph.charts = [{options, data: datum}];
 
-        $scope.resultEq = function(paragraph, result) {
-            return (paragraph.result === result);
-        };
+                _updateCharts(paragraph);
+            }
+            else
+                _updateChartsWithData(paragraph, datum);
+        }
 
-        $scope.removeParagraph = function(paragraph) {
-            $confirm.confirm('Are you sure you want to remove: "' + paragraph.name + '"?')
-                .then(function () {
-                    $scope.stopRefresh(paragraph);
+        function _areaChart(paragraph) {
+            const datum = _chartDatum(paragraph);
 
-                    var paragraph_idx = _.findIndex($scope.notebook.paragraphs, function (item) {
-                        return paragraph == item;
-                    });
+            if (_.isEmpty(paragraph.charts)) {
+                const style = paragraph.chartsOptions && paragraph.chartsOptions.areaChart
+                    ? paragraph.chartsOptions.areaChart.style
+                    : 'stack';
 
-                    var panel_idx = _.findIndex($scope.expandedParagraphs, function (item) {
-                        return paragraph_idx == item;
-                    });
+                const options = {
+                    chart: {
+                        type: 'stackedAreaChart',
+                        height: 400,
+                        margin: {left: 70},
+                        duration: 0,
+                        x: _xX,
+                        y: _yY,
+                        xAxis: {
+                            axisLabel: _xAxisLabel(paragraph),
+                            tickFormat: paragraph.chartTimeLineEnabled() ? _xAxisTimeFormat : _xAxisWithLabelFormat(paragraph),
+                            showMaxMin: false
+                        },
+                        yAxis: {
+                            axisLabel: _yAxisLabel(paragraph),
+                            tickFormat: _yAxisFormat
+                        },
+                        color: IgniteChartColors,
+                        style,
+                        legend: {
+                            vers: 'furious',
+                            margin: {right: -25}
+                        }
+                    }
+                };
 
-                    if (panel_idx >= 0)
-                        $scope.expandedParagraphs.splice(panel_idx, 1);
+                paragraph.charts = [{options, data: datum}];
 
-                    $scope.notebook.paragraphs.splice(paragraph_idx, 1);
+                _updateCharts(paragraph);
+            }
+            else
+                _updateChartsWithData(paragraph, datum);
+        }
 
-                    $scope.rebuildScrollParagraphs();
+        function _chartApplySettings(paragraph, resetCharts) {
+            if (resetCharts)
+                paragraph.charts = [];
 
-                    QueryNotebooks.save($scope.notebook)
-                        .catch(_handleException);
-                });
-        };
+            if (paragraph.chart() && paragraph.nonEmpty()) {
+                switch (paragraph.result) {
+                    case 'bar':
+                        _barChart(paragraph);
+                        break;
 
-        $scope.paragraphExpanded = function(paragraph) {
-            var paragraph_idx = _.findIndex($scope.notebook.paragraphs, function (item) {
-                return paragraph == item;
-            });
+                    case 'pie':
+                        _pieChart(paragraph);
+                        break;
 
-            var panel_idx = _.findIndex($scope.notebook.expandedParagraphs, function (item) {
-                return paragraph_idx == item;
-            });
+                    case 'line':
+                        _lineChart(paragraph);
+                        break;
 
-            return panel_idx >= 0;
+                    case 'area':
+                        _areaChart(paragraph);
+                        break;
+
+                    default:
+                }
+            }
+        }
+
+        $scope.chartRemoveKeyColumn = function(paragraph, index) {
+            paragraph.chartKeyCols.splice(index, 1);
+
+            _chartApplySettings(paragraph, true);
         };
 
-        var _columnFilter = function(paragraph) {
-            return paragraph.disabledSystemColumns || paragraph.systemColumns ? _allColumn : _hideColumn;
+        $scope.chartRemoveValColumn = function(paragraph, index) {
+            paragraph.chartValCols.splice(index, 1);
+
+            _chartApplySettings(paragraph, true);
         };
 
-        var _notObjectType = function(cls) {
-            return $common.isJavaBuiltInClass(cls);
+        $scope.chartAcceptKeyColumn = function(paragraph, item) {
+            const accepted = _.findIndex(paragraph.chartKeyCols, item) < 0;
+
+            if (accepted) {
+                paragraph.chartKeyCols = [item];
+
+                _chartApplySettings(paragraph, true);
+            }
+
+            return false;
         };
 
-        var _numberClasses = ['java.math.BigDecimal', 'java.lang.Byte', 'java.lang.Double',
+        const _numberClasses = ['java.math.BigDecimal', 'java.lang.Byte', 'java.lang.Double',
             'java.lang.Float', 'java.lang.Integer', 'java.lang.Long', 'java.lang.Short'];
 
-        var _numberType = function(cls) {
+        const _numberType = function(cls) {
             return _.includes(_numberClasses, cls);
         };
 
-        var _intClasses = ['java.lang.Byte', 'java.lang.Integer', 'java.lang.Long', 'java.lang.Short'];
+        $scope.chartAcceptValColumn = function(paragraph, item) {
+            const valCols = paragraph.chartValCols;
 
-        function _intType(cls) {
-            return _.includes(_intClasses, cls);
-        }
+            const accepted = _.findIndex(valCols, item) < 0 && item.value >= 0 && _numberType(item.type);
 
-        var _rebuildColumns = function (paragraph) {
-            var columnDefs = [];
+            if (accepted) {
+                if (valCols.length === MAX_VAL_COLS - 1)
+                    valCols.shift();
 
-            _.forEach(_.groupBy(paragraph.meta, 'fieldName'), function (colsByName, fieldName) {
-                var colsByTypes = _.groupBy(colsByName, 'typeName');
+                valCols.push(item);
 
-                var needType = _.keys(colsByTypes).length > 1;
+                _chartApplySettings(paragraph, true);
+            }
 
-                _.forEach(colsByTypes, function(colsByType, typeName) {
-                    _.forEach(colsByType, function (col, ix) {
-                        col.fieldName = (needType && !$common.isEmptyString(typeName) ? typeName + '.' : '') + fieldName + (ix > 0 ? ix : '');
-                    })
-                });
-            });
+            return false;
+        };
 
-            _.forEach(paragraph.meta, function (col, idx) {
-                if (paragraph.columnFilter(col)) {
-                    if (_notObjectType(col.fieldTypeName))
-                        paragraph.chartColumns.push({value: idx, type: col.fieldTypeName, label: col.fieldName, aggFx: $scope.aggregateFxs[0]});
-
-                    columnDefs.push({
-                        displayName: col.fieldName,
-                        headerTooltip: _fullColName(col),
-                        field: paragraph.queryArgs.query ? '' + idx : col.fieldName,
-                        minWidth: 50
-                    });
-                }
+        $scope.scrollParagraphs = [];
+
+        $scope.rebuildScrollParagraphs = function() {
+            $scope.scrollParagraphs = $scope.notebook.paragraphs.map(function(paragraph) {
+                return {
+                    text: paragraph.name,
+                    click: 'scrollToParagraph("' + paragraph.id + '")'
+                };
             });
+        };
 
-            paragraph.gridOptions.columnDefs = columnDefs;
+        $scope.scrollToParagraph = function(paragraphId) {
+            const idx = _.findIndex($scope.notebook.paragraphs, {id: paragraphId});
 
-            if (paragraph.chartColumns.length > 0) {
-                paragraph.chartColumns.push(TIME_LINE);
-                paragraph.chartColumns.push(ROW_IDX);
+            if (idx >= 0) {
+                if (!_.includes($scope.notebook.expandedParagraphs, idx))
+                    $scope.notebook.expandedParagraphs.push(idx);
+
+                setTimeout(function() {
+                    $scope.notebook.paragraphs[idx].ace.focus();
+                });
             }
 
-            // We could accept onl not object columns for X axis.
-            paragraph.chartKeyCols = _retainColumns(paragraph.chartColumns, paragraph.chartKeyCols, _notObjectType, true);
+            $location.hash(paragraphId);
 
-            // We could accept only numeric columns for Y axis.
-            paragraph.chartValCols = _retainColumns(paragraph.chartColumns, paragraph.chartValCols, _numberType, false, paragraph.chartKeyCols);
+            $anchorScroll();
         };
 
-        $scope.toggleSystemColumns = function (paragraph) {
-            if (paragraph.disabledSystemColumns)
-                return;
-
-            paragraph.systemColumns = !paragraph.systemColumns;
-
-            paragraph.columnFilter = _columnFilter(paragraph);
+        const _hideColumn = (col) => col.fieldName !== '_KEY' && col.fieldName !== '_VAL';
 
-            paragraph.chartColumns = [];
+        const _allColumn = () => true;
 
-            _rebuildColumns(paragraph);
-        };
+        let paragraphId = 0;
 
-        function _retainColumns(allCols, curCols, acceptableType, xAxis, unwantedCols) {
-            var retainedCols = [];
+        const _fullColName = function(col) {
+            const res = [];
 
-            var availableCols = xAxis ? allCols : _.filter(allCols, function (col) {
-                return col.value >= 0;
-            });
+            if (col.schemaName)
+                res.push(col.schemaName);
 
-            if (availableCols.length > 0) {
-                curCols.forEach(function (curCol) {
-                    var col = _.find(availableCols, {label: curCol.label});
+            if (col.typeName)
+                res.push(col.typeName);
 
-                    if (col && acceptableType(col.type)) {
-                        col.aggFx = curCol.aggFx;
+            res.push(col.fieldName);
 
-                        retainedCols.push(col);
-                    }
-                });
+            return res.join('.');
+        };
 
-                // If nothing was restored, add first acceptable column.
-                if (_.isEmpty(retainedCols)) {
-                    var col;
+        function enhanceParagraph(paragraph) {
+            paragraph.nonEmpty = function() {
+                return this.rows && this.rows.length > 0;
+            };
 
-                    if (unwantedCols)
-                        col = _.find(availableCols, function (col) {
-                            return !_.find(unwantedCols, {label: col.label}) && acceptableType(col.type);
-                        });
+            paragraph.chart = function() {
+                return this.result !== 'table' && this.result !== 'none';
+            };
 
-                    if (!col)
-                        col = _.find(availableCols, function (col) {
-                            return acceptableType(col.type);
-                        });
+            paragraph.queryExecuted = () =>
+                paragraph.queryArgs && paragraph.queryArgs.query && !paragraph.queryArgs.query.startsWith('EXPLAIN ');
 
-                    if (col)
-                        retainedCols.push(col);
-                }
-            }
+            paragraph.table = function() {
+                return this.result === 'table';
+            };
 
-            return retainedCols;
-        }
+            paragraph.chartColumnsConfigured = function() {
+                return !_.isEmpty(this.chartKeyCols) && !_.isEmpty(this.chartValCols);
+            };
 
-        /**
-         * @param {Object} paragraph Query
-         * @param {{fieldsMetadata: Array, items: Array, queryId: int, last: Boolean}} res Query results.
-         * @private
-         */
-        var _processQueryResult = function (paragraph, res) {
-            var prevKeyCols = paragraph.chartKeyCols;
-            var prevValCols = paragraph.chartValCols;
+            paragraph.chartTimeLineEnabled = function() {
+                return !_.isEmpty(this.chartKeyCols) && angular.equals(this.chartKeyCols[0], TIME_LINE);
+            };
 
-            if (!_.eq(paragraph.meta, res.fieldsMetadata)) {
-                paragraph.meta = [];
+            paragraph.timeLineSupported = function() {
+                return this.result !== 'pie';
+            };
 
-                paragraph.chartColumns = [];
+            paragraph.refreshExecuting = function() {
+                return paragraph.rate && paragraph.rate.stopTime;
+            };
 
-                if (!$common.isDefined(paragraph.chartKeyCols))
-                    paragraph.chartKeyCols = [];
+            Object.defineProperty(paragraph, 'gridOptions', { value: {
+                enableGridMenu: false,
+                enableColumnMenus: false,
+                flatEntityAccess: true,
+                fastWatch: true,
+                updateColumns(cols) {
+                    this.columnDefs = _.map(cols, (col) => {
+                        return {
+                            displayName: col.fieldName,
+                            headerTooltip: _fullColName(col),
+                            field: col.field,
+                            minWidth: 50
+                        };
+                    });
 
-                if (!$common.isDefined(paragraph.chartValCols))
-                    paragraph.chartValCols = [];
+                    $timeout(() => this.api.core.notifyDataChange(uiGridConstants.dataChange.COLUMN));
+                },
+                updateRows(rows) {
+                    const sizeChanged = this.data.length !== rows.length;
 
-                if (res.fieldsMetadata.length <= 2) {
-                    var _key = _.find(res.fieldsMetadata, {fieldName: '_KEY'});
-                    var _val = _.find(res.fieldsMetadata, {fieldName: '_VAL'});
+                    this.data = rows;
 
-                    paragraph.disabledSystemColumns = (res.fieldsMetadata.length == 2 && _key && _val) ||
-                        (res.fieldsMetadata.length == 1 && (_key || _val));
-                }
+                    if (sizeChanged) {
+                        const height = Math.min(rows.length, 15) * 30 + 47;
 
-                paragraph.columnFilter = _columnFilter(paragraph);
+                        // Remove header height.
+                        this.api.grid.element.css('height', height + 'px');
 
-                paragraph.meta = res.fieldsMetadata;
+                        $timeout(() => this.api.core.handleWindowResize());
+                    }
+                },
+                onRegisterApi(api) {
+                    $animate.enabled(api.grid.element, false);
 
-                _rebuildColumns(paragraph);
-            }
+                    this.api = api;
+                }
+            }});
 
-            paragraph.page = 1;
+            Object.defineProperty(paragraph, 'chartHistory', {value: []});
+        }
 
-            paragraph.total = 0;
+        $scope.aceInit = function(paragraph) {
+            return function(editor) {
+                editor.setAutoScrollEditorIntoView(true);
+                editor.$blockScrolling = Infinity;
 
-            paragraph.queryId = res.last ? null : res.queryId;
+                const renderer = editor.renderer;
 
-            delete paragraph.errMsg;
+                renderer.setHighlightGutterLine(false);
+                renderer.setShowPrintMargin(false);
+                renderer.setOption('fontFamily', 'monospace');
+                renderer.setOption('fontSize', '14px');
+                renderer.setOption('minLines', '5');
+                renderer.setOption('maxLines', '15');
 
-            // Prepare explain results for display in table.
-            if (paragraph.queryArgs.query && paragraph.queryArgs.query.startsWith('EXPLAIN') && res.items) {
-                paragraph.rows = [];
+                editor.setTheme('ace/theme/chrome');
 
-                res.items.forEach(function (row, i) {
-                    var line = res.items.length - 1 == i ? row[0] : row[0] + '\n';
+                Object.defineProperty(paragraph, 'ace', { value: editor });
+            };
+        };
 
-                    line.replace(/\"/g, '').split('\n').forEach(function (line) {
-                        paragraph.rows.push([line]);
-                    });
+        const _setActiveCache = function() {
+            if ($scope.caches.length > 0) {
+                _.forEach($scope.notebook.paragraphs, (paragraph) => {
+                    if (!_.find($scope.caches, {name: paragraph.cacheName}))
+                        paragraph.cacheName = $scope.caches[0].name;
                 });
             }
-            else
-                paragraph.rows = res.items;
-
-            paragraph.gridOptions.setRows(paragraph.rows);
+        };
 
-            var chartHistory = paragraph.chartHistory;
+        const _updateTopology = () =>
+            agentMonitor.topology()
+                .then((clusters) => {
+                    agentMonitor.checkModal();
 
-            // Clear history on query change.
-            var queryChanged = paragraph.prevQuery != paragraph.query;
+                    const caches = _.flattenDeep(clusters.map((cluster) => cluster.caches));
 
-            if (queryChanged) {
-                paragraph.prevQuery = paragraph.query;
+                    $scope.caches = _.sortBy(_.map(_.uniqBy(_.reject(caches, {mode: 'LOCAL'}), 'name'), (cache) => {
+                        cache.label = $scope.maskCacheName(cache.name);
 
-                chartHistory.length = 0;
+                        return cache;
+                    }), 'label');
 
-                _.forEach(paragraph.charts, function (chart) {
-                    chart.data.length = 0;
+                    _setActiveCache();
                 })
-            }
-
-            // Add results to history.
-            chartHistory.push({tm: new Date(), rows: paragraph.rows});
-
-            // Keep history size no more than max length.
-            while (chartHistory.length > HISTORY_LENGTH)
-                chartHistory.shift();
+                .catch((err) => {
+                    if (err.code === 2)
+                        return agentMonitor.showNodeError('Agent is failed to authenticate in grid. Please check agent\'s login and password.');
 
-            _showLoading(paragraph, false);
+                    agentMonitor.showNodeError(err);
+                });
 
-            if (paragraph.result === 'none' || !paragraph.queryExecuted())
-                paragraph.result = 'table';
-            else if (paragraph.chart()) {
-                var resetCharts = queryChanged;
+        const _startTopologyRefresh = () => {
+            $loading.start('sqlLoading');
 
-                if (!resetCharts) {
-                    var curKeyCols = paragraph.chartKeyCols;
-                    var curValCols = paragraph.chartValCols;
+            agentMonitor.awaitAgent()
+                .then(_updateTopology)
+                .finally(() => {
+                    if ($root.IgniteDemoMode)
+                        _.forEach($scope.notebook.paragraphs, $scope.execute);
 
-                    resetCharts = !prevKeyCols || !prevValCols ||
-                        prevKeyCols.length != curKeyCols.length ||
-                        prevValCols.length != curValCols.length;
-                }
+                    $loading.finish('sqlLoading');
 
-                _chartApplySettings(paragraph, resetCharts);
-            }
+                    stopTopology = $interval(_updateTopology, 5000, 0, false);
+                });
         };
 
-        const _closeOldQuery = (paragraph) => {
-            const queryId = paragraph.queryArgs && paragraph.queryArgs.queryId;
+        const loadNotebook = function(notebook) {
+            $scope.notebook = notebook;
 
-            return queryId ? agentMonitor.queryClose(queryId) : $q.when();
-        };
+            $scope.notebook_name = notebook.name;
 
-        const _executeRefresh = (paragraph) => {
-            const args = paragraph.queryArgs;
+            if (!$scope.notebook.expandedParagraphs)
+                $scope.notebook.expandedParagraphs = [];
 
-            agentMonitor.awaitAgent()
-                .then(() => _closeOldQuery(paragraph))
-                .then(() => agentMonitor.query(args.cacheName, args.pageSize, args.query))
-                .then(_processQueryResult.bind(this, paragraph))
-                .catch((err) => {
-                    paragraph.errMsg = err.message;
-                });
-        };
+            if (!$scope.notebook.paragraphs)
+                $scope.notebook.paragraphs = [];
 
-        const _showLoading = (paragraph, enable) => paragraph.loading = enable;
+            _.forEach(notebook.paragraphs, (paragraph) => {
+                paragraph.id = 'paragraph-' + paragraphId++;
 
-        $scope.execute = function (paragraph) {
-            QueryNotebooks.save($scope.notebook)
-                .catch(_handleException);
+                enhanceParagraph(paragraph);
+            });
 
-            paragraph.prevQuery = paragraph.queryArgs ? paragraph.queryArgs.query : paragraph.query;
+            if (!notebook.paragraphs || notebook.paragraphs.length === 0)
+                $scope.addParagraph();
+            else
+                $scope.rebuildScrollParagraphs();
 
-            _showLoading(paragraph, true);
+            agentMonitor.startWatch({
+                state: 'base.configuration.clusters',
+                text: 'Back to Configuration',
+                goal: 'execute sql statements',
+                onDisconnect: () => {
+                    _stopTopologyRefresh();
 
-            _closeOldQuery(paragraph)
-                .then(function () {
-                    const args = paragraph.queryArgs = {
-                        cacheName: paragraph.cacheName,
-                        pageSize: paragraph.pageSize,
-                        query: paragraph.query
-                    };
+                    _startTopologyRefresh();
+                }
+            })
+            .then(_startTopologyRefresh);
+        };
 
-                    return agentMonitor.query(args.cacheName, args.pageSize, args.query);
-                })
-                .then(function (res) {
-                    _processQueryResult(paragraph, res);
+        QueryNotebooks.read($state.params.noteId)
+            .then(loadNotebook)
+            .catch(() => {
+                $scope.notebookLoadFailed = true;
 
-                    _tryStartRefresh(paragraph);
-                })
-                .catch((err) => {
-                    paragraph.errMsg = err.message;
+                $loading.finish('sqlLoading');
+            });
 
-                    _showLoading(paragraph, false);
+        $scope.renameNotebook = function(name) {
+            if (!name)
+                return;
 
-                    $scope.stopRefresh(paragraph);
-                })
-                .finally(function () {
-                    paragraph.ace.focus();
-                });
-        };
+            if ($scope.notebook.name !== name) {
+                const prevName = $scope.notebook.name;
 
-        $scope.queryExecuted = function(paragraph) {
-            return $common.isDefined(paragraph.queryArgs);
-        };
+                $scope.notebook.name = name;
 
-        $scope.explain = function (paragraph) {
-            QueryNotebooks.save($scope.notebook)
-                .catch(_handleException);
+                QueryNotebooks.save($scope.notebook)
+                    .then(function() {
+                        const idx = _.findIndex($root.notebooks, function(item) {
+                            return item._id === $scope.notebook._id;
+                        });
 
-            _cancelRefresh(paragraph);
+                        if (idx >= 0) {
+                            $root.notebooks[idx].name = name;
 
-            _showLoading(paragraph, true);
+                            $root.rebuildDropdown();
+                        }
 
-            _closeOldQuery(paragraph)
-                .then(function () {
-                    const args = paragraph.queryArgs = {
-                        cacheName: paragraph.cacheName,
-                        pageSize: paragraph.pageSize,
-                        query: 'EXPLAIN ' + paragraph.query
-                    };
+                        $scope.notebook.edit = false;
+                    })
+                    .catch((err) => {
+                        $scope.notebook.name = prevName;
 
-                    return agentMonitor.query(args.cacheName, args.pageSize, args.query);
-                })
-                .then(_processQueryResult.bind(this, paragraph))
-                .catch((err) => {
-                    paragraph.errMsg = err.message;
+                        _handleException(err);
+                    });
+            }
+            else
+                $scope.notebook.edit = false;
+        };
 
-                    _showLoading(paragraph, false);
+        $scope.removeNotebook = function() {
+            $confirm.confirm('Are you sure you want to remove: "' + $scope.notebook.name + '"?')
+                .then(function() {
+                    return QueryNotebooks.remove($scope.notebook);
+                })
+                .then(function(notebook) {
+                    if (notebook)
+                        $state.go('base.sql.notebook', {noteId: notebook._id});
+                    else
+                        $state.go('base.configuration.clusters');
                 })
-                .finally(function () {
-                    paragraph.ace.focus();
-                });
-        };
-
-        $scope.scan = function (paragraph) {
-            QueryNotebooks.save($scope.notebook)
                 .catch(_handleException);
+        };
 
-            _cancelRefresh(paragraph);
-
-            _showLoading(paragraph, true);
+        $scope.renameParagraph = function(paragraph, newName) {
+            if (!newName)
+                return;
 
-            _closeOldQuery(paragraph)
-                .then(() => {
-                    const args = paragraph.queryArgs = {
-                        cacheName: paragraph.cacheName,
-                        pageSize: paragraph.pageSize
-                    };
+            if (paragraph.name !== newName) {
+                paragraph.name = newName;
 
-                    return agentMonitor.query(args.cacheName, args.pageSize);
-                })
-                .then(_processQueryResult.bind(this, paragraph))
-                .catch((err) => {
-                    paragraph.errMsg = err.message;
+                $scope.rebuildScrollParagraphs();
 
-                    _showLoading(paragraph, false);
-                })
-                .finally(function () {
-                    paragraph.ace.focus();
-                });
+                QueryNotebooks.save($scope.notebook)
+                    .then(function() { paragraph.edit = false; })
+                    .catch(_handleException);
+            }
+            else
+                paragraph.edit = false;
         };
 
-        $scope.nextPage = function(paragraph) {
-            _showLoading(paragraph, true);
+        $scope.addParagraph = function() {
+            const sz = $scope.notebook.paragraphs.length;
 
-            paragraph.queryArgs.pageSize = paragraph.pageSize;
+            const paragraph = {
+                id: 'paragraph-' + paragraphId++,
+                name: 'Query' + (sz === 0 ? '' : sz),
+                query: '',
+                pageSize: $scope.pageSizes[0],
+                timeLineSpan: $scope.timeLineSpans[0],
+                result: 'none',
+                rate: {
+                    value: 1,
+                    unit: 60000,
+                    installed: false
+                }
+            };
 
-            agentMonitor.next(paragraph.queryId, paragraph.pageSize)
-                .then(function (res) {
-                    paragraph.page++;
+            enhanceParagraph(paragraph);
 
-                    paragraph.total += paragraph.rows.length;
+            if ($scope.caches && $scope.caches.length > 0)
+                paragraph.cacheName = $scope.caches[0].name;
 
-                    paragraph.rows = res.items;
+            $scope.notebook.paragraphs.push(paragraph);
 
-                    if (paragraph.chart()) {
-                        if (paragraph.result == 'pie')
-                            _updatePieChartsWithData(paragraph, _pieChartDatum(paragraph));
-                        else
-                            _updateChartsWithData(paragraph, _chartDatum(paragraph));
-                    }
+            $scope.notebook.expandedParagraphs.push(sz);
 
-                    paragraph.gridOptions.setRows(paragraph.rows);
+            $scope.rebuildScrollParagraphs();
 
-                    _showLoading(paragraph, false);
+            $location.hash(paragraph.id);
 
-                    if (res.last)
-                        delete paragraph.queryId;
-                })
-                .catch((err) => {
-                    paragraph.errMsg = err.message;
+            $anchorScroll();
 
-                    _showLoading(paragraph, false);
-                })
-                .finally(function () {
-                    paragraph.ace.focus();
-                });
+            setTimeout(function() {
+                paragraph.ace.focus();
+            });
         };
 
-        var _fullColName = function(col) {
-            var res = [];
-
-            if (col.schemaName)
-                res.push(col.schemaName);
-            if (col.typeName)
-                res.push(col.typeName);
+        function _saveChartSettings(paragraph) {
+            if (!_.isEmpty(paragraph.charts)) {
+                const chart = paragraph.charts[0].api.getScope().chart;
 
-            res.push(col.fieldName);
+                if (!$common.isDefined(paragraph.chartsOptions))
+                    paragraph.chartsOptions = {barChart: {stacked: true}, areaChart: {style: 'stack'}};
 
-            return res.join('.');
-        };
+                switch (paragraph.result) {
+                    case 'bar':
+                        paragraph.chartsOptions.barChart.stacked = chart.stacked();
 
-        const _export = (fileName, columnFilter, meta, rows) => {
-            let csvContent = '';
+                        break;
 
-            const cols = [];
-            const excludedCols = [];
+                    case 'area':
+                        paragraph.chartsOptions.areaChart.style = chart.style();
 
-            if (meta) {
-                _.forEach(meta, (col, idx) => {
-                    if (columnFilter(col))
-                        cols.push(_fullColName(col));
-                    else
-                        excludedCols.push(idx);
-                });
+                        break;
 
-                csvContent += cols.join(';') + '\n';
+                    default:
+                }
             }
+        }
 
-            _.forEach(rows, (row) => {
-                cols.length = 0;
+        $scope.setResult = function(paragraph, new_result) {
+            if (paragraph.result === new_result)
+                return;
 
-                if (Array.isArray(row)) {
-                    _.forEach(row, (elem, idx) => {
-                        if (_.includes(excludedCols, idx))
-                            return;
+            _saveChartSettings(paragraph);
 
-                        cols.push(_.isUndefined(elem) ? '' : JSON.stringify(elem));
+            paragraph.result = new_result;
+
+            if (paragraph.chart())
+                _chartApplySettings(paragraph, true);
+            else
+                $timeout(() => paragraph.gridOptions.api.core.handleWindowResize());
+        };
+
+        $scope.resultEq = function(paragraph, result) {
+            return (paragraph.result === result);
+        };
+
+        $scope.removeParagraph = function(paragraph) {
+            $confirm.confirm('Are you sure you want to remove: "' + paragraph.name + '"?')
+                .then(function() {
+                    $scope.stopRefresh(paragraph);
+
+                    const paragraph_idx = _.findIndex($scope.notebook.paragraphs, function(item) {
+                        return paragraph === item;
                     });
-                }
-                else {
-                    _.forEach(meta, (col) => {
-                        if (columnFilter(col)) {
-                            const elem = row[col.fieldName];
 
-                            cols.push(_.isUndefined(elem) ? '' : JSON.stringify(elem));
-                        }
+                    const panel_idx = _.findIndex($scope.expandedParagraphs, function(item) {
+                        return paragraph_idx === item;
                     });
-                }
 
-                csvContent += cols.join(';') + '\n';
-            });
+                    if (panel_idx >= 0)
+                        $scope.expandedParagraphs.splice(panel_idx, 1);
 
-            $common.download('application/octet-stream;charset=utf-8', fileName, escape(csvContent));
-        };
+                    $scope.notebook.paragraphs.splice(paragraph_idx, 1);
 
-        $scope.exportCsv = function(paragraph) {
-            _export(paragraph.name + '.csv', paragraph.columnFilter, paragraph.meta, paragraph.rows);
+                    $scope.rebuildScrollParagraphs();
 
-            //paragraph.gridOptions.api.exporter.csvExport(uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE);
+                    QueryNotebooks.save($scope.notebook)
+                        .catch(_handleException);
+                });
         };
 
-        $scope.exportPdf = function(paragraph) {
-            paragraph.gridOptions.api.exporter.pdfExport(uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE);
-        };
+        $scope.paragraphExpanded = function(paragraph) {
+            const paragraph_idx = _.findIndex($scope.notebook.paragraphs, function(item) {
+                return paragraph === item;
+            });
 
-        $scope.exportCsvAll = function (paragraph) {
-            const args = paragraph.queryArgs;
+            const panel_idx = _.findIndex($scope.notebook.expandedParagraphs, function(item) {
+                return paragraph_idx === item;
+            });
 
-            agentMonitor.queryGetAll(args.cacheName, args.query)
-                .then((res) => _export(paragraph.name + '-all.csv', paragraph.columnFilter, res.fieldsMetadata, res.items))
-                .finally(() => paragraph.ace.focus());
+            return panel_idx >= 0;
         };
 
-        $scope.exportPdfAll = function(paragraph) {
-            //$http.post('/api/v1/agent/query/getAll', {query: paragraph.query, cacheName: paragraph.cacheName})
-            //    .success(function (item) {
-            //        _export(paragraph.name + '-all.csv', item.meta, item.rows);
-            //    })
-            //    .error(function (errMsg) {
-            //        $common.showError(errMsg);
-            //    });
+        const _columnFilter = function(paragraph) {
+            return paragraph.disabledSystemColumns || paragraph.systemColumns ? _allColumn : _hideColumn;
         };
 
-        $scope.rateAsString = function (paragraph) {
-            if (paragraph.rate && paragraph.rate.installed) {
-                var idx = _.findIndex($scope.timeUnit, function (unit) {
-                    return unit.value == paragraph.rate.unit;
-                });
+        const _notObjectType = function(cls) {
+            return $common.isJavaBuiltInClass(cls);
+        };
 
-                if (idx >= 0)
-                    return ' ' + paragraph.rate.value + $scope.timeUnit[idx].short;
+        function _retainColumns(allCols, curCols, acceptableType, xAxis, unwantedCols) {
+            const retainedCols = [];
 
-                paragraph.rate.installed = false;
-            }
+            const availableCols = xAxis ? allCols : _.filter(allCols, function(col) {
+                return col.value >= 0;
+            });
 
-            return '';
-        };
+            if (availableCols.length > 0) {
+                curCols.forEach(function(curCol) {
+                    const col = _.find(availableCols, {label: curCol.label});
 
-        var _cancelRefresh = function (paragraph) {
-            if (paragraph.rate && paragraph.rate.stopTime) {
-                delete paragraph.queryArgs;
+                    if (col && acceptableType(col.type)) {
+                        col.aggFx = curCol.aggFx;
 
-                paragraph.rate.installed = false;
+                        retainedCols.push(col);
+                    }
+                });
 
-                $interval.cancel(paragraph.rate.stopTime);
+                // If nothing was restored, add first acceptable column.
+                if (_.isEmpty(retainedCols)) {
+                    let col;
 
-                delete paragraph.rate.stopTime;
-            }
-        };
+                    if (unwantedCols)
+                        col = _.find(availableCols, (avCol) => !_.find(unwantedCols, {label: avCol.label}) && acceptableType(avCol.type));
 
-        var _tryStopRefresh = function (paragraph) {
-            if (paragraph.rate && paragraph.rate.stopTime) {
-                $interval.cancel(paragraph.rate.stopTime);
+                    if (!col)
+                        col = _.find(availableCols, (avCol) => acceptableType(avCol.type));
 
-                delete paragraph.rate.stopTime;
+                    if (col)
+                        retainedCols.push(col);
+                }
             }
-        };
 
-        var _tryStartRefresh = function (paragraph) {
-            _tryStopRefresh(paragraph);
+            return retainedCols;
+        }
 
-            if (paragraph.rate && paragraph.rate.installed && paragraph.queryArgs) {
-                $scope.chartAcceptKeyColumn(paragraph, TIME_LINE);
+        const _rebuildColumns = function(paragraph) {
+            _.forEach(_.groupBy(paragraph.meta, 'fieldName'), function(colsByName, fieldName) {
+                const colsByTypes = _.groupBy(colsByName, 'typeName');
 
-                _executeRefresh(paragraph);
+                const needType = _.keys(colsByTypes).length > 1;
 
-                var delay = paragraph.rate.value * paragraph.rate.unit;
+                _.forEach(colsByTypes, function(colsByType, typeName) {
+                    _.forEach(colsByType, function(col, ix) {
+                        col.fieldName = (needType && !$common.isEmptyString(typeName) ? typeName + '.' : '') + fieldName + (ix > 0 ? ix : '');
+                    });
+                });
+            });
 
-                paragraph.rate.stopTime = $interval(_executeRefresh, delay, 0, false, paragraph);
-            }
-        };
+            const cols = [];
 
-        $scope.startRefresh = function (paragraph, value, unit) {
-            paragraph.rate.value = value;
-            paragraph.rate.unit = unit;
-            paragraph.rate.installed = true;
+            _.forEach(paragraph.meta, (col, idx) => {
+                if (paragraph.columnFilter(col)) {
+                    col.field = paragraph.queryArgs.query ? idx.toString() : col.fieldName;
 
-            if (paragraph.queryExecuted())
-                _tryStartRefresh(paragraph);
-        };
+                    cols.push(col);
+                }
+            });
 
-        $scope.stopRefresh = function (paragraph) {
-            paragraph.rate.installed = false;
+            paragraph.gridOptions.updateColumns(cols);
 
-            _tryStopRefresh(paragraph);
-        };
+            paragraph.chartColumns = _.reduce(cols, (acc, col) => {
+                if (_notObjectType(col.fieldTypeName)) {
+                    acc.push({
+                        label: col.fieldName,
+                        type: col.fieldTypeName,
+                        aggFx: $scope.aggregateFxs[0],
+                        value: col.field
+                    });
+                }
 
-        function _chartNumber(arr, idx, dflt) {
-            if (idx >= 0 && arr && arr.length > idx && _.isNumber(arr[idx]))
-                return arr[idx];
+                return acc;
+            }, []);
 
-            return dflt;
-        }
+            if (paragraph.chartColumns.length > 0) {
+                paragraph.chartColumns.push(TIME_LINE);
+                paragraph.chartColumns.push(ROW_IDX);
+            }
 
-        function _chartLabel(arr, idx, dflt) {
-            if (arr && arr.length > idx && _.isString(arr[idx]))
-                return arr[idx];
+            // We could accept onl not object columns for X axis.
+            paragraph.chartKeyCols = _retainColumns(paragraph.chartColumns, paragraph.chartKeyCols, _notObjectType, true);
+
+            // We could accept only numeric columns for Y axis.
+            paragraph.chartValCols = _retainColumns(paragraph.chartColumns, paragraph.chartValCols, _numberType, false, paragraph.chartKeyCols);
+        };
+
+        $scope.toggleSystemColumns = function(paragraph) {
+            if (paragraph.disabledSystemColumns)
+                return;
+
+            paragraph.systemColumns = !paragraph.systemColumns;
 
-            return dflt;
-        }
+            paragraph.columnFilter = _columnFilter(paragraph);
 
-        function _min(rows, idx, dflt) {
-            var min = _chartNumber(rows[0], idx, dflt);
+            paragraph.chartColumns = [];
 
-            _.forEach(rows, function (row) {
-                var v = _chartNumber(row, idx, dflt);
+            _rebuildColumns(paragraph);
+        };
 
-                if (v < min)
-                    min = v;
-            });
+        const _showLoading = (paragraph, enable) => paragraph.loading = enable;
 
-            return min;
-        }
+        /**
+         * @param {Object} paragraph Query
+         * @param {{fieldsMetadata: Array, items: Array, queryId: int, last: Boolean}} res Query results.
+         * @private
+         */
+        const _processQueryResult = function(paragraph, res) {
+            const prevKeyCols = paragraph.chartKeyCols;
+            const prevValCols = paragraph.chartValCols;
 
-        function _max(rows, idx, dflt) {
-            var max = _chartNumber(rows[0], idx, dflt);
+            if (!_.eq(paragraph.meta, res.fieldsMetadata)) {
+                paragraph.meta = [];
 
-            _.forEach(rows, function (row) {
-                var v = _chartNumber(row, idx, dflt);
+                paragraph.chartColumns = [];
 
-                if (v > max)
-                    max = v;
-            });
+                if (!$common.isDefined(paragraph.chartKeyCols))
+                    paragraph.chartKeyCols = [];
 
-            return max;
-        }
+                if (!$common.isDefined(paragraph.chartValCols))
+                    paragraph.chartValCols = [];
 
-        function _sum(rows, idx) {
-            var sum = 0;
+                if (res.fieldsMetadata.length <= 2) {
+                    const _key = _.find(res.fieldsMetadata, {fieldName: '_KEY'});
+                    const _val = _.find(res.fieldsMetadata, {fieldName: '_VAL'});
 
-            _.forEach(rows, function (row) {
-                sum += _chartNumber(row, idx, 0);
-            });
+                    paragraph.disabledSystemColumns = (res.fieldsMetadata.length === 2 && _key && _val) ||
+                        (res.fieldsMetadata.length === 1 && (_key || _val));
+                }
 
-            return sum;
-        }
+                paragraph.columnFilter = _columnFilter(paragraph);
 
-        function _aggregate(rows, aggFx, idx, dflt) {
-            var len = rows.length;
+                paragraph.meta = res.fieldsMetadata;
 
-            switch (aggFx) {
-                case  'FIRST':
-                    return _chartNumber(rows[0], idx, dflt);
+                _rebuildColumns(paragraph);
+            }
 
-                case 'LAST':
-                    return _chartNumber(rows[len - 1], idx, dflt);
+            paragraph.page = 1;
 
-                case 'MIN':
-                    return _min(rows, idx, dflt);
+            paragraph.total = 0;
 
-                case 'MAX':
-                    return _max(rows, idx, dflt);
+            paragraph.queryId = res.last ? null : res.queryId;
 
-                case 'SUM':
-                    return _sum(rows, idx);
+            delete paragraph.errMsg;
 
-                case 'AVG':
-                    return len > 0 ? _sum(rows, idx) / len : 0;
+            // Prepare explain results for display in table.
+            if (paragraph.queryArgs.query && paragraph.queryArgs.query.startsWith('EXPLAIN') && res.items) {
+                paragraph.rows = [];
 
-                case 'COUNT':
-                    return len;
+                res.items.forEach(function(row, i) {
+                    const line = res.items.length - 1 === i ? row[0] : row[0] + '\n';
+
+                    line.replace(/\"/g, '').split('\n').forEach((ln) => paragraph.rows.push([ln]));
+                });
             }
+            else
+                paragraph.rows = res.items;
 
-            return 0;
-        }
+            paragraph.gridOptions.updateRows(paragraph.rows);
 
-        function _chartDatum(paragraph) {
-            var datum = [];
+            const chartHistory = paragraph.chartHistory;
 
-            if (paragraph.chartColumnsConfigured()) {
-                paragraph.chartValCols.forEach(function (valCol) {
-                    var index = 0;
-                    var values = [];
-                    var colIdx = valCol.value;
+            // Clear history on query change.
+            const queryChanged = paragraph.prevQuery !== paragraph.query;
 
-                    if (paragraph.chartTimeLineEnabled()) {
-                        var aggFx = valCol.aggFx;
-                        var colLbl = valCol.label + ' [' + aggFx + ']';
+            if (queryChanged) {
+                paragraph.prevQuery = paragraph.query;
 
-                        if (paragraph.charts && paragraph.charts.length == 1)
-                            datum = paragraph.charts[0].data;
+                chartHistory.length = 0;
 
-                        var chartData = _.find(datum, {series: valCol.label});
+                _.forEach(paragraph.charts, (chart) => chart.data.length = 0);
+            }
 
-                        var leftBound = new Date();
-                        leftBound.setMinutes(leftBound.getMinutes() - parseInt(paragraph.timeLineSpan));
+            // Add results to history.
+            chartHistory.push({tm: new Date(), rows: paragraph.rows});
 
-                        if (chartData) {
-                            var lastItem = _.last(paragraph.chartHistory);
+            // Keep history size no more than max length.
+            while (chartHistory.length > HISTORY_LENGTH)
+                chartHistory.shift();
 
-                            values = chartData.values;
+            _showLoading(paragraph, false);
 
-                            values.push({
-                                x: lastItem.tm,
-                                y: _aggregate(lastItem.rows, aggFx, colIdx, index++)
-                            });
+            if (paragraph.result === 'none' || !paragraph.queryExecuted())
+                paragraph.result = 'table';
+            else if (paragraph.chart()) {
+                let resetCharts = queryChanged;
 
-                            while (values.length > 0 && values[0].x < leftBound)
-                                values.shift();
-                        }
-                        else {
-                            _.forEach(paragraph.chartHistory, function (history) {
-                                if (history.tm >= leftBound)
-                                    values.push({
-                                        x: history.tm,
-                                        y: _aggregate(history.rows, aggFx, colIdx, index++)
-                                    });
-                            });
+                if (!resetCharts) {
+                    const curKeyCols = paragraph.chartKeyCols;
+                    const curValCols = paragraph.chartValCols;
 
-                            datum.push({series: valCol.label, key: colLbl, values: values});
-                        }
-                    }
-                    else {
-                        index = paragraph.total;
+                    resetCharts = !prevKeyCols || !prevValCols ||
+                        prevKeyCols.length !== curKeyCols.length ||
+                        prevValCols.length !== curValCols.length;
+                }
 
-                        values = _.map(paragraph.rows, function (row) {
-                            var xCol = paragraph.chartKeyCols[0].value;
+                _chartApplySettings(paragraph, resetCharts);
+            }
+        };
 
-                            var v = {
-                                x: _chartNumber(row, xCol, index),
-                                xLbl: _chartLabel(row, xCol, undefined),
-                                y: _chartNumber(row, colIdx, index)
-                            };
+        const _closeOldQuery = (paragraph) => {
+            const queryId = paragraph.queryArgs && paragraph.queryArgs.queryId;
 
-                            index++;
+            return queryId ? agentMonitor.queryClose(queryId) : $q.when();
+        };
 
-                            return v;
-                        });
+        const _executeRefresh = (paragraph) => {
+            const args = paragraph.queryArgs;
 
-                        datum.push({series: valCol.label, key: valCol.label, values: values});
-                    }
-                });
-            }
+            agentMonitor.awaitAgent()
+                .then(() => _closeOldQuery(paragraph))
+                .then(() => agentMonitor.query(args.cacheName, args.pageSize, args.query))
+                .then(_processQueryResult.bind(this, paragraph))
+                .catch((err) => paragraph.errMsg = err.message);
+        };
 
-            return datum;
-        }
+        const _tryStartRefresh = function(paragraph) {
+            _tryStopRefresh(paragraph);
 
-        function _pieChartDatum(paragraph) {
-            var datum = [];
+            if (paragraph.rate && paragraph.rate.installed && paragraph.queryArgs) {
+                $scope.chartAcceptKeyColumn(paragraph, TIME_LINE);
 
-            if (paragraph.chartColumnsConfigured() && !paragraph.chartTimeLineEnabled()) {
-                paragraph.chartValCols.forEach(function (valCol) {
-                    var index = paragraph.total;
+                _executeRefresh(paragraph);
 
-                    var values = _.map(paragraph.rows, function (row) {
-                        var xCol = paragraph.chartKeyCols[0].value;
+                const delay = paragraph.rate.value * paragraph.rate.unit;
 
-                        var v = {
-                            x: xCol < 0 ? index : row[xCol],
-                            y: _chartNumber(row, valCol.value, index)
-                        };
+                paragraph.rate.stopTime = $interval(_executeRefresh, delay, 0, false, paragraph);
+            }
+        };
 
-                        index++;
+        $scope.execute = function(paragraph) {
+            QueryNotebooks.save($scope.notebook)
+                .catch(_handleException);
 
-                        return v;
-                    });
+            paragraph.prevQuery = paragraph.queryArgs ? paragraph.queryArgs.query : paragraph.query;
 
-                    datum.push({series: paragraph.chartKeyCols[0].label, key: valCol.label, values: values});
-                });
-            }
+            _showLoading(paragraph, true);
 
-            return datum;
-        }
+            _closeOldQuery(paragraph)
+                .then(function() {
+                    const args = paragraph.queryArgs = {
+                        cacheName: paragraph.cacheName,
+                        pageSize: paragraph.pageSize,
+                        query: paragraph.query
+                    };
 
-        $scope.paragraphTimeSpanVisible = function (paragraph) {
-            return paragraph.timeLineSupported() && paragraph.chartTimeLineEnabled();
-        };
+                    return agentMonitor.query(args.cacheName, args.pageSize, args.query);
+                })
+                .then(function(res) {
+                    _processQueryResult(paragraph, res);
 
-        $scope.paragraphTimeLineSpan = function (paragraph) {
-          if (paragraph && paragraph.timeLineSpan)
-            return paragraph.timeLineSpan.toString();
+                    _tryStartRefresh(paragraph);
+                })
+                .catch((err) => {
+                    paragraph.errMsg = err.message;
 
-            return '1';
-        };
+                    _showLoading(paragraph, false);
 
-        function _saveChartSettings(paragraph) {
-            if (!_.isEmpty(paragraph.charts)) {
-                var chart = paragraph.charts[0].api.getScope().chart;
+                    $scope.stopRefresh(paragraph);
+                })
+                .finally(() => paragraph.ace.focus());
+        };
 
-                if (!$common.isDefined(paragraph.chartsOptions))
-                    paragraph.chartsOptions = {barChart: {stacked: true}, areaChart: {style: 'stack'}};
+        $scope.queryExecuted = function(paragraph) {
+            return $common.isDefined(paragraph.queryArgs);
+        };
 
-                switch (paragraph.result) {
-                    case 'bar':
-                        paragraph.chartsOptions.barChart.stacked = chart.stacked();
+        const _cancelRefresh = function(paragraph) {
+            if (paragraph.rate && paragraph.rate.stopTime) {
+                delete paragraph.queryArgs;
 
-                        break;
+                paragraph.rate.installed = false;
 
-                    case 'area':
-                        paragraph.chartsOptions.areaChart.style = chart.style();
+                $interval.cancel(paragraph.rate.stopTime);
 
-                        break;
-                }
+                delete paragraph.rate.stopTime;
             }
-        }
+        };
 
-        function _chartApplySettings(paragraph, resetCharts) {
-            if (resetCharts)
-                paragraph.charts = [];
+        $scope.explain = function(paragraph) {
+            QueryNotebooks.save($scope.notebook)
+                .catch(_handleException);
 
-            if (paragraph.chart() && paragraph.nonEmpty()) {
-                switch (paragraph.result) {
-                    case 'bar':
-                        _barChart(paragraph);
-                        break;
+            _cancelRefresh(paragraph);
 
-                    case 'pie':
-                        _pieChart(paragraph);
-                        break;
+            _showLoading(paragraph, true);
 
-                    case 'line':
-                        _lineChart(paragraph);
-                        break;
+            _closeOldQuery(paragraph)
+                .then(function() {
+                    const args = paragraph.queryArgs = {
+                        cacheName: paragraph.cacheName,
+                        pageSize: paragraph.pageSize,
+                        query: 'EXPLAIN ' + paragraph.query
+                    };
 
-                    case 'area':
-                        _areaChart(paragraph);
-                        break;
-                }
-            }
-        }
+                    return agentMonitor.query(args.cacheName, args.pageSize, args.query);
+                })
+                .then(_processQueryResult.bind(this, paragraph))
+                .catch((err) => {
+                    paragraph.errMsg = err.message;
 
-        $scope.applyChartSettings = function (paragraph) {
-            _chartApplySettings(paragraph, true);
+                    _showLoading(paragraph, false);
+                })
+                .finally(() => paragraph.ace.focus());
         };
 
-        function _xAxisLabel(paragraph) {
-            return _.isEmpty(paragraph.chartKeyCols) ? 'X' : paragraph.chartKeyCols[0].label;
-        }
+        $scope.scan = function(paragraph) {
+            QueryNotebooks.save($scope.notebook)
+                .catch(_handleException);
+
+            _cancelRefresh(paragraph);
+
+            _showLoading(paragraph, true);
+
+            _closeOldQuery(paragraph)
+                .then(() => {
+                    const args = paragraph.queryArgs = {
+                        cacheName: paragraph.cacheName,
+                        pageSize: paragraph.pageSize
+                    };
 
-        function _yAxisLabel(paragraph) {
-            var cols = paragraph.chartValCols;
+                    return agentMonitor.query(args.cacheName, args.pageSize);
+                })
+                .then(_processQueryResult.bind(this, paragraph))
+                .catch((err) => {
+                    paragraph.errMsg = err.message;
 
-            var tml = paragraph.chartTimeLineEnabled();
+                    _showLoading(paragraph, false);
+                })
+                .finally(() => paragraph.ace.focus());
+        };
 
-            return _.isEmpty(cols) ? 'Y' : _.map(cols, function (col) {
-                var lbl = col.label;
+        function _updatePieChartsWithData(paragraph, newDatum) {
+            $timeout(() => {
+                _.forEach(paragraph.charts, function(chart) {
+                    const chartDatum = chart.data;
 
-                if (tml)
-                 lbl += ' [' + col.aggFx + ']';
+                    chartDatum.length = 0;
 
-                return lbl;
-            }).join(', ');
-        }
+                    _.forEach(newDatum, function(series) {
+                        if (chart.options.title.text === series.key)
+                            _.forEach(series.values, (v) => chartDatum.push(v));
+                    });
+                });
 
-        function _xX(d) {
-            return d.x;
+                _.forEach(paragraph.charts, (chart) => chart.api.update());
+            });
         }
 
-        function _yY(d) {
-            return d.y;
-        }
+        $scope.nextPage = function(paragraph) {
+            _showLoading(paragraph, true);
 
-        function _xAxisTimeFormat(d) {
-            return d3.time.format('%X')(new Date(d));
-        }
+            paragraph.queryArgs.pageSize = paragraph.pageSize;
 
-        var _xAxisWithLabelFormat = function(paragraph) {
-            return function (d) {
-                var values = paragraph.charts[0].data[0].values;
+            agentMonitor.next(paragraph.queryId, paragraph.pageSize)
+                .then(function(res) {
+                    paragraph.page++;
 
-                var fmt = _intType(paragraph.chartKeyCols[0].type) ? 'd' : ',.2f';
+                    paragraph.total += paragraph.rows.length;
 
-                var dx = values[d];
+                    paragraph.rows = res.items;
 
-                if (!dx)
-                    return d3.format(fmt)(d);
+                    if (paragraph.chart()) {
+                        if (paragraph.result === 'pie')
+                            _updatePieChartsWithData(paragraph, _pieChartDatum(paragraph));
+                        else
+                            _updateChartsWithData(paragraph, _chartDatum(paragraph));
+                    }
 
-                var lbl = dx.xLbl;
+                    paragraph.gridOptions.updateRows(paragraph.rows);
 
-                return lbl ? lbl : d3.format(fmt)(d);
-            }
-        };
+                    _showLoading(paragraph, false);
 
-        var _yAxisFormat = function(d) {
-            var fmt = d < 1000 ? ',.2f' : '.3s';
+                    if (res.last)
+                        delete paragraph.queryId;
+                })
+                .catch((err) => {
+                    paragraph.errMsg = err.message;
 
-            return d3.format(fmt)(d);
+                    _showLoading(paragraph, false);
+                })
+                .finally(() => paragraph.ace.focus());
         };
 
-        function _updateCharts(paragraph) {
-            $timeout(function () {
-                _.forEach(paragraph.charts, function (chart) {
-                    chart.api.update();
-                });
-            }, 100);
-        }
+        const _export = (fileName, columnFilter, meta, rows) =>

<TRUNCATED>

[24/50] [abbrv] ignite git commit: IGNITE-3113: CPP: Binary containers documentation. This closes #711.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/transactions/transaction.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/transactions/transaction.h b/modules/platforms/cpp/core/include/ignite/transactions/transaction.h
index f68470e..b51a42c 100644
--- a/modules/platforms/cpp/core/include/ignite/transactions/transaction.h
+++ b/modules/platforms/cpp/core/include/ignite/transactions/transaction.h
@@ -24,7 +24,6 @@
 #define _IGNITE_TRANSACTIONS_TRANSACTION
 
 #include <ignite/common/concurrent.h>
-#include <ignite/jni/java.h>
 
 #include "ignite/impl/transactions/transaction_impl.h"
 #include "ignite/transactions/transaction_consts.h"
@@ -34,13 +33,26 @@ namespace ignite
     namespace transactions
     {
         /**
-         * Transaction.
+         * %Ignite cache transaction.
+         * Cache transactions have a default 2PC (two-phase-commit) behavior.
+         *
+         * @see TransactionConcurrency and TransactionIsolation for details on
+         * the supported isolation levels and concurrency models.
+         *
+         * This class implemented as a reference to an implementation so copying
+         * of this class instance will only create another reference to the same
+         * underlying object. Underlying object released automatically once all
+         * the instances are destructed.
          */
         class IGNITE_FRIEND_EXPORT Transaction
         {
         public:
             /**
              * Constructor.
+             *
+             * Internal method. Should not be used by user.
+             *
+             * @param impl Implementation.
              */
             Transaction(common::concurrent::SharedPointer<impl::transactions::TransactionImpl> impl);
 
@@ -66,36 +78,60 @@ namespace ignite
 
             /**
              * Commit the transaction.
+             *
+             * This method should only be used on the valid instance.
+             *
+             * @throw IgniteError class instance in case of failure.
              */
             void Commit();
 
             /**
              * Commit the transaction.
              *
+             * Properly sets error param in case of failure.
+             *
+             * This method should only be used on the valid instance.
+             *
              * @param err Error.
              */
             void Commit(IgniteError& err);
 
             /**
              * Rollback the transaction.
+             *
+             * This method should only be used on the valid instance.
+             *
+             * @throw IgniteError class instance in case of failure.
              */
             void Rollback();
 
             /**
              * Rollback the transaction.
              *
+             * Properly sets error param in case of failure.
+             *
+             * This method should only be used on the valid instance.
+             *
              * @param err Error.
              */
             void Rollback(IgniteError& err);
 
             /**
              * Close the transaction.
+             *
+             * This method should only be used on the valid instance.
+             *
+             * @throw IgniteError class instance in case of failure.
              */
             void Close();
 
             /**
              * Close the transaction.
              *
+             * Properly sets error param in case of failure.
+             *
+             * This method should only be used on the valid instance.
+             *
              * @param err Error.
              */
             void Close(IgniteError& err);
@@ -106,6 +142,10 @@ namespace ignite
              * After transaction have been marked as rollback-only it may
              * only be rolled back. Error occurs if such transaction is
              * being commited.
+             *
+             * This method should only be used on the valid instance.
+             *
+             * @throw IgniteError class instance in case of failure.
              */
             void SetRollbackOnly();
 
@@ -116,6 +156,10 @@ namespace ignite
              * only be rolled back. Error occurs if such transaction is
              * being commited.
              *
+             * Properly sets error param in case of failure.
+             *
+             * This method should only be used on the valid instance.
+             *
              * @param err Error.
              */
             void SetRollbackOnly(IgniteError& err);
@@ -128,6 +172,8 @@ namespace ignite
              * being commited.
              *
              * @return True if the transaction is rollback-only.
+             *
+             * @throw IgniteError class instance in case of failure.
              */
             bool IsRollbackOnly();
 
@@ -138,6 +184,10 @@ namespace ignite
              * only be rolled back. Error occurs if such transaction is
              * being commited.
              *
+             * Properly sets error param in case of failure.
+             *
+             * This method should only be used on the valid instance.
+             *
              * @param err Error.
              * @return True if the transaction is rollback-only.
              */
@@ -146,13 +196,21 @@ namespace ignite
             /**
              * Get current state.
              *
+             * This method should only be used on the valid instance.
+             *
              * @return Transaction state.
+             *
+             * @throw IgniteError class instance in case of failure.
              */
             TransactionState GetState();
 
             /**
              * Get current state.
              *
+             * Properly sets error param in case of failure.
+             *
+             * This method should only be used on the valid instance.
+             *
              * @param err Error.
              * @return Transaction state.
              */
@@ -161,6 +219,8 @@ namespace ignite
             /**
              * Get concurrency.
              *
+             * This method should only be used on the valid instance.
+             *
              * @return Concurrency.
              */
             TransactionConcurrency GetConcurrency() const
@@ -171,6 +231,8 @@ namespace ignite
             /**
              * Get isolation.
              *
+             * This method should only be used on the valid instance.
+             *
              * @return Isolation.
              */
             TransactionIsolation GetIsolation() const
@@ -181,6 +243,8 @@ namespace ignite
             /**
              * Get timeout.
              *
+             * This method should only be used on the valid instance.
+             *
              * @return Timeout in milliseconds. Zero if timeout is infinite.
              */
             int64_t GetTimeout() const

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/transactions/transaction_consts.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/transactions/transaction_consts.h b/modules/platforms/cpp/core/include/ignite/transactions/transaction_consts.h
index 5799b9f..8b25d3a 100644
--- a/modules/platforms/cpp/core/include/ignite/transactions/transaction_consts.h
+++ b/modules/platforms/cpp/core/include/ignite/transactions/transaction_consts.h
@@ -17,7 +17,7 @@
 
 /**
  * @file
- * Declares ignite::transactions::TransactionState enumeration.
+ * Declares Transaction-related enumerations.
  */
 
 #ifndef _IGNITE_TRANSACTIONS_TRANSACTION_CONSTS
@@ -28,14 +28,37 @@ namespace ignite
     namespace transactions
     {
         /**
-         * Transaction concurrency control.
+         * Transaction concurrency control model.
          */
         enum TransactionConcurrency
         {
-            /** Optimistic concurrency control. */
+            /**
+             * Optimistic concurrency model. In this mode all cache operations
+             * are not distributed to other nodes until Transaction::Commit()
+             * is called. In this mode one @c 'PREPARE' message will be sent to
+             * participating cache nodes to start acquiring per-transaction
+             * locks, and once all nodes reply @c 'OK', a one-way @c 'COMMIT'
+             * message is sent without waiting for reply.
+             *
+             * Note that in this mode, optimistic failures are only possible in
+             * conjunction with ::IGNITE_TX_ISOLATION_SERIALIZABLE isolation 
+             * level. In all other cases, optimistic transactions will never
+             * fail optimistically and will always be identically ordered on all
+             * participating grid nodes.
+             */
             IGNITE_TX_CONCURRENCY_OPTIMISTIC = 0,
 
-            /** Pessimistic concurrency control. */
+            /**
+             * Pessimistic concurrency model. In this mode a lock is acquired
+             * on all cache operations with exception of read operations in
+             * ::IGNITE_TX_ISOLATION_READ_COMMITTED mode. All optional filters
+             * passed into cache operations will be evaluated after successful
+             * lock acquisition. Whenever Transaction::Commit() is called, a
+             * single one-way @c 'COMMIT' message is sent to participating cache
+             * nodes without waiting for reply. Note that there is no reason for
+             * distributed @c 'PREPARE' step, as all locks have been already
+             * acquired.
+             */
             IGNITE_TX_CONCURRENCY_PESSIMISTIC = 1
         };
 
@@ -44,13 +67,42 @@ namespace ignite
          */
         enum TransactionIsolation
         {
-            /** Read committed isolation level. */
+            /**
+             * Read committed isolation level. This isolation level means that
+             * always a committed value will be provided for read operations.
+             * With this isolation level values are always read from cache
+             * global memory or persistent store every time a value is accessed.
+             * In other words, if the same key is accessed more than once within
+             * the same transaction, it may have different value every time
+             * since global cache memory may be updated concurrently by other
+             * threads.
+             */
             IGNITE_TX_ISOLATION_READ_COMMITTED = 0,
 
-            /** Repeatable read isolation level. */
+            /**
+             * Repeatable read isolation level. This isolation level means that
+             * if a value was read once within transaction, then all consecutive
+             * reads will provide the same in-transaction value. With this
+             * isolation level accessed values are stored within in-transaction
+             * memory, so consecutive access to the same key within the same
+             * transaction will always return the value that was previously read
+             * or updated within this transaction. If concurrency is
+             * ::IGNITE_TX_CONCURRENCY_PESSIMISTIC, then a lock on the key will
+             * be acquired prior to accessing the value.
+             */
             IGNITE_TX_ISOLATION_REPEATABLE_READ = 1,
 
-            /** Serializable isolation level. */
+            /**
+             * Serializable isolation level. This isolation level means that all
+             * transactions occur in a completely isolated fashion, as if all
+             * transactions in the system had executed serially, one after the
+             * other. Read access with this level happens the same way as with
+             * ::IGNITE_TX_ISOLATION_REPEATABLE_READ level. However, in
+             * ::IGNITE_TX_CONCURRENCY_OPTIMISTIC mode, if some transactions
+             * cannot be serially isolated from each other, then one winner will
+             * be picked and the other transactions in conflict will result in
+             * IgniteError being thrown.
+             */
             IGNITE_TX_ISOLATION_SERIALIZABLE = 2
         };
 
@@ -59,31 +111,31 @@ namespace ignite
          */
         enum TransactionState
         {
-            /** Transaction started. */
+            /** %Transaction started. */
             IGNITE_TX_STATE_ACTIVE,
 
-            /** Transaction validating. */
+            /** %Transaction validating. */
             IGNITE_TX_STATE_PREPARING,
 
-            /** Transaction validation succeeded. */
+            /** %Transaction validation succeeded. */
             IGNITE_TX_STATE_PREPARED,
 
-            /** Transaction is marked for rollback. */
+            /** %Transaction is marked for rollback. */
             IGNITE_TX_STATE_MARKED_ROLLBACK,
 
-            /** Transaction commit started (validating finished). */
+            /** %Transaction commit started (validating finished). */
             IGNITE_TX_STATE_COMMITTING,
 
-            /** Transaction commit succeeded. */
+            /** %Transaction commit succeeded. */
             IGNITE_TX_STATE_COMMITTED,
 
-            /** Transaction rollback started (validation failed). */
+            /** %Transaction rollback started (validation failed). */
             IGNITE_TX_STATE_ROLLING_BACK,
 
-            /** Transaction rollback succeeded. */
+            /** %Transaction rollback succeeded. */
             IGNITE_TX_STATE_ROLLED_BACK,
 
-            /** Transaction rollback failed or is otherwise unknown state. */
+            /** %Transaction rollback failed or is otherwise unknown state. */
             IGNITE_TX_STATE_UNKNOWN
         };
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/transactions/transaction_metrics.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/transactions/transaction_metrics.h b/modules/platforms/cpp/core/include/ignite/transactions/transaction_metrics.h
index 4986a64..00ebd10 100644
--- a/modules/platforms/cpp/core/include/ignite/transactions/transaction_metrics.h
+++ b/modules/platforms/cpp/core/include/ignite/transactions/transaction_metrics.h
@@ -32,13 +32,15 @@ namespace ignite
     namespace transactions
     {
         /**
-         * Transaction metrics.
+         * %Transaction metrics, shared across all caches.
          */
         class IGNITE_IMPORT_EXPORT TransactionMetrics
         {
         public:
             /**
              * Default constructor.
+             *
+             * Constructed instance is not valid.
              */
             TransactionMetrics() :
                 valid(false),
@@ -71,6 +73,8 @@ namespace ignite
 
             /**
              * Copy constructor.
+             *
+             * @param other Another instance.
              */
             TransactionMetrics(const TransactionMetrics& other) :
                 valid(other.valid),
@@ -84,6 +88,9 @@ namespace ignite
 
             /**
              * Assignment operator.
+             *
+             * @param other Another instance.
+             * @return @c *this.
              */
             TransactionMetrics& operator=(const TransactionMetrics& other)
             {
@@ -105,7 +112,7 @@ namespace ignite
             {
                 return commitTime;
             }
-            
+
             /**
              * Get rollback time.
              *
@@ -145,7 +152,7 @@ namespace ignite
              * in case of error. Invalid instances also often can be
              * created using default constructor.
              *
-             * @return True if the instance contains valid data.
+             * @return @c true if the instance contains valid data.
              */
             bool IsValid() const
             {

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/transactions/transactions.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/transactions/transactions.h b/modules/platforms/cpp/core/include/ignite/transactions/transactions.h
index 130116a..98282bd 100644
--- a/modules/platforms/cpp/core/include/ignite/transactions/transactions.h
+++ b/modules/platforms/cpp/core/include/ignite/transactions/transactions.h
@@ -35,13 +35,22 @@ namespace ignite
     namespace transactions
     {
         /**
-         * Transactions.
+         * %Transactions facade.
+         *
+         * This class implemented as a reference to an implementation so copying
+         * of this class instance will only create another reference to the same
+         * underlying object. Underlying object released automatically once all
+         * the instances are destructed.
          */
         class IGNITE_FRIEND_EXPORT Transactions
         {
         public:
             /**
              * Constructor.
+             *
+             * Internal method. Should not be used by user.
+             *
+             * @param impl Implementation.
              */
             Transactions(ignite::common::concurrent::SharedPointer<impl::transactions::TransactionsImpl> impl);
 
@@ -75,14 +84,16 @@ namespace ignite
             Transaction GetTx();
 
             /**
-             * Start new transaction.
+             * Start new transaction with default isolation, concurrency
+             * and timeout.
              *
              * @return New transaction instance.
              */
             Transaction TxStart();
 
             /**
-             * Start new transaction.
+             * Start new transaction with default isolation, concurrency
+             * and timeout.
              *
              * @param err Error.
              * @return New transaction instance.
@@ -90,7 +101,8 @@ namespace ignite
             Transaction TxStart(IgniteError& err);
 
             /**
-             * Start new transaction.
+             * Starts new transaction with the specified concurrency and
+             * isolation.
              *
              * @param concurrency Concurrency.
              * @param isolation Isolation.
@@ -100,7 +112,8 @@ namespace ignite
                 TransactionIsolation isolation);
 
             /**
-             * Start new transaction.
+             * Starts new transaction with the specified concurrency and
+             * isolation.
              *
              * @param concurrency Concurrency.
              * @param isolation Isolation.
@@ -111,12 +124,14 @@ namespace ignite
                 TransactionIsolation isolation, IgniteError& err);
 
             /**
-             * Start new transaction.
+             * Starts transaction with specified isolation, concurrency,
+             * timeout, and number of participating entries.
              *
              * @param concurrency Concurrency.
              * @param isolation Isolation.
              * @param timeout Timeout. Zero if for infinite timeout.
-             * @param txSize Number of entries participating in transaction (may be approximate).
+             * @param txSize Number of entries participating in transaction
+             *     (may be approximate).
              * @return New transaction instance.
              */
             Transaction TxStart(TransactionConcurrency concurrency,
@@ -129,7 +144,8 @@ namespace ignite
              * @param concurrency Concurrency.
              * @param isolation Isolation.
              * @param timeout Timeout. Zero if for infinite timeout.
-             * @param txSize Number of entries participating in transaction (may be approximate).
+             * @param txSize Number of entries participating in transaction
+             *     (may be approximate).
              * @param err Error.
              * @return New transaction instance.
              */
@@ -138,14 +154,14 @@ namespace ignite
                 int32_t txSize, IgniteError& err);
 
             /**
-             * Get metrics.
+             * Get transaction metrics.
              *
              * @return Metrics instance.
              */
             TransactionMetrics GetMetrics();
 
             /**
-             * Get metrics.
+             * Get transaction metrics.
              *
              * @param err Error.
              * @return Metrics instance.

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/namespaces.dox
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/namespaces.dox b/modules/platforms/cpp/core/namespaces.dox
index 20aa5ba..0f5f11f 100644
--- a/modules/platforms/cpp/core/namespaces.dox
+++ b/modules/platforms/cpp/core/namespaces.dox
@@ -37,7 +37,7 @@
 	 }
 
 	 /**
-	  * %Ignite Transaction API.
+	  * %Ignite %Transaction API.
 	  */
 	 namespace transactions
 	 {

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/cpp.dxg
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/cpp.dxg b/modules/platforms/cpp/cpp.dxg
index 605a613..d25d978 100644
--- a/modules/platforms/cpp/cpp.dxg
+++ b/modules/platforms/cpp/cpp.dxg
@@ -1715,8 +1715,8 @@ GENERATE_LEGEND        = YES
 
 DOT_CLEANUP            = YES
 
-;INPUT=core binary
-;EXCLUDE=core/include/ignite/impl core/os/linux/include/ignite/impl core/os/linux/src/impl core/os/win/include/ignite/impl core/os/win/src/impl core/src/impl binary/include/ignite/impl binary/src/impl
+;INPUT=core binary common
+;EXCLUDE=core/include/ignite/impl core/os/linux/include/ignite/impl core/os/linux/src/impl core/os/win/include/ignite/impl core/os/win/src/impl core/src/impl binary/include/ignite/impl binary/src/impl common/include/ignite/common common/os
 ;STRIP_FROM_PATH=core/include/ignite core/src binary/include/ignite binary/src
 ;OUTPUT_DIRECTORY=../../clients/target/cppdoc
 ;PROJECT_LOGO=../../../assembly/docfiles/ignite_logo.png


[16/50] [abbrv] ignite git commit: IGNITE-3152 Client node's addresses are registered in IP finder

Posted by sb...@apache.org.
IGNITE-3152 Client node's addresses are registered in IP finder


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8ce29a92
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8ce29a92
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8ce29a92

Branch: refs/heads/ignite-1232
Commit: 8ce29a92d5e06d5a3d68aae0f6a2865ffd21a28c
Parents: 5177c33
Author: Anton Vinogradov <av...@apache.org>
Authored: Wed Jun 22 12:43:05 2016 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Wed Jun 22 12:58:10 2016 +0300

----------------------------------------------------------------------
 .../ignite/spi/discovery/tcp/ServerImpl.java    |  2 +-
 .../vm/TcpDiscoveryVmIpFinderSelfTest.java      | 75 ++++++++++++++++++++
 2 files changed, 76 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8ce29a92/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
index 38ed671..b1c56c0 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
@@ -4035,7 +4035,7 @@ class ServerImpl extends TcpDiscoveryImpl {
                     notifyDiscovery(EVT_NODE_JOINED, topVer, node);
 
                 try {
-                    if (spi.ipFinder.isShared() && locNodeCoord)
+                    if (spi.ipFinder.isShared() && locNodeCoord && !node.isClient())
                         spi.ipFinder.registerAddresses(node.socketAddresses());
                 }
                 catch (IgniteSpiException e) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ce29a92/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/vm/TcpDiscoveryVmIpFinderSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/vm/TcpDiscoveryVmIpFinderSelfTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/vm/TcpDiscoveryVmIpFinderSelfTest.java
index 86587ba..aa00007 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/vm/TcpDiscoveryVmIpFinderSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/vm/TcpDiscoveryVmIpFinderSelfTest.java
@@ -19,8 +19,16 @@ package org.apache.ignite.spi.discovery.tcp.ipfinder.vm;
 
 import java.util.Arrays;
 import java.util.Collections;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.lang.GridAbsPredicate;
+import org.apache.ignite.internal.util.typedef.G;
 import org.apache.ignite.spi.IgniteSpiException;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinderAbstractSelfTest;
+import org.apache.ignite.testframework.GridTestUtils;
+
+import static org.apache.ignite.internal.processors.cache.binary.GridCacheBinaryObjectsAbstractSelfTest.IP_FINDER;
 
 /**
  * GridTcpDiscoveryVmIpFinder test.
@@ -190,4 +198,71 @@ public class TcpDiscoveryVmIpFinderSelfTest
         assertEquals("Registered addresses: " + finder.getRegisteredAddresses().toString(),
             10, finder.getRegisteredAddresses().size());
     }
+
+    /**
+     *
+     */
+    public void testUnregistration() throws Exception {
+        Ignition.start(config("server1", false, false));
+
+        int srvSize = IP_FINDER.getRegisteredAddresses().size();
+
+        Ignition.start(config("server2", false, false));
+        Ignition.start(config("client1", true, false));
+
+        assertEquals(2 * srvSize, IP_FINDER.getRegisteredAddresses().size());
+
+        Ignition.start(config("client2", true, false));
+        Ignition.start(config("client3", true, false));
+
+        assertEquals(2 * srvSize, IP_FINDER.getRegisteredAddresses().size());
+
+        Ignition.start(config("client4", true, true));
+
+        assertEquals(3 * srvSize, IP_FINDER.getRegisteredAddresses().size());
+
+        Ignition.stop("client1", true);
+        Ignition.stop("client2", true);
+
+        assertEquals(3 * srvSize, IP_FINDER.getRegisteredAddresses().size());
+
+        Ignition.stop("client4", true);
+
+        GridTestUtils.waitForCondition(new GridAbsPredicate() {
+            @Override public boolean apply() {
+                return 2 == G.allGrids().size();
+            }
+        }, 10000);
+
+        Ignition.stop("server1", true);
+        Ignition.stop("server2", true);
+
+        GridTestUtils.waitForCondition(new GridAbsPredicate() {
+            @Override public boolean apply() {
+                return 0 == G.allGrids().size();
+            }
+        }, 10000);
+
+        assertTrue(3 * srvSize >= IP_FINDER.getRegisteredAddresses().size());
+    }
+
+    /**
+     * @param name Name.
+     * @param client Client.
+     */
+    private static IgniteConfiguration config(String name, boolean client, boolean forceServerMode) {
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        cfg.setGridName(name);
+        cfg.setClientMode(client);
+
+        TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+        disco.setForceServerMode(forceServerMode);
+        disco.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(disco);
+
+        return cfg;
+    }
 }
\ No newline at end of file


[43/50] [abbrv] ignite git commit: Ignite Web Console beta2.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/caches/store.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/caches/store.jade b/modules/web-console/src/main/js/app/modules/states/configuration/caches/store.jade
index d4f698e..cb26d03 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/caches/store.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/caches/store.jade
@@ -20,7 +20,7 @@ include ../../../../../app/helpers/jade/mixins.jade
 -var model = 'backupItem'
 
 //- Mixin for DB dialect.
-mixin dialect(lbl, model, name, tipTitle, genericDialectName, placeholder)
+mixin dialect(lbl, model, name, required, tipTitle, genericDialectName, placeholder)
     ignite-form-field
         ignite-form-field-label
             | #{lbl}
@@ -46,7 +46,7 @@ mixin dialect(lbl, model, name, tipTitle, genericDialectName, placeholder)
                 {value: "H2", label: "H2 database"}\
             ]'
             data-ng-model=model
-            data-ng-required='true'
+            data-ng-required=required
             data-placeholder=placeholder
         )
 
@@ -60,7 +60,7 @@ mixin hibernateField(items, field, valid, save, newItem)
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
     ignite-form-field-input-text(
-        data-name=field
+        data-name='#{field}{{ $index || "" }}'
         data-ng-model=field
         data-ng-required='true'
         data-placeholder='key=value'
@@ -96,22 +96,23 @@ form.panel.panel-default(name=form novalidate)
                         ]',
                         'Factory for persistent storage for cache data'
                     )
-                    span(ng-if=storeFactoryKind ng-init='__.expanded = true')
+                    span(ng-show=storeFactoryKind ng-init='__.expanded = true')
                         a.customize(ng-show='__.expanded' ng-click='__.expanded = false') Hide settings
                         a.customize(ng-hide='__.expanded' ng-click='__.expanded = true') Show settings
-                        .panel-details(ng-if='__.expanded')
-                            div(ng-if='#{storeFactoryKind} === "CacheJdbcPojoStoreFactory"')
+                        .panel-details(ng-show='__.expanded')
+                            div(ng-show='#{storeFactoryKind} === "CacheJdbcPojoStoreFactory"')
                                 -var pojoStoreFactory = storeFactory + '.CacheJdbcPojoStoreFactory'
+                                -var required = storeFactoryKind + ' === "CacheJdbcPojoStoreFactory"'
 
                                 .details-row
                                     +text('Data source bean name:', pojoStoreFactory + '.dataSourceBean',
-                                        'pojoDataSourceBean', 'true', 'Input bean name',
+                                        'pojoDataSourceBean', required, 'Input bean name',
                                         'Name of the data source bean in Spring context')
                                 .details-row
-                                    +dialect('Dialect:', pojoStoreFactory + '.dialect', 'pojoDialect',
+                                    +dialect('Dialect:', pojoStoreFactory + '.dialect', 'pojoDialect', required,
                                         'Dialect of SQL implemented by a particular RDBMS:', 'Generic JDBC dialect',
                                         'Choose JDBC dialect')
-                            div(ng-if='#{storeFactoryKind} === "CacheJdbcBlobStoreFactory"')
+                            div(ng-show='#{storeFactoryKind} === "CacheJdbcBlobStoreFactory"')
                                 -var blobStoreFactory = storeFactory + '.CacheJdbcBlobStoreFactory'
                                 -var blobStoreFactoryVia = blobStoreFactory + '.connectVia'
 
@@ -126,20 +127,24 @@ form.panel.panel-default(name=form novalidate)
                                             <li>JDBC URL, for example: jdbc:h2:mem:myDatabase</li>\
                                             <li>Configured data source</li>\
                                         </ul>')
-                                div(ng-if='#{blobStoreFactoryVia} === "URL"')
+                                div(ng-show='#{blobStoreFactoryVia} === "URL"')
+                                    -var required = storeFactoryKind + ' === "CacheJdbcBlobStoreFactory" && ' + blobStoreFactoryVia + ' === "URL"'
+
                                     .details-row
-                                        +text('Connection URL:', blobStoreFactory + '.connectionUrl', 'connectionUrl', 'true', 'Input URL',
+                                        +text('Connection URL:', blobStoreFactory + '.connectionUrl', 'connectionUrl', required, 'Input URL',
                                             'URL for database access, for example: jdbc:h2:mem:myDatabase')
                                     .details-row
-                                        +text('User:', blobStoreFactory + '.user', 'user', 'true', 'Input user name', 'User name for database access')
+                                        +text('User:', blobStoreFactory + '.user', 'user', required, 'Input user name', 'User name for database access')
                                     .details-row
                                         label Note, password will be generated as stub
-                                div(ng-if='#{blobStoreFactoryVia} !== "URL"')
+                                div(ng-show='#{blobStoreFactoryVia} !== "URL"')
+                                    -var required = storeFactoryKind + ' === "CacheJdbcBlobStoreFactory" && ' + blobStoreFactoryVia + '!== "URL"'
+
                                     .details-row
-                                        +text('Data source bean name:', blobStoreFactory + '.dataSourceBean', 'blobDataSourceBean', 'true', 'Input bean name',
+                                        +text('Data source bean name:', blobStoreFactory + '.dataSourceBean', 'blobDataSourceBean', required, 'Input bean name',
                                             'Name of the data source bean in Spring context')
                                     .details-row
-                                        +dialect('Database:', blobStoreFactory + '.dialect', 'blobDialect', 'Supported databases:', 'Generic database', 'Choose database')
+                                        +dialect('Database:', blobStoreFactory + '.dialect', 'blobDialect', required, 'Supported databases:', 'Generic database', 'Choose database')
                                 .details-row
                                     +checkbox('Init schema', blobStoreFactory + '.initSchema', 'initSchema',
                                         'Flag indicating whether DB schema should be initialized by Ignite (default behaviour) or was explicitly created by user')
@@ -164,7 +169,7 @@ form.panel.panel-default(name=form novalidate)
                                         'Query for delete entry from underlying database<br/>\
                                         Default value: delete from ENTRIES where key=?')
 
-                            div(ng-if='#{storeFactoryKind} === "CacheHibernateBlobStoreFactory"')
+                            div(ng-show='#{storeFactoryKind} === "CacheHibernateBlobStoreFactory"')
                                 -var hibernateStoreFactory = storeFactory + '.CacheHibernateBlobStoreFactory'
                                 -var hibernateProperties = hibernateStoreFactory + '.hibernateProperties'
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/attributes.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/attributes.directive.js b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/attributes.directive.js
new file mode 100644
index 0000000..cc9d474
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/attributes.directive.js
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+import template from './attributes.jade!';
+
+export default ['igniteConfigurationUserAttributes', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/attributes.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/attributes.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/attributes.jade
new file mode 100644
index 0000000..e6ffd50
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/attributes.jade
@@ -0,0 +1,58 @@
+//-
+    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.
+
+include ../../../../../app/helpers/jade/mixins.jade
+
+-var form = 'attributes'
+-var model = 'backupItem'
+-var types = model + '.typeConfigurations'
+-var userAttributes = model + '.attributes'
+
+form.panel.panel-default(name=form novalidate)
+    .panel-heading(bs-collapse-toggle ng-click='ui.loadPanel("#{form}")')
+        ignite-form-panel-chevron
+        label User attributes
+        ignite-form-field-tooltip.tipLabel
+            | Configuration for Ignite user attributes
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
+        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
+            .col-sm-6
+                .settings-row
+                    ignite-form-group(ng-model='#{userAttributes}' ng-form='#{form}')
+                        ignite-form-field-label
+                            | User attributes
+                        ignite-form-group-tooltip
+                            | User-defined attributes to add to node
+                        ignite-form-group-add(ng-click='tableNewItem(attributesTbl)')
+                            | Add user attribute
+                        .group-content-empty(ng-if='!((#{userAttributes} && #{userAttributes}.length > 0) || tableNewItemActive(attributesTbl))')
+                            | Not defined
+                        .group-content(ng-show='(#{userAttributes} && #{userAttributes}.length > 0) || tableNewItemActive(attributesTbl)')
+                            table.links-edit(id='attributes' st-table=userAttributes)
+                                tbody
+                                    tr(ng-repeat='item in #{userAttributes}')
+                                        td.col-sm-12(ng-show='!tableEditing(attributesTbl, $index)')
+                                            a.labelFormField(ng-click='tableStartEdit(backupItem, attributesTbl, $index)') {{item.name}} = {{item.value}}
+                                            +btn-remove('tableRemove(backupItem, attributesTbl, $index)', '"Remove attribute"')
+                                        td.col-sm-12(ng-show='tableEditing(attributesTbl, $index)')
+                                            +table-pair-edit('attributesTbl', 'cur', 'Attribute name', 'Attribute value', false, false, '{{::attributesTbl.focusId + $index}}', '$index', '=')
+                                tfoot(ng-show='tableNewItemActive(attributesTbl)')
+                                    tr
+                                        td.col-sm-12
+                                            +table-pair-edit('attributesTbl', 'new', 'Attribute name', 'Attribute value', false, false, '{{::attributesTbl.focusId + $index}}', '-1', '=')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterUserAttributes')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/binary.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/binary.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/binary.jade
index 37e7559..77caa36 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/binary.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/binary.jade
@@ -79,20 +79,20 @@ form.panel.panel-default(name=form novalidate)
                             | Add new type configuration.
                         .group-content-empty(ng-if='!#{types}.length')
                             | Not defined
-                        .group-content(ng-repeat='type in #{types} track by $index')
+                        .group-content(ng-repeat='model in #{types} track by $index')
                             hr(ng-if='$index !== 0')
                             .settings-row
-                                +binary-types-java-class('Type name:', 'type.typeName', '"typeName" + $index', 'true', 'true', true, 'true', 'Type name')
+                                +binary-types-java-class('Type name:', 'model.typeName', '"typeName" + $index', 'true', 'true', true, 'true', 'Type name')
                             .settings-row
-                                +binary-types-java-class('ID mapper:', 'type.idMapper', '"idMapper" + $index', 'true', 'false', false, 'false',
+                                +binary-types-java-class('ID mapper:', 'model.idMapper', '"idMapper" + $index', 'true', 'false', false, 'false',
                                     'Maps given from BinaryNameMapper type and filed name to ID that will be used by Ignite in internals<br/>\
                                     Ignite never writes full strings for field or type/class names. Instead, for performance reasons, Ignite writes integer hash codes for type/class and field names. It has been tested that hash code conflicts for the type/class names or the field names within the same type are virtually non - existent and, to gain performance, it is safe to work with hash codes. For the cases when hash codes for different types or fields actually do collide #[b BinaryIdMapper] allows to override the automatically generated hash code IDs for the type and field names')
                             .settings-row
-                                +binary-types-java-class('Name mapper:', 'type.nameMapper', '"nameMapper" + $index', 'true', 'false', false, 'false', 'Maps type/class and field names to different names')
+                                +binary-types-java-class('Name mapper:', 'model.nameMapper', '"nameMapper" + $index', 'true', 'false', false, 'false', 'Maps type/class and field names to different names')
                             .settings-row
-                                +binary-types-java-class('Serializer:', 'type.serializer', '"serializer" + $index', 'true', 'false', false, 'false', 'Class with custom serialization logic for binary object')
+                                +binary-types-java-class('Serializer:', 'model.serializer', '"serializer" + $index', 'true', 'false', false, 'false', 'Class with custom serialization logic for binary object')
                             .settings-row
-                                +checkbox('Enum', 'type.enum', 'enum', 'Flag indicating that this type is the enum')
+                                +checkbox('Enum', 'model.enum', 'enum', 'Flag indicating that this type is the enum')
 
                 .settings-row
                     +checkbox('Compact footer', model + '.compactFooter', 'compactFooter', 'When enabled, Ignite will not write fields metadata when serializing objects(this will increase serialization performance), because internally #[b BinaryMarshaller] already distribute metadata inside cluster')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision.directive.js b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision.directive.js
new file mode 100644
index 0000000..624056e
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision.directive.js
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+import template from './collision.jade!';
+
+export default ['igniteConfigurationClustersCollision', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision.jade
new file mode 100644
index 0000000..10e51f0
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision.jade
@@ -0,0 +1,60 @@
+//-
+    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.
+
+include ../../../../../app/helpers/jade/mixins.jade
+
+-var form = 'collision'
+-var model = 'backupItem.collision'
+
+form.panel.panel-default(name=form novalidate)
+    .panel-heading(bs-collapse-toggle ng-click='ui.loadPanel("#{form}")')
+        ignite-form-panel-chevron
+        label Collision configuration
+        ignite-form-field-tooltip.tipLabel
+            | Configuration Collision SPI allows to regulate how grid jobs get executed when they arrive on a destination node for execution
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
+        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
+            .col-sm-6
+                .settings-row
+                    +dropdown('CollisionSpi:', model + '.kind', 'collision', 'true', '',
+                        '[\
+                            {value: "JobStealing", label: "Job stealing"},\
+                            {value: "FifoQueue", label: "FIFO queue"},\
+                            {value: "PriorityQueue", label: "Priority queue"},\
+                            {value: "Custom", label: "Custom"},\
+                            {value: "Noop", label: "Default"}\
+                        ]',
+                        'Regulate how grid jobs get executed when they arrive on a destination node for execution\
+                        <ul>\
+                            <li>Job stealing - supports job stealing from over-utilized nodes to under-utilized nodes</li>\
+                            <li>FIFO queue - jobs are ordered as they arrived</li>\
+                            <li>Priority queue - jobs are first ordered by their priority</li>\
+                            <li>Custom - custom CollisionSpi implementation</li>\
+                            <li>Default - jobs are activated immediately on arrival to mapped node</li>\
+                        </ul>')
+                .settings-row(ng-show='#{model}.kind !== "Noop"')
+                    .panel-details
+                        ignite-configuration-clusters-collision-job-stealing(
+                            ng-show='#{model}.kind === "JobStealing"')
+                        ignite-configuration-clusters-collision-fifo-queue(
+                            ng-show='#{model}.kind === "FifoQueue"')
+                        ignite-configuration-clusters-collision-priority-queue(
+                            ng-show='#{model}.kind === "PriorityQueue"')
+                        ignite-configuration-clusters-collision-custom(
+                            ng-show='#{model}.kind === "Custom"')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterCollision')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/custom.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/custom.directive.js b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/custom.directive.js
new file mode 100644
index 0000000..9a8d414
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/custom.directive.js
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+import template from './custom.jade!';
+
+export default ['igniteConfigurationClustersCollisionCustom', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/custom.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/custom.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/custom.jade
new file mode 100644
index 0000000..b666f54
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/custom.jade
@@ -0,0 +1,24 @@
+//-
+    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.
+
+include ../../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem.collision.Custom'
+-var required = 'backupItem.collision.kind === "Custom"'
+
+div
+    .details-row
+        +java-class('Class:', model + '.class', 'collisionCustom', 'true', required, 'CollisionSpi implementation class')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/fifo-queue.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/fifo-queue.directive.js b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/fifo-queue.directive.js
new file mode 100644
index 0000000..240c98a
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/fifo-queue.directive.js
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+import template from './fifo-queue.jade!';
+
+export default ['igniteConfigurationClustersCollisionFifoQueue', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/fifo-queue.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/fifo-queue.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/fifo-queue.jade
new file mode 100644
index 0000000..9c9d315
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/fifo-queue.jade
@@ -0,0 +1,28 @@
+//-
+    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.
+
+include ../../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem.collision.FifoQueue'
+-var form = 'collisionFifoQueue'
+
+div
+    .details-row
+        +number('Parallel jobs number:', model + '.parallelJobsNumber', 'fifoParallelJobsNumber', 'true', 'availableProcessors * 2', '1',
+            'Number of jobs that can be executed in parallel')
+    .details-row
+        +number('Wait jobs number:', model + '.waitingJobsNumber', 'fifoWaitingJobsNumber', 'true', 'Integer.MAX_VALUE', '0',
+            'Maximum number of jobs that are allowed to wait in waiting queue')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/job-stealing.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/job-stealing.directive.js b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/job-stealing.directive.js
new file mode 100644
index 0000000..3c187d1
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/job-stealing.directive.js
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+import template from './job-stealing.jade!';
+
+export default ['igniteConfigurationClustersCollisionJobStealing', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/job-stealing.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/job-stealing.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/job-stealing.jade
new file mode 100644
index 0000000..17392c0
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/job-stealing.jade
@@ -0,0 +1,64 @@
+//-
+    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.
+
+include ../../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem.collision.JobStealing'
+-var form = 'collisionJobStealing'
+-var stealingAttributes = model + '.stealingAttributes'
+
+div
+    .details-row
+        +number('Active jobs threshold:', model + '.activeJobsThreshold', 'jsActiveJobsThreshold', 'true', '95', '0',
+            'Number of jobs that can be executed in parallel')
+    .details-row
+        +number('Wait jobs threshold:', model + '.waitJobsThreshold', 'jsWaitJobsThreshold', 'true', '0', '0',
+            'Job count threshold at which this node will start stealing jobs from other nodes')
+    .details-row
+        +number('Message expire time:', model + '.messageExpireTime', 'jsMessageExpireTime', 'true', '1000', '1',
+            'Message expire time in ms')
+    .details-row
+        +number('Maximum stealing attempts:', model + '.maximumStealingAttempts', 'jsMaximumStealingAttempts', 'true', '5', '1',
+            'Maximum number of attempts to steal job by another node')
+    .details-row
+        +checkbox('Stealing enabled', model + '.stealingEnabled', 'jsStealingEnabled',
+            'Node should attempt to steal jobs from other nodes')
+    .details-row
+        +java-class('External listener:', model + '.externalCollisionListener', 'jsExternalCollisionListener', 'true', 'false',
+            'Listener to be set for notification of external collision events')
+    .details-row
+        ignite-form-group(ng-model='#{stealingAttributes}' ng-form='#{form}')
+            ignite-form-field-label
+                | Stealing attributes
+            ignite-form-group-tooltip
+                | Configuration parameter to enable stealing to/from only nodes that have these attributes set
+            ignite-form-group-add(ng-click='tableNewItem(stealingAttributesTbl)')
+                | Add stealing attribute
+            .group-content-empty(ng-if='!((#{stealingAttributes} && #{stealingAttributes}.length > 0) || tableNewItemActive(stealingAttributesTbl))')
+                | Not defined
+            .group-content(ng-show='(#{stealingAttributes} && #{stealingAttributes}.length > 0) || tableNewItemActive(stealingAttributesTbl)')
+                table.links-edit(id='attributes' st-table=stealingAttributes)
+                    tbody
+                        tr(ng-repeat='item in #{stealingAttributes}')
+                            td.col-sm-12(ng-show='!tableEditing(stealingAttributesTbl, $index)')
+                                a.labelFormField(ng-click='tableStartEdit(backupItem, stealingAttributesTbl, $index)') {{item.name}} = {{item.value}}
+                                +btn-remove('tableRemove(backupItem, stealingAttributesTbl, $index)', '"Remove attribute"')
+                            td.col-sm-12(ng-show='tableEditing(stealingAttributesTbl, $index)')
+                                +table-pair-edit('stealingAttributesTbl', 'cur', 'Attribute name', 'Attribute value', false, false, '{{::stealingAttributesTbl.focusId + $index}}', '$index', '=')
+                    tfoot(ng-show='tableNewItemActive(stealingAttributesTbl)')
+                        tr
+                            td.col-sm-12
+                                +table-pair-edit('stealingAttributesTbl', 'new', 'Attribute name', 'Attribute value', false, false, '{{::stealingAttributesTbl.focusId + $index}}', '-1', '=')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/priority-queue.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/priority-queue.directive.js b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/priority-queue.directive.js
new file mode 100644
index 0000000..e7e8798
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/priority-queue.directive.js
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+import template from './priority-queue.jade!';
+
+export default ['igniteConfigurationClustersCollisionPriorityQueue', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/priority-queue.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/priority-queue.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/priority-queue.jade
new file mode 100644
index 0000000..208c12b
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/collision/priority-queue.jade
@@ -0,0 +1,43 @@
+//-
+    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.
+
+include ../../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem.collision.PriorityQueue'
+-var form = 'collisionPriorityQueue'
+
+div
+    .details-row
+        +number('Parallel jobs number:', model + '.parallelJobsNumber', 'priorityParallelJobsNumber', 'true', 'availableProcessors * 2', '1',
+            'Number of jobs that can be executed in parallel')
+    .details-row
+        +number('Waiting jobs number:', model + '.waitingJobsNumber', 'priorityWaitingJobsNumber', 'true', 'Integer.MAX_VALUE', '0',
+            'Maximum number of jobs that are allowed to wait in waiting queue')
+    .details-row
+        +text('Priority attribute key:', model + '.priorityAttributeKey', 'priorityPriorityAttributeKey', 'false', 'grid.task.priority',
+            'Task priority attribute key')
+    .details-row
+        +text('Job priority attribute key:', model + '.jobPriorityAttributeKey', 'priorityJobPriorityAttributeKey', 'false', 'grid.job.priority',
+            'Job priority attribute key')
+    .details-row
+        +number('Default priority:', model + '.defaultPriority', 'priorityDefaultPriority', 'true', '0', '0',
+            'Default priority to use if a job does not have priority attribute set')
+    .details-row
+        +number('Starvation increment:', model + '.starvationIncrement', 'priorityStarvationIncrement', 'true', '1', '0',
+            'Value to increment job priority by every time a lower priority job gets behind a higher priority job')
+    .details-row
+        +checkbox('Starvation prevention enabled', model + '.starvationPreventionEnabled', 'priorityStarvationPreventionEnabled',
+            'Job starvation prevention is enabled')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/communication.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/communication.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/communication.jade
index 5d8ed10..7073f27 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/communication.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/communication.jade
@@ -41,7 +41,7 @@ form.panel.panel-default(name=form novalidate)
                 .settings-row
                     +java-class('Communication listener:', communication + '.listener', 'comListener', 'true', 'false', 'Communication listener')
                 .settings-row
-                    +text-ip-address('Local IP address:', communication + '.localAddress', 'comLocalAddress', 'true', '228.1.2.4', 'Local host address for socket binding')
+                    +text-ip-address('Local IP address:', communication + '.localAddress', 'comLocalAddress', 'true', '0.0.0.0', 'Local host address for socket binding')
                 .settings-row
                     +number-min-max('Local port:', communication + '.localPort', 'comLocalPort', 'true', '47100', '1024', '65535', 'Local port for socket binding')
                 .settings-row
@@ -51,12 +51,6 @@ form.panel.panel-default(name=form novalidate)
                         'Local port to accept shared memory connections<br/>\
                         If set to #[b -1] shared memory communication will be disabled')
                 .settings-row
-                    +checkbox('Direct buffer', communication + '.directBuffer', 'directBuffer',
-                        'If value is true, then SPI will use ByteBuffer.allocateDirect(int) call<br/>\
-                        Otherwise, SPI will use ByteBuffer.allocate(int) call.')
-                .settings-row
-                    +checkbox('Direct send buffer', communication + '.directSendBuffer', 'directSendBuffer', 'Flag defining whether direct send buffer should be used')
-                .settings-row
                     +number('Idle connection timeout:', communication + '.idleConnectionTimeout', 'idleConnectionTimeout', 'true', '30000', '1',
                         'Maximum idle connection timeout upon which a connection to client will be closed')
                 .settings-row
@@ -71,20 +65,32 @@ form.panel.panel-default(name=form novalidate)
                 .settings-row
                     +number('Socket receive buffer:', communication + '.socketReceiveBuffer', 'socketReceiveBuffer', 'true', '32768', '0', 'Receive buffer size for sockets created or accepted by this SPI')
                 .settings-row
-                    +number('Message queue limit:', communication + '.messageQueueLimit', 'messageQueueLimit', 'true', '1024', '0', 'Message queue limit for incoming and outgoing messages')
-                .settings-row
                     +number('Slow client queue limit:', communication + '.slowClientQueueLimit', 'slowClientQueueLimit', 'true', '0', '0', 'Slow client queue limit')
                 .settings-row
-                    +checkbox('TCP_NODELAY option', communication + '.tcpNoDelay', 'tcpNoDelay', 'Value for TCP_NODELAY socket option')
-                .settings-row
                     +number('Ack send threshold:', communication + '.ackSendThreshold', 'ackSendThreshold', 'true', '16', '1', 'Number of received messages per connection to node after which acknowledgment message is sent')
                 .settings-row
-                    +number('Unacknowledged messages:', communication + '.unacknowledgedMessagesBufferSize', 'unacknowledgedMessagesBufferSize', 'true', '0', '0', 'Maximum number of stored unacknowledged messages per connection to node')
+                    +number('Message queue limit:', communication + '.messageQueueLimit', 'messageQueueLimit', 'true', '1024', '0', 'Message queue limit for incoming and outgoing messages')
+                .settings-row
+                    +number('Unacknowledged messages:', communication + '.unacknowledgedMessagesBufferSize', 'unacknowledgedMessagesBufferSize', 'true', '0', '0',
+                        'Maximum number of stored unacknowledged messages per connection to node<br/>\
+                        If specified non zero value it should be\
+                        <ul>\
+                            <li>At least ack send threshold * 5</li>\
+                            <li>At least message queue limit * 5</li>\
+                        </ul>')
                 .settings-row
                     +number('Socket write timeout:', communication + '.socketWriteTimeout', 'socketWriteTimeout', 'true', '2000', '0', 'Socket write timeout')
                 .settings-row
                     +number('Selectors count:', communication + '.selectorsCount', 'selectorsCount', 'true', 'min(4, availableProcessors)', '1', 'Count of selectors te be used in TCP server')
                 .settings-row
                     +java-class('Address resolver:', communication + '.addressResolver', 'comAddressResolver', 'true', 'false', 'Address resolver')
+                .settings-row
+                    +checkbox('Direct buffer', communication + '.directBuffer', 'directBuffer',
+                    'If value is true, then SPI will use ByteBuffer.allocateDirect(int) call<br/>\
+                    Otherwise, SPI will use ByteBuffer.allocate(int) call.')
+                .settings-row
+                    +checkbox('Direct send buffer', communication + '.directSendBuffer', 'directSendBuffer', 'Flag defining whether direct send buffer should be used')
+                .settings-row
+                    +checkbox('TCP_NODELAY option', communication + '.tcpNoDelay', 'tcpNoDelay', 'Value for TCP_NODELAY socket option')
             .col-sm-6
                 +preview-xml-java(model, 'clusterCommunication')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/deployment.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/deployment.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/deployment.jade
index b2f1fb9..98e7f61 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/deployment.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/deployment.jade
@@ -77,18 +77,25 @@ form.panel.panel-default(name='deployment' novalidate)
                             -var javaKeywords = 'form[ngModelName].$error.javaKeywords'
                             -var save = exclude + '[$index] = ' + field
 
-                            ignite-form-field(ng-repeat='model in #{exclude} track by $index' type='internal' name='Package name')
-                                .indexField
-                                    | {{ $index+1 }})
-                                +table-remove-button(exclude, 'Remove package name')
-                                span(ng-hide='field.edit')
-                                    a.labelFormField(ng-click='#{enabled} && (field.edit = true)') {{ model }}
-                                span(ng-if='field.edit' ng-init='#{field} = model')
-                                    +table-java-package-field(field, exclude, valid, save, false)
-                                        +table-save-button(valid, save, false)
-                                        +unique-feedback(unique, uniqueTip)
-                                        +error-feedback(javaPackageName, 'javaPackageName', tipJavaPackageName)
-                                        +error-feedback(javaKeywords, 'javaKeywords', tipJavaKeyWord)
+                            div(ng-show=enabled)
+                                ignite-form-field(ng-repeat='model in #{exclude} track by $index' type='internal' name='Package name')
+                                    .indexField
+                                        | {{ $index+1 }})
+                                    +table-remove-button(exclude, 'Remove package name')
+                                    span(ng-hide='field.edit')
+                                        a.labelFormField(ng-click='#{enabled} && (field.edit = true)') {{ model }}
+                                    span(ng-if='field.edit' ng-init='#{field} = model')
+                                        +table-java-package-field(field, exclude, valid, save, false)
+                                            +table-save-button(valid, save, false)
+                                            +unique-feedback(unique, uniqueTip)
+                                            +error-feedback(javaPackageName, 'javaPackageName', tipJavaPackageName)
+                                            +error-feedback(javaKeywords, 'javaKeywords', tipJavaKeyWord)
+                            div(ng-hide=enabled)
+                                ignite-form-field(ng-repeat='model in #{exclude} track by $index' type='internal' name='Package name')
+                                    .labelFormField.labelField
+                                        | {{ $index+1 }})
+                                    span.labelFormField
+                                        | {{ model }}
 
                         .group-content(ng-repeat='field in group.add')
                             -var field = 'new'

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/discovery.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/discovery.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/discovery.jade
index d1ee763..15b7065 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/discovery.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/discovery.jade
@@ -47,7 +47,9 @@ form.panel.panel-default(name=form novalidate)
                 .settings-row
                     +number('Network timeout:', model + '.networkTimeout', 'discoNetworkTimeout', 'true', '5000', '1', 'Network timeout')
                 .settings-row
-                    +number('Join timeout:', model + '.joinTimeout', 'joinTimeout', 'true', '0', '0', 'Join timeout')
+                    +number('Join timeout:', model + '.joinTimeout', 'joinTimeout', 'true', '0', '0',
+                        'Join timeout<br/>' +
+                        '0 means wait forever')
                 .settings-row
                     +number('Thread priority:', model + '.threadPriority', 'threadPriority', 'true', '10', '1', 'Thread priority for all threads started by SPI')
                 .settings-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/failover.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/failover.directive.js b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/failover.directive.js
new file mode 100644
index 0000000..98335a7
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/failover.directive.js
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+import template from './failover.jade!';
+
+export default ['igniteConfigurationClustersFailover', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/failover.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/failover.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/failover.jade
new file mode 100644
index 0000000..a973aeb
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/failover.jade
@@ -0,0 +1,82 @@
+//-
+    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.
+
+include ../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem'
+-var form = 'failoverSpi'
+-var failoverSpi = model + '.failoverSpi'
+-var failoverCustom = 'failover.kind === "Custom"'
+
+form.panel.panel-default(name=form novalidate)
+    .panel-heading(bs-collapse-toggle ng-click='ui.loadPanel("#{form}")')
+        ignite-form-panel-chevron
+        label Failover configuration
+        ignite-form-field-tooltip.tipLabel
+            | Failover SPI provides ability to supply custom logic for handling failed execution of a grid job
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
+        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
+            .col-sm-6
+                .settings-row(ng-init='failoverSpiTbl={type: "failoverSpi", model: "failoverSpi", focusId: "kind", ui: "failover-table"}')
+                    ignite-form-group(ng-model='#{failoverSpi}' ng-form=form)
+                        ignite-form-field-label
+                            | Failover SPI configurations
+                        ignite-form-group-tooltip
+                            | Failover SPI configurations
+                        ignite-form-group-add(ng-click='tableNewItem(failoverSpiTbl)')
+                            | Add failover SPI
+                        .group-content-empty(ng-if='!(#{failoverSpi} && #{failoverSpi}.length > 0)')
+                            | Not defined
+                        .group-content(ng-show='#{failoverSpi} && #{failoverSpi}.length > 0' ng-repeat='failover in #{failoverSpi} track by $index')
+                            hr(ng-if='$index != 0')
+                            .settings-row
+                                ignite-form-field
+                                    ignite-form-field-label
+                                        | Failover SPI
+                                    i.tipField.fa.fa-remove(bs-tooltip='"Remove Failover SPI"' ng-click='removeFailoverConfiguration($index)')
+                                    ignite-form-field-tooltip
+                                        | Provides ability to supply custom logic for handling failed execution of a grid job
+                                        ul
+                                            li Job stealing - Supports job stealing from over-utilized nodes to under-utilized nodes
+                                            li Never - Jobs are ordered as they arrived
+                                            li Always - Jobs are first ordered by their priority
+                                            li Custom - Jobs are activated immediately on arrival to mapped node
+                                            li Default - Default FailoverSpi implementation
+                                    ignite-form-field-dropdown(
+                                        data-id='failoverKind{{$index}}'
+                                        data-name='failoverKind{{$index}}'
+                                        data-options='[\
+                                            {value: "JobStealing", label: "Job stealing"},\
+                                            {value: "Never", label: "Never"},\
+                                            {value: "Always", label: "Always"},\
+                                            {value: "Custom", label: "Custom"}\
+                                        ]'
+                                        data-ng-model='failover.kind'
+                                        data-ng-required='true'
+                                        data-placeholder='Choose Failover SPI'
+                                    )
+                            .settings-row(ng-show='failover.kind === "JobStealing"')
+                                +number('Maximum failover attempts:', 'failover.JobStealing.maximumFailoverAttempts', 'jsMaximumFailoverAttempts{{$index}}', 'true', '5', '0',
+                                    'Maximum number of attempts to execute a failed job on another node')
+                            .settings-row(ng-show='failover.kind === "Always"')
+                                +number('Maximum failover attempts:', 'failover.Always.maximumFailoverAttempts', 'alwaysMaximumFailoverAttempts{{$index}}', 'true', '5', '0',
+                                    'Maximum number of attempts to execute a failed job on another node')
+                            .settings-row(ng-show=failoverCustom)
+                                +java-class('SPI implementation', 'failover.Custom.class', 'failoverSpiClass{{$index}}', 'true', failoverCustom,
+                                    'Custom FailoverSpi implementation class name.')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterFailover')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general.jade
index aea42d6..2ed0db0 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general.jade
@@ -30,9 +30,7 @@ form.panel.panel-default(name=form novalidate)
                 .settings-row
                     +text('Name:', model + '.name', 'clusterName', 'true', 'Input name', 'Grid name')
                 .settings-row
-                    +dropdown-multiple('<span>Caches:</span><a ui-sref="base.configuration.caches({id: ' + model + '._id})"> (add)</a>',
-                        model + '.caches', 'caches', 'true', 'Choose caches', 'No caches configured', 'caches',
-                        'Select caches to start in cluster or add a new cache')
+                    +caches(model, 'Select caches to start in cluster or add a new cache')
                 .settings-row
                     +text-ip-address('Local host:', model + '.localHost', 'localHost', 'true', '0.0.0.0', 'System-wide local address or host for all Ignite components to bind to')
                 .settings-row
@@ -51,20 +49,20 @@ form.panel.panel-default(name=form novalidate)
                 .settings-row
                     .panel-details
                         ignite-configuration-clusters-general-discovery-cloud(
-                            ng-if='#{model}.discovery.kind === "Cloud"')
+                            ng-show='#{model}.discovery.kind === "Cloud"')
                         ignite-configuration-clusters-general-discovery-google(
-                            ng-if='#{model}.discovery.kind === "GoogleStorage"')
+                            ng-show='#{model}.discovery.kind === "GoogleStorage"')
                         ignite-configuration-clusters-general-discovery-jdbc(
-                            ng-if='#{model}.discovery.kind === "Jdbc"')
+                            ng-show='#{model}.discovery.kind === "Jdbc"')
                         ignite-configuration-clusters-general-discovery-multicast(
-                            ng-if='#{model}.discovery.kind === "Multicast"')
+                            ng-show='#{model}.discovery.kind === "Multicast"')
                         ignite-configuration-clusters-general-discovery-s3(
-                            ng-if='#{model}.discovery.kind === "S3"')
+                            ng-show='#{model}.discovery.kind === "S3"')
                         ignite-configuration-clusters-general-discovery-shared(
-                            ng-if='#{model}.discovery.kind === "SharedFs"')
+                            ng-show='#{model}.discovery.kind === "SharedFs"')
                         ignite-configuration-clusters-general-discovery-vm(
-                            ng-if='#{model}.discovery.kind === "Vm"')
+                            ng-show='#{model}.discovery.kind === "Vm"')
                         ignite-configuration-clusters-general-discovery-zookeeper(
-                            ng-if='#{model}.discovery.kind === "ZooKeeper"')
+                            ng-show='#{model}.discovery.kind === "ZooKeeper"')
             .col-sm-6
                 +preview-xml-java(model, 'clusterCaches', 'caches')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
index 1f5ef16..3a6565d 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/cloud.jade
@@ -16,6 +16,8 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
+-var discoveryKind = 'Cloud'
+-var required = 'backupItem.discovery.kind == "' + discoveryKind + '"'
 -var model = 'backupItem.discovery.Cloud'
 -var regions = model + '.regions'
 -var zones = model + '.zones'
@@ -32,11 +34,11 @@ div
             'Path to a credential that is used during authentication on the cloud<br/>\
             Access key or private key should be stored in a plain or PEM file without a passphrase')
     .details-row
-        +text('Identity:', model + '.identity', 'identity', 'true', 'Input identity',
+        +text('Identity:', model + '.identity', discoveryKind + 'Identity', required, 'Input identity',
             'Identity that is used as a user name during a connection to the cloud<br/>\
             Depending on a cloud platform it can be an email address, user name, etc')
     .details-row
-        +text('Provider:', model + '.provider', 'provider', 'true', 'Input provider', 'Cloud provider to use')
+        +text('Provider:', model + '.provider', discoveryKind + 'Provider', required, 'Input provider', 'Cloud provider to use')
     .details-row
         ignite-form-group(ng-model=regions ng-form=formRegions)
             -var uniqueTip = 'Such region already exists!'

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade
index 54e4bb5..2a651df 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/google.jade
@@ -16,20 +16,23 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
+
+-var discoveryKind = 'GoogleStorage'
+-var required = 'backupItem.discovery.kind == "' + discoveryKind + '"'
 -var model = 'backupItem.discovery.GoogleStorage'
 
 div
     .details-row
-        +text('Project name:', model + '.projectName', 'projectName', 'true', 'Input project name', '' +
+        +text('Project name:', model + '.projectName', discoveryKind + 'ProjectName', required, 'Input project name', '' +
             'Google Cloud Platforms project name<br/>\
             Usually this is an auto generated project number(ex. 208709979073) that can be found in "Overview" section of Google Developer Console')
     .details-row
-        +text('Bucket name:', model + '.bucketName', 'bucketName', 'true', 'Input bucket name',
+        +text('Bucket name:', model + '.bucketName', discoveryKind + 'BucketName', required, 'Input bucket name',
             'Google Cloud Storage bucket name<br/>\
             If the bucket does not exist Ignite will automatically create it<br/>\
             However the name must be unique across whole Google Cloud Storage and Service Account Id must be authorized to perform this operation')
     .details-row
-        +text('Private key path:', model + '.serviceAccountP12FilePath', 'serviceAccountP12FilePath', 'true', 'Input private key path',
+        +text('Private key path:', model + '.serviceAccountP12FilePath', discoveryKind + 'ServiceAccountP12FilePath', required, 'Input private key path',
             'Full path to the private key in PKCS12 format of the Service Account')
     .details-row
-        +text('Account id:', model + '.serviceAccountId', 'serviceAccountId', 'true', 'Input account id', 'Service account ID (typically an e-mail address)')
+        +text('Account id:', model + '.serviceAccountId', discoveryKind + 'ServiceAccountId', required, 'Input account id', 'Service account ID (typically an e-mail address)')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade
index d693709..c2e29be 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/s3.jade
@@ -16,10 +16,12 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
+-var discoveryKind = 'S3'
+-var required = 'backupItem.discovery.kind == "' + discoveryKind + '"'
 -var model = 'backupItem.discovery.S3'
 
 div
     .details-row
-        +text('Bucket name:', model + '.bucketName', 'bucketName', 'true', 'Input bucket name', 'Bucket name for IP finder')
+        +text('Bucket name:', model + '.bucketName', discoveryKind + 'BucketName', required, 'Input bucket name', 'Bucket name for IP finder')
     .details-row
         label Note, AWS credentials will be generated as stub

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
index ad3dbea..72f0678 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
@@ -16,6 +16,8 @@
 
 include ../../../../../../../app/helpers/jade/mixins.jade
 
+-var discoveryKind = 'ZooKeeper'
+-var required = 'backupItem.discovery.kind == "' + discoveryKind + '"'
 -var model = 'backupItem.discovery.ZooKeeper'
 
 div
@@ -25,7 +27,7 @@ div
             By default generates curator of org.apache.curator. framework.imps.CuratorFrameworkImpl\
             class with configured connect string, retry policy, and default session and connection timeouts')
     .details-row
-        +text('Connect string:', model + '.zkConnectionString', 'zkConnectionString', 'true', 'host:port[chroot][,host:port[chroot]]',
+        +text('Connect string:', model + '.zkConnectionString', ZooKeeper + 'ConnectionString', required, 'host:port[chroot][,host:port[chroot]]',
             'When "IGNITE_ZK_CONNECTION_STRING" system property is not configured this property will be used')
     .details-row
         +dropdown('Retry policy:', model + '.retryPolicy.kind', 'retryPolicy', 'true', 'Default',
@@ -50,16 +52,15 @@ div
                 <li>Custom - custom retry policy implementation</li>\
                 <li>Default - exponential backoff retry policy with configured base sleep time equal to 1000ms and max retry count equal to 10</li>\
             </ul>')
-    .details-row(ng-if='#{model}.retryPolicy.kind')
+    .details-row(ng-show='#{model}.retryPolicy.kind')
         .panel-details
-            div(ng-switch='#{model}.retryPolicy.kind')
-                ignite-configuration-clusters-general-discovery-zookeeper-exponential(ng-switch-when='ExponentialBackoff')
-                ignite-configuration-clusters-general-discovery-zookeeper-bounded-exponential(ng-switch-when='BoundedExponentialBackoff')
-                ignite-configuration-clusters-general-discovery-zookeeper-until-elapsed(ng-switch-when='UntilElapsed')
-                ignite-configuration-clusters-general-discovery-zookeeper-n-times(ng-switch-when='NTimes')
-                ignite-configuration-clusters-general-discovery-zookeeper-one-time(ng-switch-when='OneTime')
-                ignite-configuration-clusters-general-discovery-zookeeper-forever(ng-switch-when='Forever')
-                ignite-configuration-clusters-general-discovery-zookeeper-custom(ng-switch-when='Custom')
+            ignite-configuration-clusters-general-discovery-zookeeper-exponential(ng-show='#{model}.retryPolicy.kind === "ExponentialBackoff"')
+            ignite-configuration-clusters-general-discovery-zookeeper-bounded-exponential(ng-show='#{model}.retryPolicy.kind === "BoundedExponentialBackoff"')
+            ignite-configuration-clusters-general-discovery-zookeeper-until-elapsed(ng-show='#{model}.retryPolicy.kind === "UntilElapsed"')
+            ignite-configuration-clusters-general-discovery-zookeeper-n-times(ng-show='#{model}.retryPolicy.kind === "NTimes"')
+            ignite-configuration-clusters-general-discovery-zookeeper-one-time(ng-show='#{model}.retryPolicy.kind === "OneTime"')
+            ignite-configuration-clusters-general-discovery-zookeeper-forever(ng-show='#{model}.retryPolicy.kind === "Forever"')
+            ignite-configuration-clusters-general-discovery-zookeeper-custom(ng-show='#{model}.retryPolicy.kind === "Custom"')
     .details-row
         +text('Base path:', model + '.basePath', 'basePath', 'false', '/services', 'Base path for service registration')
     .details-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
index f8f78f8..6f6e035 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
@@ -20,8 +20,8 @@ include ../../../../../../../../../app/helpers/jade/mixins.jade
 
 div
     .details-row
-        +number('Base interval:', model + '.baseSleepTimeMs', 'baseSleepTimeMs', 'true', '1000', '0', 'Initial amount of time in ms to wait between retries')
+        +number('Base interval:', model + '.baseSleepTimeMs', 'beBaseSleepTimeMs', 'true', '1000', '0', 'Initial amount of time in ms to wait between retries')
     .details-row
-        +number('Max interval:', model + '.maxSleepTimeMs', 'maxSleepTimeMs', 'true', 'Integer.MAX_VALUE', '0', 'Max time in ms to sleep on each retry')
+        +number('Max interval:', model + '.maxSleepTimeMs', 'beMaxSleepTimeMs', 'true', 'Integer.MAX_VALUE', '0', 'Max time in ms to sleep on each retry')
     .details-row
-        +number-min-max('Max retries:', model + '.maxRetries', 'maxRetries', 'true', '10', '0', '29', 'Max number of times to retry')
+        +number-min-max('Max retries:', model + '.maxRetries', 'beMaxRetries', 'true', '10', '0', '29', 'Max number of times to retry')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
index 8c55ad8..6e631ab 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
@@ -16,7 +16,9 @@
 
 include ../../../../../../../../../app/helpers/jade/mixins.jade
 
--var model = 'backupItem.discovery.ZooKeeper.retryPolicy.Custom'
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy'
+-var retry = model + '.Custom'
+-var required = 'backupItem.discovery.kind === "ZooKeeper" && backupItem.discovery.ZooKeeper.retryPolicy.kind === "Custom"'
 
 .details-row
-    +java-class('Class name:', model + '.className', 'className', 'true', 'true', 'Custom retry policy implementation class name')
+    +java-class('Class name:', retry + '.className', 'customClassName', 'true', required, 'Custom retry policy implementation class name')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
index b039335..9be2a71 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
@@ -20,8 +20,8 @@ include ../../../../../../../../../app/helpers/jade/mixins.jade
 
 div
     .details-row
-        +number('Base interval:', model + '.baseSleepTimeMs', 'baseSleepTimeMs', 'true', '1000', '0', 'Initial amount of time in ms to wait between retries')
+        +number('Base interval:', model + '.baseSleepTimeMs', 'expBaseSleepTimeMs', 'true', '1000', '0', 'Initial amount of time in ms to wait between retries')
     .details-row
-        +number-min-max('Max retries:', model + '.maxRetries', 'maxRetries', 'true', '10', '0', '29', 'Max number of times to retry')
+        +number-min-max('Max retries:', model + '.maxRetries', 'expMaxRetries', 'true', '10', '0', '29', 'Max number of times to retry')
     .details-row
-        +number('Max interval:', model + '.maxSleepMs', 'maxSleepMs', 'true', 'Integer.MAX_VALUE', '0', 'Max time in ms to sleep on each retry')
+        +number('Max interval:', model + '.maxSleepMs', 'expMaxSleepMs', 'true', 'Integer.MAX_VALUE', '0', 'Max time in ms to sleep on each retry')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
index 1d09caa..f4045eb 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
@@ -19,4 +19,4 @@ include ../../../../../../../../../app/helpers/jade/mixins.jade
 -var model = 'backupItem.discovery.ZooKeeper.retryPolicy.Forever'
 
 .details-row
-    +number('Interval:', model + '.retryIntervalMs', 'retryIntervalMs', 'true', '1000', '0', 'Time in ms between retry attempts')
+    +number('Interval:', model + '.retryIntervalMs', 'feRetryIntervalMs', 'true', '1000', '0', 'Time in ms between retry attempts')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
index 0b70f59..a4083b7 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
@@ -22,4 +22,4 @@ div
     .details-row
         +number('Retries:', model + '.n', 'n', 'true', '10', '0', 'Number of times to retry')
     .details-row
-        +number('Interval:', model + '.sleepMsBetweenRetries', 'sleepMsBetweenRetries', 'true', '1000', '0', 'Time in ms between retry attempts')
+        +number('Interval:', model + '.sleepMsBetweenRetries', 'ntSleepMsBetweenRetries', 'true', '1000', '0', 'Time in ms between retry attempts')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
index 8b9fa18..f259630 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
@@ -20,4 +20,4 @@ include ../../../../../../../../../app/helpers/jade/mixins.jade
 
 div
     .details-row
-        +number('Interval:', model + '.sleepMsBetweenRetry', 'sleepMsBetweenRetry', 'true', '1000', '0', 'Time in ms to retry attempt')
+        +number('Interval:', model + '.sleepMsBetweenRetry', 'oneSleepMsBetweenRetry', 'true', '1000', '0', 'Time in ms to retry attempt')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
index ad9f3c1..24a884e 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
@@ -20,6 +20,6 @@ include ../../../../../../../../../app/helpers/jade/mixins.jade
 
 div
     .details-row
-        +number('Total time:', model + '.maxElapsedTimeMs', 'maxElapsedTimeMs', 'true', '60000', '0', 'Total time in ms for execution of retry attempt')
+        +number('Total time:', model + '.maxElapsedTimeMs', 'ueMaxElapsedTimeMs', 'true', '60000', '0', 'Total time in ms for execution of retry attempt')
     .details-row
-        +number('Interval:', model + '.sleepMsBetweenRetries', 'sleepMsBetweenRetries', 'true', '1000', '0', 'Time in ms between retry attempts')
+        +number('Interval:', model + '.sleepMsBetweenRetries', 'ueSleepMsBetweenRetries', 'true', '1000', '0', 'Time in ms between retry attempts')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/igfs.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/igfs.jade b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/igfs.jade
index c76c66d..de20dfe 100644
--- a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/igfs.jade
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/igfs.jade
@@ -30,8 +30,8 @@ form.panel.panel-default(name=form novalidate)
         .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
             .col-sm-6
                 .settings-row
-                    +dropdown-multiple('<span>IGFS:</span><a ui-sref="base.configuration.igfs({id: ' + model + '._id})"> (add)</a>',
+                    +dropdown-multiple('<span>IGFS:</span><a ui-sref="base.configuration.igfs({linkId: linkId()})"> (add)</a>',
                         model + '.igfss', 'igfss', 'true', 'Choose IGFS', 'No IGFS configured', 'igfss',
                         'Select IGFS to start in cluster or add a new IGFS')
             .col-sm-6
-                +preview-xml-java(model, 'igfss')
+                +preview-xml-java(model, 'igfss', 'igfss')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger.directive.js b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger.directive.js
new file mode 100644
index 0000000..3df231f
--- /dev/null
+++ b/modules/web-console/src/main/js/app/modules/states/configuration/clusters/logger.directive.js
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+import template from './logger.jade!';
+
+export default ['igniteConfigurationClustersLogger', [() => {
+    return {
+        scope: true,
+        restrict: 'E',
+        template,
+        replace: true
+    };
+}]];


[23/50] [abbrv] ignite git commit: ignite-3233 Added 'resourceClass' for SpringResource annotation.

Posted by sb...@apache.org.
ignite-3233 Added 'resourceClass' for SpringResource annotation.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d59e5f56
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d59e5f56
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d59e5f56

Branch: refs/heads/ignite-1232
Commit: d59e5f5612bc916432e13bfa38a034d9120274fc
Parents: 41f81da
Author: sboikov <sb...@gridgain.com>
Authored: Thu Jun 23 12:48:13 2016 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Thu Jun 23 12:48:13 2016 +0300

----------------------------------------------------------------------
 .../apache/ignite/resources/SpringResource.java |  15 +-
 .../GridResourceSpringBeanInjector.java         |  39 ++-
 .../GridSpringResourceInjectionSelfTest.java    | 311 ++++++++++++++++---
 .../spring-resource-with-duplicate-beans.xml    |  30 ++
 .../processors/resource/spring-resource.xml     |   2 +-
 5 files changed, 353 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d59e5f56/modules/core/src/main/java/org/apache/ignite/resources/SpringResource.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/resources/SpringResource.java b/modules/core/src/main/java/org/apache/ignite/resources/SpringResource.java
index f4c041e..0a8b832 100644
--- a/modules/core/src/main/java/org/apache/ignite/resources/SpringResource.java
+++ b/modules/core/src/main/java/org/apache/ignite/resources/SpringResource.java
@@ -112,5 +112,18 @@ public @interface SpringResource {
      *
      * @return Resource bean name.
      */
-    String resourceName();
+    String resourceName() default "";
+
+    /**
+     * Resource bean class in provided {@code ApplicationContext} to look up
+     * a Spring bean.
+     *
+     * @return Resource bean class.
+     */
+    Class<?> resourceClass() default DEFAULT.class;
+
+    /** Dummy class to compensate for impossibility of having default null value for annotation method. */
+    final class DEFAULT {
+        // No-op.
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/d59e5f56/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java
----------------------------------------------------------------------
diff --git a/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java b/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java
index adcf141..816a597 100644
--- a/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java
+++ b/modules/spring/src/main/java/org/apache/ignite/internal/processors/resource/GridResourceSpringBeanInjector.java
@@ -24,6 +24,7 @@ import org.apache.ignite.internal.managers.deployment.GridDeployment;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.resources.SpringResource;
 import org.springframework.context.ApplicationContext;
+import org.springframework.util.StringUtils;
 
 /**
  * Spring bean injector implementation works with resources provided
@@ -59,10 +60,8 @@ public class GridResourceSpringBeanInjector implements GridResourceInjector {
                 field.getField());
         }
 
-        String name = ann.resourceName();
-
         if (springCtx != null) {
-            Object bean = springCtx.getBean(name);
+            Object bean = getBeanByResourceAnnotation(ann);
 
             GridResourceUtils.inject(field.getField(), target, bean);
         }
@@ -78,10 +77,8 @@ public class GridResourceSpringBeanInjector implements GridResourceInjector {
         if (mtd.getMethod().getParameterTypes().length != 1)
             throw new IgniteCheckedException("Method injection setter must have only one parameter: " + mtd.getMethod());
 
-        String name = ann.resourceName();
-
         if (springCtx != null) {
-            Object bean = springCtx.getBean(name);
+            Object bean = getBeanByResourceAnnotation(ann);
 
             GridResourceUtils.inject(mtd.getMethod(), target, bean);
         }
@@ -96,4 +93,34 @@ public class GridResourceSpringBeanInjector implements GridResourceInjector {
     @Override public String toString() {
         return S.toString(GridResourceSpringBeanInjector.class, this);
     }
+
+    /**
+     * Retrieves from {@link #springCtx} the bean specified by {@link SpringResource} annotation.
+     *
+     * @param annotation {@link SpringResource} annotation instance from field or method.
+     * @return Bean object retrieved from spring context.
+     * @throws IgniteCheckedException If failed.
+     */
+    private Object getBeanByResourceAnnotation(SpringResource annotation) throws IgniteCheckedException {
+        assert springCtx != null;
+
+        String beanName = annotation.resourceName();
+        Class<?> beanCls = annotation.resourceClass();
+
+        boolean oneParamSet = !StringUtils.isEmpty(beanName) ^ beanCls != SpringResource.DEFAULT.class;
+
+        if (!oneParamSet) {
+            throw new IgniteCheckedException("Either bean name or its class must be specified in @SpringResource, " +
+                "but not both");
+        }
+
+        Object bean;
+
+        if (!StringUtils.isEmpty(beanName))
+            bean = springCtx.getBean(beanName);
+        else
+            bean = springCtx.getBean(beanCls);
+
+        return bean;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/d59e5f56/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java
index 968c8c4..b989ac8 100644
--- a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java
+++ b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java
@@ -17,17 +17,22 @@
 
 package org.apache.ignite.internal.processors.resource;
 
+import java.util.concurrent.Callable;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteSpring;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.G;
 import org.apache.ignite.lang.IgniteCallable;
 import org.apache.ignite.resources.SpringResource;
+import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
 /**
  * Tests for injected resource.
  */
+@SuppressWarnings("unused")
 public class GridSpringResourceInjectionSelfTest extends GridCommonAbstractTest {
     /** Bean name. */
     private static final String DUMMY_BEAN = "dummyResourceBean";
@@ -49,13 +54,13 @@ public class GridSpringResourceInjectionSelfTest extends GridCommonAbstractTest
     /**
      * @throws Exception If failed.
      */
-    public void testClosureField() throws Exception {
+    public void testClosureFieldByResourceName() throws Exception {
         grid.compute().call(new IgniteCallable<Object>() {
             @SpringResource(resourceName = DUMMY_BEAN)
-            private transient DummyResourceBean dummyResourceBean;
+            private transient DummyResourceBean dummyRsrcBean;
 
             @Override public Object call() throws Exception {
-                assertNotNull(dummyResourceBean);
+                assertNotNull(dummyRsrcBean);
 
                 return null;
             }
@@ -63,81 +68,315 @@ public class GridSpringResourceInjectionSelfTest extends GridCommonAbstractTest
     }
 
     /**
+     * @throws Exception If failed.
+     */
+    public void testClosureFieldByResourceClass() throws Exception {
+        grid.compute().call(new IgniteCallable<Object>() {
+            @SpringResource(resourceClass = DummyResourceBean.class)
+            private transient DummyResourceBean dummyRsrcBean;
+
+            @Override public Object call() throws Exception {
+                assertNotNull(dummyRsrcBean);
+
+                return null;
+            }
+        });
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testClosureFieldByResourceClassWithMultipleBeans() throws Exception {
+        IgniteConfiguration anotherCfg = new IgniteConfiguration();
+        anotherCfg.setGridName("anotherGrid");
+
+        Ignite anotherGrid = IgniteSpring.start(anotherCfg, new ClassPathXmlApplicationContext(
+            "/org/apache/ignite/internal/processors/resource/spring-resource-with-duplicate-beans.xml"));
+
+        Throwable err = assertError(new IgniteCallable<Object>() {
+            @SpringResource(resourceClass = DummyResourceBean.class)
+            private transient DummyResourceBean dummyRsrcBean;
+
+            @Override public Object call() throws Exception {
+                assertNotNull(dummyRsrcBean);
+
+                return null;
+            }
+        }, anotherGrid, null);
+
+        assertTrue("Unexpected message: " + err.getMessage(), err.getMessage().startsWith("No qualifying bean of type " +
+            "[org.apache.ignite.internal.processors.resource.GridSpringResourceInjectionSelfTest$DummyResourceBean]" +
+            " is defined: expected single matching bean but found 2:"));
+
+        G.stop("anotherGrid", false);
+    }
+
+    /**
      * Resource injection with non-existing resource name.
      */
-    public void testClosureFieldWithWrongResourceName() throws Exception {
-        try {
-            grid.compute().call(new IgniteCallable<Object>() {
-                @SpringResource(resourceName = "")
-                private transient DummyResourceBean dummyResourceBean;
+    public void testClosureFieldWithWrongResourceName() {
+        assertError(new IgniteCallable<Object>() {
+            @SpringResource(resourceName = "nonExistentResource")
+            private transient DummyResourceBean dummyRsrcBean;
 
-                @Override public Object call() throws Exception {
-                    assertNull(dummyResourceBean);
+            @Override public Object call() throws Exception {
+                assertNull(dummyRsrcBean);
 
-                    return null;
-                }
-            });
-        }
-        catch (IgniteException e) {
-            if (e.getMessage().contains("No bean named '' is defined"))
-                return;
-        }
+                return null;
+            }
+        }, "No bean named 'nonExistentResource' is defined");
+    }
+
+    /**
+     * Resource injection with non-existing resource class.
+     */
+    public void testClosureFieldWithWrongResourceClass() {
+        assertError(new IgniteCallable<Object>() {
+            @SpringResource(resourceClass = AnotherDummyResourceBean.class)
+            private transient AnotherDummyResourceBean dummyRsrcBean;
+
+            @Override public Object call() throws Exception {
+                assertNull(dummyRsrcBean);
+
+                return null;
+            }
+        }, "No qualifying bean of type [org.apache.ignite.internal.processors.resource." +
+            "GridSpringResourceInjectionSelfTest$AnotherDummyResourceBean] is defined");
+    }
 
-        fail();
+    /**
+     * Resource injection with both resource and class set (ambiguity).
+     */
+    public void testClosureFieldByResourceClassAndName() {
+        assertError(new IgniteCallable<Object>() {
+            @SpringResource(resourceClass = DummyResourceBean.class, resourceName = DUMMY_BEAN)
+            private transient DummyResourceBean dummyRsrcBean;
+
+            @Override public Object call() throws Exception {
+                assertNull(dummyRsrcBean);
+
+                return null;
+            }
+        }, "Either bean name or its class must be specified in @SpringResource, but not both");
+    }
+
+    /**
+     * Resource injection with no name and class set.
+     */
+    public void testClosureFieldWithNoParams() {
+        assertError(new IgniteCallable<Object>() {
+            @SpringResource
+            private transient DummyResourceBean dummyRsrcBean;
+
+            @Override public Object call() throws Exception {
+                assertNull(dummyRsrcBean);
+
+                return null;
+            }
+        }, "Either bean name or its class must be specified in @SpringResource, but not both");
     }
 
     /**
      * @throws Exception If failed.
      */
-    public void testClosureMethod() throws Exception {
+    public void testClosureMethodWithResourceName() throws Exception {
         grid.compute().call(new IgniteCallable<Object>() {
-            private DummyResourceBean dummyResourceBean;
+            private DummyResourceBean dummyRsrcBean;
 
             @SpringResource(resourceName = DUMMY_BEAN)
-            private void setDummyResourceBean(DummyResourceBean dummyResourceBean) {
-                assertNotNull(dummyResourceBean);
+            private void setDummyResourceBean(DummyResourceBean dummyRsrcBean) {
+                assertNotNull(dummyRsrcBean);
 
-                this.dummyResourceBean = dummyResourceBean;
+                this.dummyRsrcBean = dummyRsrcBean;
             }
 
             @Override public Object call() throws Exception {
+                assertNotNull(dummyRsrcBean);
+
                 return null;
             }
         });
     }
 
     /**
-     * Resource injection with non-existing resource name.
+     * @throws Exception If failed.
      */
-    public void testClosureMethodWithWrongResourceName() throws Exception {
+    public void testClosureMethodWithResourceClass() throws Exception {
+        grid.compute().call(new IgniteCallable<Object>() {
+            private DummyResourceBean dummyRsrcBean;
+
+            @SpringResource(resourceClass = DummyResourceBean.class)
+            private void setDummyResourceBean(DummyResourceBean dummyRsrcBean) {
+                assertNotNull(dummyRsrcBean);
+
+                this.dummyRsrcBean = dummyRsrcBean;
+            }
+
+            @Override public Object call() throws Exception {
+                assertNotNull(dummyRsrcBean);
+
+                return null;
+            }
+        });
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+    public void testClosureMethodWithResourceClassWithMultipleBeans() throws Exception {
+        IgniteConfiguration anotherCfg = new IgniteConfiguration();
+        anotherCfg.setGridName("anotherGrid");
+
+        Ignite anotherGrid = IgniteSpring.start(anotherCfg, new ClassPathXmlApplicationContext(
+            "/org/apache/ignite/internal/processors/resource/spring-resource-with-duplicate-beans.xml"));
+
         try {
-            grid.compute().call(new IgniteCallable<Object>() {
-                private DummyResourceBean dummyResourceBean;
+            Throwable err = assertError(new IgniteCallable<Object>() {
+                private DummyResourceBean dummyRsrcBean;
+
+                @SpringResource(resourceClass = DummyResourceBean.class)
+                private void setDummyResourceBean(DummyResourceBean dummyRsrcBean) {
+                    assertNotNull(dummyRsrcBean);
 
-                @SpringResource(resourceName = "")
-                private void setDummyResourceBean(DummyResourceBean dummyResourceBean) {
+                    this.dummyRsrcBean = dummyRsrcBean;
                 }
 
                 @Override public Object call() throws Exception {
-                    assertNull(dummyResourceBean);
+                    assertNotNull(dummyRsrcBean);
 
                     return null;
                 }
-            });
+            }, anotherGrid, null);
+
+            assertTrue("Unexpected message: " + err.getMessage(), err.getMessage().startsWith("No qualifying bean of type " +
+                "[org.apache.ignite.internal.processors.resource.GridSpringResourceInjectionSelfTest$DummyResourceBean]" +
+                " is defined: expected single matching bean but found 2:"));
         }
-        catch (IgniteException e) {
-            if (e.getMessage().contains("No bean named '' is defined"))
-                return;
+        finally {
+            G.stop("anotherGrid", false);
         }
+    }
+
+    /**
+     * Resource injection with non-existing resource name.
+     */
+    public void testClosureMethodWithWrongResourceName() {
+        assertError(new IgniteCallable<Object>() {
+            private DummyResourceBean dummyRsrcBean;
 
-        fail();
+            @SpringResource(resourceName = "nonExistentResource")
+            private void setDummyResourceBean(DummyResourceBean dummyRsrcBean) {
+                // No-op.
+            }
+
+            @Override public Object call() throws Exception {
+                assertNull(dummyRsrcBean);
+
+                return null;
+            }
+        }, "No bean named 'nonExistentResource' is defined");
+    }
+
+    /**
+     * Resource injection with non-existing resource class.
+     */
+    public void testClosureMethodWithWrongResourceClass() {
+        assertError(new IgniteCallable<Object>() {
+            private AnotherDummyResourceBean dummyRsrcBean;
+
+            @SpringResource(resourceClass = AnotherDummyResourceBean.class)
+            private void setDummyResourceBean(AnotherDummyResourceBean dummyRsrcBean) {
+                // No-op.
+            }
+
+            @Override public Object call() throws Exception {
+                assertNull(dummyRsrcBean);
+
+                return null;
+            }
+        }, "No qualifying bean of type [org.apache.ignite.internal.processors.resource" +
+                ".GridSpringResourceInjectionSelfTest$AnotherDummyResourceBean] is defined");
+    }
+
+    /**
+     * Resource injection with both resource and class set (ambiguity).
+     */
+    public void testClosureMethodByResourceClassAndName() {
+        assertError(new IgniteCallable<Object>() {
+            @SpringResource(resourceClass = DummyResourceBean.class, resourceName = DUMMY_BEAN)
+            private transient DummyResourceBean dummyRsrcBean;
+
+            @Override public Object call() throws Exception {
+                assertNull(dummyRsrcBean);
+
+                return null;
+            }
+        }, "Either bean name or its class must be specified in @SpringResource, but not both");
+    }
+
+    /**
+     * Resource injection with no params.
+     */
+    public void testClosureMethodWithNoParams() {
+        assertError(new IgniteCallable<Object>() {
+            @SpringResource
+            private transient DummyResourceBean dummyRsrcBean;
+
+            @Override public Object call() throws Exception {
+                assertNull(dummyRsrcBean);
+
+                return null;
+            }
+        }, "Either bean name or its class must be specified in @SpringResource, but not both");
+    }
+
+    /**
+     * @param job {@link IgniteCallable} to be run
+     * @param grid Node.
+     * @param expEMsg Message that {@link IgniteException} thrown from <tt>job</tt> should bear
+     * @return Thrown error.
+     */
+    @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+    private Throwable assertError(final IgniteCallable<?> job, final Ignite grid, String expEMsg) {
+        return GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                grid.compute(grid.cluster().forLocal()).call(job);
+                return null;
+            }
+        }, IgniteException.class, expEMsg);
+    }
+
+    /**
+     * @param job {@link IgniteCallable} to be run
+     * @param expEMsg Message that {@link IgniteException} thrown from <tt>job</tt> should bear
+     */
+    @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+    private void assertError(final IgniteCallable<?> job, String expEMsg) {
+        assertError(job, grid, expEMsg);
     }
 
     /**
      * Dummy resource bean.
      */
     public static class DummyResourceBean {
+        /**
+         *
+         */
         public DummyResourceBean() {
+            // No-op.
+        }
+    }
+
+    /**
+     * Another dummy resource bean.
+     */
+    private static class AnotherDummyResourceBean {
+        /**
+         *
+         */
+        public AnotherDummyResourceBean() {
+            // No-op.
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d59e5f56/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource-with-duplicate-beans.xml
----------------------------------------------------------------------
diff --git a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource-with-duplicate-beans.xml b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource-with-duplicate-beans.xml
new file mode 100644
index 0000000..98a94f8
--- /dev/null
+++ b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource-with-duplicate-beans.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
+
+    <bean id="dummyBean1"
+          class="org.apache.ignite.internal.processors.resource.GridSpringResourceInjectionSelfTest$DummyResourceBean">
+    </bean>
+    <bean id="dummyBean2"
+          class="org.apache.ignite.internal.processors.resource.GridSpringResourceInjectionSelfTest$DummyResourceBean">
+    </bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/ignite/blob/d59e5f56/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml
----------------------------------------------------------------------
diff --git a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml
index 3abb521..6baf116 100644
--- a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml
+++ b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml
@@ -19,7 +19,7 @@
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
-    	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
+        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 
     <bean id="dummyResourceBean"
           class="org.apache.ignite.internal.processors.resource.GridSpringResourceInjectionSelfTest$DummyResourceBean">


[11/50] [abbrv] ignite git commit: Merge branch 'gridgain-7.6.1' of https://github.com/gridgain/apache-ignite

Posted by sb...@apache.org.
Merge branch 'gridgain-7.6.1' of https://github.com/gridgain/apache-ignite


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8f283826
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8f283826
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8f283826

Branch: refs/heads/ignite-1232
Commit: 8f28382698207058c8d1a5c2a08976bcef3db083
Parents: 766c89e 482015e
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Tue Jun 21 17:54:19 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Tue Jun 21 17:54:19 2016 +0700

----------------------------------------------------------------------
 .../JettyRestProcessorAbstractSelfTest.java     | 33 ++++++++++++++++++++
 .../http/jetty/GridJettyObjectMapper.java       | 23 +++++++++++---
 2 files changed, 52 insertions(+), 4 deletions(-)
----------------------------------------------------------------------



[35/50] [abbrv] ignite git commit: Ignite Web Console beta2.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/generator/generator-java.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/generator/generator-java.js b/modules/web-console/src/main/js/generator/generator-java.js
index 7bb6f10..2b6ac2f 100644
--- a/modules/web-console/src/main/js/generator/generator-java.js
+++ b/modules/web-console/src/main/js/generator/generator-java.js
@@ -25,7 +25,7 @@ const $generatorJava = {};
  * @param type Value type.
  * @returns {*} String with value that will be valid for java.
  */
-$generatorJava.toJavaCode = function (val, type) {
+$generatorJava.toJavaCode = function(val, type) {
     if (val === null)
         return 'null';
 
@@ -44,13 +44,13 @@ $generatorJava.toJavaCode = function (val, type) {
     if (type)
         return type + '.' + val;
 
-    if (typeof(val) === 'string')
+    if (typeof (val) === 'string')
         return '"' + val.replace('"', '\\"') + '"';
 
-    if (typeof(val) === 'number' || typeof(val) === 'boolean')
-        return '' + val;
+    if (typeof (val) === 'number' || typeof (val) === 'boolean')
+        return String(val);
 
-    return 'Unknown type: ' + typeof(val) + ' (' + val + ')';
+    return 'Unknown type: ' + typeof (val) + ' (' + val + ')';
 };
 
 /**
@@ -58,20 +58,20 @@ $generatorJava.toJavaCode = function (val, type) {
  * @param setterName Optional concrete setter name.
  * @returns Property setter with name by java conventions.
  */
-$generatorJava.setterName = function (propName, setterName) {
+$generatorJava.setterName = function(propName, setterName) {
     return setterName ? setterName : $generatorCommon.toJavaName('set', propName);
 };
 
 // Add constructor argument
-$generatorJava.constructorArg = function (obj, propName, dflt, notFirst, opt) {
-    var v = (obj ? obj[propName] : null) || dflt;
+$generatorJava.constructorArg = function(obj, propName, dflt, notFirst, opt) {
+    const v = (obj ? obj[propName] : null) || dflt;
 
     if ($generatorCommon.isDefinedAndNotEmpty(v))
         return (notFirst ? ', ' : '') + $generatorJava.toJavaCode(v);
     else if (!opt)
         return notFirst ? ', null' : 'null';
-    else
-        return '';
+
+    return '';
 };
 
 /**
@@ -85,20 +85,20 @@ $generatorJava.constructorArg = function (obj, propName, dflt, notFirst, opt) {
  * @param varFullGenericType2 Optional full class name of second generic.
  * @param subClass If 'true' then variable will be declared as anonymous subclass.
  */
-$generatorJava.declareVariable = function (res, varName, varFullType, varFullActualType, varFullGenericType1, varFullGenericType2, subClass) {
+$generatorJava.declareVariable = function(res, varName, varFullType, varFullActualType, varFullGenericType1, varFullGenericType2, subClass) {
     res.emptyLineIfNeeded();
 
-    var varType = res.importClass(varFullType);
+    const varType = res.importClass(varFullType);
 
-    var varNew = !res.vars[varName];
+    const varNew = !res.vars[varName];
 
     if (varNew)
         res.vars[varName] = true;
 
     if (varFullActualType && varFullGenericType1) {
-        var varActualType = res.importClass(varFullActualType);
-        var varGenericType1 = res.importClass(varFullGenericType1);
-        var varGenericType2 = null;
+        const varActualType = res.importClass(varFullActualType);
+        const varGenericType1 = res.importClass(varFullGenericType1);
+        let varGenericType2 = null;
 
         if (varFullGenericType2)
             varGenericType2 = res.importClass(varFullGenericType2);
@@ -122,8 +122,8 @@ $generatorJava.declareVariable = function (res, varName, varFullType, varFullAct
  * @param varName Variable name.
  * @param varFullType Variable full class name to be added to imports.
  */
-$generatorJava.declareVariableLocal = function (res, varName, varFullType) {
-    var varType = res.importClass(varFullType);
+$generatorJava.declareVariableLocal = function(res, varName, varFullType) {
+    const varType = res.importClass(varFullType);
 
     res.line(varType + ' ' + varName + ' = new ' + varType + '();');
 
@@ -139,10 +139,10 @@ $generatorJava.declareVariableLocal = function (res, varName, varFullType) {
  * @param varExpr Custom variable creation expression.
  * @param modifier Additional variable modifier.
  */
-$generatorJava.declareVariableCustom = function (res, varName, varFullType, varExpr, modifier) {
-    var varType = res.importClass(varFullType);
+$generatorJava.declareVariableCustom = function(res, varName, varFullType, varExpr, modifier) {
+    const varType = res.importClass(varFullType);
 
-    var varNew = !res.vars[varName];
+    const varNew = !res.vars[varName];
 
     if (varNew)
         res.vars[varName] = true;
@@ -160,10 +160,10 @@ $generatorJava.declareVariableCustom = function (res, varName, varFullType, varE
  * @param varFullType Variable full class name to be added to imports.
  * @param length Array length.
  */
-$generatorJava.declareVariableArray = function (res, varName, varFullType, length) {
-    var varType = res.importClass(varFullType);
+$generatorJava.declareVariableArray = function(res, varName, varFullType, length) {
+    const varType = res.importClass(varFullType);
 
-    var varNew = !res.vars[varName];
+    const varNew = !res.vars[varName];
 
     if (varNew)
         res.vars[varName] = true;
@@ -178,7 +178,7 @@ $generatorJava.declareVariableArray = function (res, varName, varFullType, lengt
  *
  * @param res
  */
-$generatorJava.resetVariables = function (res) {
+$generatorJava.resetVariables = function(res) {
     res.vars = {};
 };
 
@@ -193,18 +193,20 @@ $generatorJava.resetVariables = function (res) {
  * @param setterName Optional special setter name.
  * @param dflt Optional default value.
  */
-$generatorJava.property = function (res, varName, obj, propName, dataType, setterName, dflt) {
-    var val = obj[propName];
+$generatorJava.property = function(res, varName, obj, propName, dataType, setterName, dflt) {
+    if (!_.isNil(obj)) {
+        const val = obj[propName];
 
-    if ($generatorCommon.isDefinedAndNotEmpty(val)) {
-        var missDflt = _.isNil(dflt);
+        if ($generatorCommon.isDefinedAndNotEmpty(val)) {
+            const missDflt = _.isNil(dflt);
 
-        // Add to result if no default provided or value not equals to default.
-        if (missDflt || (!missDflt && val !== dflt)) {
-            res.line(varName + '.' + $generatorJava.setterName(propName, setterName) +
-                '(' + $generatorJava.toJavaCode(val, dataType) + ');');
+            // Add to result if no default provided or value not equals to default.
+            if (missDflt || (!missDflt && val !== dflt)) {
+                res.line(varName + '.' + $generatorJava.setterName(propName, setterName) +
+                    '(' + $generatorJava.toJavaCode(val, dataType) + ');');
 
-            return true;
+                return true;
+            }
         }
     }
 
@@ -222,11 +224,11 @@ $generatorJava.property = function (res, varName, obj, propName, dataType, sette
  * @param setterName Optional special setter name.
  * @param dflt Optional default value.
  */
-$generatorJava.enumProperty = function (res, varName, obj, propName, dataType, setterName, dflt) {
-    var val = obj[propName];
+$generatorJava.enumProperty = function(res, varName, obj, propName, dataType, setterName, dflt) {
+    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)) {
@@ -241,8 +243,8 @@ $generatorJava.enumProperty = function (res, varName, obj, propName, dataType, s
 };
 
 // Add property for class name.
-$generatorJava.classNameProperty = function (res, varName, obj, propName) {
-    var val = obj[propName];
+$generatorJava.classNameProperty = function(res, varName, obj, propName) {
+    const val = obj[propName];
 
     if (!_.isNil(val)) {
         res.line(varName + '.' + $generatorJava.setterName(propName) +
@@ -260,26 +262,48 @@ $generatorJava.classNameProperty = function (res, varName, obj, propName) {
  * @param dataType Optional data type.
  * @param setterName Optional setter name.
  */
-$generatorJava.listProperty = function (res, varName, obj, propName, dataType, setterName) {
-    var val = obj[propName];
+$generatorJava.listProperty = function(res, varName, obj, propName, dataType, setterName) {
+    const val = obj[propName];
 
     if (val && val.length > 0) {
         res.emptyLineIfNeeded();
 
         res.importClass('java.util.Arrays');
 
-        res.line(varName + '.' + $generatorJava.setterName(propName, setterName) +
-            '(Arrays.asList(' +
-                _.map(val, function (v) {
-                    return $generatorJava.toJavaCode(v, dataType);
-                }).join(', ') +
-            '));');
+        $generatorJava.fxVarArgs(res, varName + '.' + $generatorJava.setterName(propName, setterName), false,
+            _.map(val, (v) => $generatorJava.toJavaCode(v, dataType)), '(Arrays.asList(', '))');
 
         res.needEmptyLine = true;
     }
 };
 
 /**
+ * Add function with varargs arguments.
+ *
+ * @param res Resulting output with generated code.
+ * @param fx Function name.
+ * @param quote Whether to quote arguments.
+ * @param args Array with arguments.
+ * @param startBlock Optional start block string.
+ * @param endBlock Optional end block string.
+ */
+$generatorJava.fxVarArgs = function(res, fx, quote, args, startBlock = '(', endBlock = ')') {
+    const quoteArg = (arg) => quote ? '"' + arg + '"' : arg;
+
+    if (args.length === 1)
+        res.append(fx + startBlock + quoteArg(args[0]) + endBlock + ';');
+    else {
+        res.startBlock(fx + startBlock);
+
+        const len = args.length - 1;
+
+        _.forEach(args, (arg, ix) => res.line(quoteArg(arg) + (ix < len ? ', ' : '')));
+
+        res.endBlock(endBlock + ';');
+    }
+};
+
+/**
  * Add array property.
  *
  * @param res Resulting output with generated code.
@@ -288,17 +312,14 @@ $generatorJava.listProperty = function (res, varName, obj, propName, dataType, s
  * @param propName Property name to take from source object.
  * @param setterName Optional setter name.
  */
-$generatorJava.arrayProperty = function (res, varName, obj, propName, setterName) {
-    var val = obj[propName];
+$generatorJava.arrayProperty = function(res, varName, obj, propName, setterName) {
+    const val = obj[propName];
 
     if (val && val.length > 0) {
         res.emptyLineIfNeeded();
 
-        res.line(varName + '.' + $generatorJava.setterName(propName, setterName) + '({ ' +
-            _.map(val, function (v) {
-                return 'new ' + res.importClass(v) + '()';
-            }).join(', ') +
-        ' });');
+        $generatorJava.fxVarArgs(res, varName + '.' + $generatorJava.setterName(propName, setterName), false,
+            _.map(val, (v) => 'new ' + res.importClass(v) + '()'), '({ ', ' });');
 
         res.needEmptyLine = true;
     }
@@ -314,19 +335,12 @@ $generatorJava.arrayProperty = function (res, varName, obj, propName, setterName
  * @param dataType Optional data type.
  * @param setterName Optional setter name.
  */
-$generatorJava.multiparamProperty = function (res, varName, obj, propName, dataType, setterName) {
-    var val = obj[propName];
+$generatorJava.multiparamProperty = function(res, varName, obj, propName, dataType, setterName) {
+    const val = obj[propName];
 
     if (val && val.length > 0) {
-        res.emptyLineIfNeeded();
-
-        res.startBlock(varName + '.' + $generatorJava.setterName(propName, setterName) + '(');
-
-        _.forEach(val, function(v, ix) {
-            res.append($generatorJava.toJavaCode(v, dataType) + (ix < val.length - 1 ? ', ' : ''));
-        });
-
-        res.endBlock(');');
+        $generatorJava.fxVarArgs(res, varName + '.' + $generatorJava.setterName(propName, setterName), false,
+            _.map(val, (v) => $generatorJava.toJavaCode(dataType === 'class' ? res.importClass(v) : v, dataType)));
     }
 };
 
@@ -342,7 +356,7 @@ $generatorJava.multiparamProperty = function (res, varName, obj, propName, dataT
  * @param props
  * @param createBeanAlthoughNoProps If 'true' then create empty bean.
  */
-$generatorJava.beanProperty = function (res, varName, bean, beanPropName, beanVarName, beanClass, props, createBeanAlthoughNoProps) {
+$generatorJava.beanProperty = function(res, varName, bean, beanPropName, beanVarName, beanClass, props, createBeanAlthoughNoProps) {
     if (bean && $generatorCommon.hasProperty(bean, props)) {
         res.emptyLineIfNeeded();
 
@@ -377,13 +391,13 @@ $generatorJava.beanProperty = function (res, varName, bean, beanPropName, beanVa
                             break;
 
                         case 'propertiesAsList':
-                            var val = bean[propName];
+                            const val = bean[propName];
 
                             if (val && val.length > 0) {
                                 $generatorJava.declareVariable(res, descr.propVarName, 'java.util.Properties');
 
                                 _.forEach(val, function(nameAndValue) {
-                                    var eqIndex = nameAndValue.indexOf('=');
+                                    const eqIndex = nameAndValue.indexOf('=');
 
                                     if (eqIndex >= 0) {
                                         res.line(descr.propVarName + '.setProperty(' +
@@ -408,9 +422,8 @@ $generatorJava.beanProperty = function (res, varName, bean, beanPropName, beanVa
                             $generatorJava.property(res, beanVarName, bean, propName, null, descr.setterName, descr.dflt);
                     }
                 }
-                else {
+                else
                     $generatorJava.property(res, beanVarName, bean, propName);
-                }
             }
         });
 
@@ -436,11 +449,11 @@ $generatorJava.beanProperty = function (res, varName, bean, beanPropName, beanVa
  * @param evtPlc Data to add.
  * @param propName Name in source data.
  */
-$generatorJava.evictionPolicy = function (res, varName, evtPlc, propName) {
+$generatorJava.evictionPolicy = function(res, varName, evtPlc, propName) {
     if (evtPlc && evtPlc.kind) {
-        var evictionPolicyDesc = $generatorCommon.EVICTION_POLICIES[evtPlc.kind];
+        const evictionPolicyDesc = $generatorCommon.EVICTION_POLICIES[evtPlc.kind];
 
-        var obj = evtPlc[evtPlc.kind.toUpperCase()];
+        const obj = evtPlc[evtPlc.kind.toUpperCase()];
 
         $generatorJava.beanProperty(res, varName, obj, propName, propName,
             evictionPolicyDesc.className, evictionPolicyDesc.fields, true);
@@ -448,7 +461,7 @@ $generatorJava.evictionPolicy = function (res, varName, evtPlc, propName) {
 };
 
 // Generate cluster general group.
-$generatorJava.clusterGeneral = function (cluster, clientNearCfg, res) {
+$generatorJava.clusterGeneral = function(cluster, clientNearCfg, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -467,7 +480,7 @@ $generatorJava.clusterGeneral = function (cluster, clientNearCfg, res) {
     }
 
     if (cluster.discovery) {
-        var d = cluster.discovery;
+        const d = cluster.discovery;
 
         $generatorJava.declareVariable(res, 'discovery', 'org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi');
 
@@ -538,7 +551,7 @@ $generatorJava.clusterGeneral = function (cluster, clientNearCfg, res) {
                 break;
 
             case 'ZooKeeper':
-                var finderVar = 'ipFinder';
+                const finderVar = 'ipFinder';
 
                 $generatorJava.declareVariable(res, 'ipFinder', 'org.apache.ignite.spi.discovery.tcp.ipfinder.zk.TcpDiscoveryZookeeperIpFinder');
 
@@ -549,8 +562,8 @@ $generatorJava.clusterGeneral = function (cluster, clientNearCfg, res) {
                     $generatorJava.property(res, finderVar, d.ZooKeeper, 'zkConnectionString');
 
                     if (d.ZooKeeper.retryPolicy && d.ZooKeeper.retryPolicy.kind) {
-                        var kind = d.ZooKeeper.retryPolicy.kind;
-                        var retryPolicy = d.ZooKeeper.retryPolicy[kind];
+                        const kind = d.ZooKeeper.retryPolicy.kind;
+                        const retryPolicy = d.ZooKeeper.retryPolicy[kind];
 
                         switch (kind) {
                             case 'ExponentialBackoff':
@@ -600,6 +613,8 @@ $generatorJava.clusterGeneral = function (cluster, clientNearCfg, res) {
                                     res.line(finderVar + '.setRetryPolicy(new ' + res.importClass(retryPolicy.className) + '());');
 
                                 break;
+
+                            default:
                         }
                     }
 
@@ -631,7 +646,7 @@ $generatorJava.clusterGeneral = function (cluster, clientNearCfg, res) {
 };
 
 // Generate atomics group.
-$generatorJava.clusterAtomics = function (atomics, res) {
+$generatorJava.clusterAtomics = function(atomics, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -642,9 +657,9 @@ $generatorJava.clusterAtomics = function (atomics, res) {
 
         $generatorJava.enumProperty(res, 'atomicCfg', atomics, 'cacheMode', 'org.apache.ignite.cache.CacheMode', null, 'PARTITIONED');
 
-        var cacheMode = atomics.cacheMode ? atomics.cacheMode : 'PARTITIONED';
+        const cacheMode = atomics.cacheMode ? atomics.cacheMode : 'PARTITIONED';
 
-        var hasData = cacheMode !== 'PARTITIONED';
+        let hasData = cacheMode !== 'PARTITIONED';
 
         hasData = $generatorJava.property(res, 'atomicCfg', atomics, 'atomicSequenceReserveSize', null, null, 1000) || hasData;
 
@@ -665,12 +680,12 @@ $generatorJava.clusterAtomics = function (atomics, res) {
 };
 
 // Generate binary group.
-$generatorJava.clusterBinary = function (binary, res) {
+$generatorJava.clusterBinary = function(binary, res) {
     if (!res)
         res = $generatorCommon.builder();
 
     if ($generatorCommon.binaryIsDefined(binary)) {
-        var varName = 'binary';
+        const varName = 'binary';
 
         $generatorJava.declareVariable(res, varName, 'org.apache.ignite.configuration.BinaryConfiguration');
 
@@ -686,15 +701,13 @@ $generatorJava.clusterBinary = function (binary, res) {
         res.needEmptyLine = $generatorCommon.isDefinedAndNotEmpty(binary.idMapper) || $generatorCommon.isDefinedAndNotEmpty(binary.serializer);
 
         if ($generatorCommon.isDefinedAndNotEmpty(binary.typeConfigurations)) {
-            var arrVar = 'types';
+            const arrVar = 'types';
 
             $generatorJava.declareVariable(res, arrVar, 'java.util.Collection', 'java.util.ArrayList', 'org.apache.ignite.binary.BinaryTypeConfiguration');
 
-            _.forEach(binary.typeConfigurations, function (type) {
-                if ($generatorCommon.isDefinedAndNotEmpty(type.typeName)) {
-                    // TODO IGNITE-2269 Replace using of separated methods for binary type configurations to extended constructors.
-                    res.line(arrVar + '.add(' + $generatorJava.binaryTypeFunctionName(type.typeName) + '());');
-                }
+            _.forEach(binary.typeConfigurations, function(type) {
+                if ($generatorCommon.isDefinedAndNotEmpty(type.typeName))
+                    res.line(arrVar + '.add(' + $generatorJava.binaryTypeFunctionName(type.typeName) + '());'); // TODO IGNITE-2269 Replace using of separated methods for binary type configurations to extended constructors.
             });
 
             res.needEmptyLine = true;
@@ -704,7 +717,7 @@ $generatorJava.clusterBinary = function (binary, res) {
             res.needEmptyLine = true;
         }
 
-        $generatorJava.property(res, varName, binary, 'compactFooter', undefined, undefined, true);
+        $generatorJava.property(res, varName, binary, 'compactFooter', null, null, true);
 
         res.needEmptyLine = true;
 
@@ -718,18 +731,18 @@ $generatorJava.clusterBinary = function (binary, res) {
 
 // TODO IGNITE-2269 Remove specified methods after implamentation of extended constructors.
 // Construct binary type configuration factory method name.
-$generatorJava.binaryTypeFunctionName = function (typeName) {
-    var dotIdx = typeName.lastIndexOf('.');
+$generatorJava.binaryTypeFunctionName = function(typeName) {
+    const dotIdx = typeName.lastIndexOf('.');
 
-    var shortName = dotIdx > 0 ? typeName.substr(dotIdx + 1) : typeName;
+    const shortName = dotIdx > 0 ? typeName.substr(dotIdx + 1) : typeName;
 
     return $generatorCommon.toJavaName('binaryType', shortName);
 };
 
 // TODO IGNITE-2269 Remove specified methods after implamentation of extended constructors.
 // Generate factory method for specified BinaryTypeConfiguration.
-$generatorJava.binaryTypeConfiguration = function (type, res) {
-    var typeName = type.typeName;
+$generatorJava.binaryTypeConfiguration = function(type, res) {
+    const typeName = type.typeName;
 
     res.line('/**');
     res.line(' * Create binary type configuration for ' + typeName + '.');
@@ -740,7 +753,7 @@ $generatorJava.binaryTypeConfiguration = function (type, res) {
 
     $generatorJava.resetVariables(res);
 
-    var typeVar = 'typeCfg';
+    const typeVar = 'typeCfg';
 
     $generatorJava.declareVariable(res, typeVar, 'org.apache.ignite.binary.BinaryTypeConfiguration');
 
@@ -767,12 +780,12 @@ $generatorJava.binaryTypeConfiguration = function (type, res) {
 
 // TODO IGNITE-2269 Remove specified methods after implamentation of extended constructors.
 // Generates binary type configuration factory methods.
-$generatorJava.binaryTypeConfigurations = function (binary, res) {
+$generatorJava.binaryTypeConfigurations = function(binary, res) {
     if (!res)
         res = $generatorCommon.builder();
 
     if (!_.isNil(binary)) {
-        _.forEach(binary.typeConfigurations, function (type) {
+        _.forEach(binary.typeConfigurations, function(type) {
             $generatorJava.binaryTypeConfiguration(type, res);
         });
     }
@@ -780,12 +793,96 @@ $generatorJava.binaryTypeConfigurations = function (binary, res) {
     return res;
 };
 
+// Generate collision group.
+$generatorJava.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))) {
+            const varName = 'collisionSpi';
+
+            switch (collision.kind) {
+                case 'JobStealing':
+                    $generatorJava.declareVariable(res, varName, 'org.apache.ignite.spi.collision.jobstealing.JobStealingCollisionSpi');
+
+                    $generatorJava.property(res, varName, spi, 'activeJobsThreshold', null, null, 95);
+                    $generatorJava.property(res, varName, spi, 'waitJobsThreshold', null, null, 0);
+                    $generatorJava.property(res, varName, spi, 'messageExpireTime', null, null, 1000);
+                    $generatorJava.property(res, varName, spi, 'maximumStealingAttempts', null, null, 5);
+                    $generatorJava.property(res, varName, spi, 'stealingEnabled', null, null, true);
+
+                    if ($generatorCommon.isDefinedAndNotEmpty(spi.externalCollisionListener)) {
+                        res.line(varName + '.' + $generatorJava.setterName('externalCollisionListener') +
+                            '(new ' + res.importClass(spi.externalCollisionListener) + '());');
+                    }
+
+                    if ($generatorCommon.isDefinedAndNotEmpty(spi.stealingAttributes)) {
+                        const stealingAttrsVar = 'stealingAttrs';
+
+                        res.needEmptyLine = true;
+
+                        $generatorJava.declareVariable(res, stealingAttrsVar, 'java.util.Map', 'java.util.HashMap', 'String', 'java.io.Serializable');
+
+                        _.forEach(spi.stealingAttributes, function(attr) {
+                            res.line(stealingAttrsVar + '.put("' + attr.name + '", "' + attr.value + '");');
+                        });
+
+                        res.needEmptyLine = true;
+
+                        res.line(varName + '.setStealingAttributes(' + stealingAttrsVar + ');');
+                    }
+
+                    break;
+
+                case 'FifoQueue':
+                    $generatorJava.declareVariable(res, varName, 'org.apache.ignite.spi.collision.fifoqueue.FifoQueueCollisionSpi');
+
+                    $generatorJava.property(res, varName, spi, 'parallelJobsNumber');
+                    $generatorJava.property(res, varName, spi, 'waitingJobsNumber');
+
+                    break;
+
+                case 'PriorityQueue':
+                    $generatorJava.declareVariable(res, varName, 'org.apache.ignite.spi.collision.priorityqueue.PriorityQueueCollisionSpi');
+
+                    $generatorJava.property(res, varName, spi, 'parallelJobsNumber');
+                    $generatorJava.property(res, varName, spi, 'waitingJobsNumber');
+                    $generatorJava.property(res, varName, spi, 'priorityAttributeKey', null, null, 'grid.task.priority');
+                    $generatorJava.property(res, varName, spi, 'jobPriorityAttributeKey', null, null, 'grid.job.priority');
+                    $generatorJava.property(res, varName, spi, 'defaultPriority', null, null, 0);
+                    $generatorJava.property(res, varName, spi, 'starvationIncrement', null, null, 1);
+                    $generatorJava.property(res, varName, spi, 'starvationPreventionEnabled', null, null, true);
+
+                    break;
+
+                case 'Custom':
+                    $generatorJava.declareVariable(res, varName, spi.class);
+
+                    break;
+
+                default:
+            }
+
+            res.needEmptyLine = true;
+
+            res.line('cfg.setCollisionSpi(' + varName + ');');
+
+            res.needEmptyLine = true;
+        }
+    }
+
+    return res;
+};
+
 // Generate communication group.
-$generatorJava.clusterCommunication = function (cluster, res) {
+$generatorJava.clusterCommunication = function(cluster, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    var cfg = $generatorCommon.COMMUNICATION_CONFIGURATION;
+    const cfg = $generatorCommon.COMMUNICATION_CONFIGURATION;
 
     $generatorJava.beanProperty(res, 'cfg', cluster.communication, 'communicationSpi', 'commSpi', cfg.className, cfg.fields);
 
@@ -804,12 +901,12 @@ $generatorJava.clusterCommunication = function (cluster, res) {
 };
 
 // Generate REST access group.
-$generatorJava.clusterConnector = function (connector, res) {
+$generatorJava.clusterConnector = function(connector, res) {
     if (!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};
@@ -826,7 +923,7 @@ $generatorJava.clusterConnector = function (connector, res) {
 };
 
 // Generate deployment group.
-$generatorJava.clusterDeployment = function (cluster, res) {
+$generatorJava.clusterDeployment = function(cluster, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -834,7 +931,7 @@ $generatorJava.clusterDeployment = function (cluster, res) {
 
     res.softEmptyLine();
 
-    var p2pEnabled = cluster.peerClassLoadingEnabled;
+    const p2pEnabled = cluster.peerClassLoadingEnabled;
 
     if (!_.isNil(p2pEnabled)) {
         $generatorJava.property(res, 'cfg', cluster, 'peerClassLoadingEnabled', null, null, false);
@@ -852,7 +949,7 @@ $generatorJava.clusterDeployment = function (cluster, res) {
 };
 
 // Generate discovery group.
-$generatorJava.clusterDiscovery = function (disco, res) {
+$generatorJava.clusterDiscovery = function(disco, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -911,31 +1008,30 @@ $generatorJava.clusterDiscovery = function (disco, res) {
 };
 
 // Generate events group.
-$generatorJava.clusterEvents = function (cluster, res) {
+$generatorJava.clusterEvents = function(cluster, res) {
     if (!res)
         res = $generatorCommon.builder();
 
     if (cluster.includeEventTypes && cluster.includeEventTypes.length > 0) {
         res.emptyLineIfNeeded();
 
-        var evtGrps = angular.element(document.getElementById('app')).injector().get('igniteEventGroups');
-
-        var evtGrpDscr = _.find(evtGrps, {value: cluster.includeEventTypes[0]});
+        const evtGrps = angular.element(document.getElementById('app')).injector().get('igniteEventGroups');
 
-        var evt = res.importStatic(evtGrpDscr.class + '.' + evtGrpDscr.value);
+        if (cluster.includeEventTypes.length === 1) {
+            const evtGrp = _.find(evtGrps, {value: cluster.includeEventTypes[0]});
+            const evts = res.importStatic(evtGrp.class + '.' + evtGrp.value);
 
-        if (cluster.includeEventTypes.length === 1)
-            res.line('cfg.setIncludeEventTypes(' + evt + ');');
+            res.line('cfg.setIncludeEventTypes(' + evts + ');');
+        }
         else {
             _.forEach(cluster.includeEventTypes, function(value, ix) {
-                var evtGrpDscr = _.find(evtGrps, {value: value});
-
-                var evt = res.importStatic(evtGrpDscr.class + '.' + evtGrpDscr.value);
+                const evtGrp = _.find(evtGrps, {value});
+                const evts = res.importStatic(evtGrp.class + '.' + evtGrp.value);
 
                 if (ix === 0)
-                    res.line('int[] events = new int[' + evt + '.length');
+                    res.line('int[] events = new int[' + evts + '.length');
                 else
-                    res.line('    + ' + evt + '.length');
+                    res.line('    + ' + evts + '.length');
             });
 
             res.line('];');
@@ -947,14 +1043,13 @@ $generatorJava.clusterEvents = function (cluster, res) {
             _.forEach(cluster.includeEventTypes, function(value, idx) {
                 res.needEmptyLine = true;
 
-                var evtGrpDscr = _.find(evtGrps, {value: value});
-
-                evt = res.importStatic(evtGrpDscr.class + '.' + value);
+                const evtGrp = _.find(evtGrps, {value});
+                const evts = res.importStatic(evtGrp.class + '.' + value);
 
-                res.line('System.arraycopy(' + evt + ', 0, events, k, ' + evt + '.length);');
+                res.line('System.arraycopy(' + evts + ', 0, events, k, ' + evts + '.length);');
 
                 if (idx < cluster.includeEventTypes.length - 1)
-                    res.line('k += ' + evt + '.length;');
+                    res.line('k += ' + evts + '.length;');
             });
 
             res.needEmptyLine = true;
@@ -970,15 +1065,133 @@ $generatorJava.clusterEvents = function (cluster, res) {
     return res;
 };
 
+// Generate failover group.
+$generatorJava.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) {
+        const arrayVarName = 'failoverSpiList';
+
+        $generatorJava.declareVariable(res, arrayVarName, 'java.util.List', 'java.util.ArrayList', 'org.apache.ignite.spi.failover.FailoverSpi');
+
+        _.forEach(cluster.failoverSpi, function(spi) {
+            if (spi.kind && (spi.kind !== 'Custom' || $generatorCommon.isDefinedAndNotEmpty(_.get(spi, spi.kind + '.class')))) {
+                const varName = 'failoverSpi';
+
+                const maxAttempts = _.get(spi, spi.kind + '.maximumFailoverAttempts');
+
+                if ((spi.kind === 'JobStealing' || spi.kind === 'Always') && $generatorCommon.isDefinedAndNotEmpty(maxAttempts) && maxAttempts !== 5) {
+                    const spiCls = res.importClass($generatorCommon.failoverSpiClass(spi));
+
+                    $generatorJava.declareVariableCustom(res, varName, 'org.apache.ignite.spi.failover.FailoverSpi', 'new ' + spiCls + '()');
+
+                    if ($generatorCommon.isDefinedAndNotEmpty(spi[spi.kind].maximumFailoverAttempts))
+                        res.line('((' + spiCls + ') ' + varName + ').setMaximumFailoverAttempts(' + spi[spi.kind].maximumFailoverAttempts + ');');
+
+                    res.needEmptyLine = true;
+
+                    res.line(arrayVarName + '.add(' + varName + ');');
+                }
+                else
+                    res.line(arrayVarName + '.add(new ' + res.importClass($generatorCommon.failoverSpiClass(spi)) + '());');
+
+                res.needEmptyLine = true;
+            }
+        });
+
+        res.line('cfg.setFailoverSpi(' + arrayVarName + '.toArray(new FailoverSpi[' + arrayVarName + '.size()]));');
+
+        res.needEmptyLine = true;
+    }
+
+    return res;
+};
+
 // Generate marshaller group.
-$generatorJava.clusterMarshaller = function (cluster, res) {
+$generatorJava.clusterLogger = function(logger, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    var marshaller = cluster.marshaller;
+    if ($generatorCommon.loggerConfigured(logger)) {
+        const varName = 'logger';
+
+        const log = logger[logger.kind];
+
+        switch (logger.kind) {
+            case 'Log4j2':
+                $generatorJava.declareVariableCustom(res, varName, 'org.apache.ignite.logger.log4j2.Log4J2Logger',
+                    'new Log4J2Logger(' + $generatorJava.toJavaCode(log.path, 'path') + ')');
+
+                res.needEmptyLine = true;
+
+                if ($generatorCommon.isDefinedAndNotEmpty(log.level))
+                    res.line(varName + '.setLevel(' + res.importClass('org.apache.logging.log4j.Level') + '.' + log.level + ');');
+
+                break;
+
+            case 'Null':
+                $generatorJava.declareVariable(res, varName, 'org.apache.ignite.logger.NullLogger');
+
+                break;
+
+            case 'Java':
+                $generatorJava.declareVariable(res, varName, 'org.apache.ignite.logger.java.JavaLogger');
+
+                break;
+
+            case 'JCL':
+                $generatorJava.declareVariable(res, varName, 'org.apache.ignite.logger.jcl.JclLogger');
+
+                break;
+
+            case 'SLF4J':
+                $generatorJava.declareVariable(res, varName, 'org.apache.ignite.logger.slf4j.Slf4jLogger');
+
+                break;
+
+            case 'Log4j':
+                if (log.mode === 'Default')
+                    $generatorJava.declareVariable(res, varName, 'org.apache.ignite.logger.log4j.Log4JLogger');
+                else {
+                    $generatorJava.declareVariableCustom(res, varName, 'org.apache.ignite.logger.log4j.Log4JLogger',
+                        'new Log4JLogger(' + $generatorJava.toJavaCode(log.path, 'path') + ')');
+                }
+
+                if ($generatorCommon.isDefinedAndNotEmpty(log.level))
+                    res.line(varName + '.setLevel(' + res.importClass('org.apache.log4j.Level') + '.' + log.level + ');');
+
+                break;
+
+            case 'Custom':
+                $generatorJava.declareVariable(res, varName, log.class);
+
+                break;
+
+            default:
+        }
+
+        res.needEmptyLine = true;
+
+        res.line('cfg.setGridLogger(' + varName + ');');
+
+        res.needEmptyLine = true;
+    }
+
+    return res;
+};
+
+// Generate marshaller group.
+$generatorJava.clusterMarshaller = function(cluster, res) {
+    if (!res)
+        res = $generatorCommon.builder();
+
+    const marshaller = cluster.marshaller;
 
     if (marshaller && marshaller.kind) {
-        var marshallerDesc = $generatorCommon.MARSHALLERS[marshaller.kind];
+        const marshallerDesc = $generatorCommon.MARSHALLERS[marshaller.kind];
 
         $generatorJava.beanProperty(res, 'cfg', marshaller[marshaller.kind], 'marshaller', 'marshaller',
             marshallerDesc.className, marshallerDesc.fields, true);
@@ -996,7 +1209,7 @@ $generatorJava.clusterMarshaller = function (cluster, res) {
 };
 
 // Generate metrics group.
-$generatorJava.clusterMetrics = function (cluster, res) {
+$generatorJava.clusterMetrics = function(cluster, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1011,7 +1224,7 @@ $generatorJava.clusterMetrics = function (cluster, res) {
 };
 
 // Generate swap group.
-$generatorJava.clusterSwap = function (cluster, res) {
+$generatorJava.clusterSwap = function(cluster, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1026,7 +1239,7 @@ $generatorJava.clusterSwap = function (cluster, res) {
 };
 
 // Generate time group.
-$generatorJava.clusterTime = function (cluster, res) {
+$generatorJava.clusterTime = function(cluster, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1041,7 +1254,7 @@ $generatorJava.clusterTime = function (cluster, res) {
 };
 
 // Generate thread pools group.
-$generatorJava.clusterPools = function (cluster, res) {
+$generatorJava.clusterPools = function(cluster, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1057,7 +1270,7 @@ $generatorJava.clusterPools = function (cluster, res) {
 };
 
 // Generate transactions group.
-$generatorJava.clusterTransactions = function (transactionConfiguration, res) {
+$generatorJava.clusterTransactions = function(transactionConfiguration, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1068,8 +1281,33 @@ $generatorJava.clusterTransactions = function (transactionConfiguration, res) {
     return res;
 };
 
+// Generate user attributes group.
+$generatorJava.clusterUserAttributes = function(cluster, res) {
+    if (!res)
+        res = $generatorCommon.builder();
+
+    if ($generatorCommon.isDefinedAndNotEmpty(cluster.attributes)) {
+        $generatorJava.declareVariable(res, 'attributes', 'java.util.Map', 'java.util.HashMap', 'java.lang.String', 'java.lang.String');
+
+        _.forEach(cluster.attributes, function(attr) {
+            res.line('attributes.put("' + attr.name + '", "' + attr.value + '");');
+        });
+
+        res.needEmptyLine = true;
+
+        res.line('cfg.setUserAttributes(attributes);');
+
+        res.needEmptyLine = true;
+    }
+
+    res.needEmptyLine = true;
+
+    return res;
+};
+
+
 // Generate cache general group.
-$generatorJava.cacheGeneral = function (cache, varName, res) {
+$generatorJava.cacheGeneral = function(cache, varName, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1096,7 +1334,7 @@ $generatorJava.cacheGeneral = function (cache, varName, res) {
 };
 
 // Generate cache memory group.
-$generatorJava.cacheMemory = function (cache, varName, res) {
+$generatorJava.cacheMemory = function(cache, varName, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1119,7 +1357,7 @@ $generatorJava.cacheMemory = function (cache, varName, res) {
 };
 
 // Generate cache query & indexing group.
-$generatorJava.cacheQuery = function (cache, varName, res) {
+$generatorJava.cacheQuery = function(cache, varName, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1150,15 +1388,15 @@ $generatorJava.cacheQuery = function (cache, varName, res) {
  * @param storeFactory Factory to generate data source for.
  * @param res Resulting output with generated code.
  */
-$generatorJava.cacheStoreDataSource = function (storeFactory, res) {
-    var dialect = storeFactory.connectVia ? (storeFactory.connectVia === 'DataSource' ? storeFactory.dialect : null) : storeFactory.dialect;
+$generatorJava.cacheStoreDataSource = function(storeFactory, res) {
+    const dialect = storeFactory.connectVia ? (storeFactory.connectVia === 'DataSource' ? storeFactory.dialect : null) : storeFactory.dialect;
 
     if (dialect) {
-        var varName = 'dataSource';
+        const varName = 'dataSource';
 
-        var dataSourceBean = storeFactory.dataSourceBean;
+        const dataSourceBean = storeFactory.dataSourceBean;
 
-        var varType = res.importClass($generatorCommon.dataSourceClassName(dialect));
+        const varType = res.importClass($generatorCommon.dataSourceClassName(dialect));
 
         res.line('public static final ' + varType + ' INSTANCE_' + dataSourceBean + ' = create' + dataSourceBean + '();');
 
@@ -1219,21 +1457,21 @@ $generatorJava.cacheStoreDataSource = function (storeFactory, res) {
     return null;
 };
 
-$generatorJava.clusterDataSources = function (caches, res) {
+$generatorJava.clusterDataSources = function(caches, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    var datasources = [];
+    const datasources = [];
 
-    var storeFound = false;
+    let storeFound = false;
 
-    _.forEach(caches, function (cache) {
-        var factoryKind = cache.cacheStoreFactory.kind;
+    _.forEach(caches, function(cache) {
+        const factoryKind = cache.cacheStoreFactory.kind;
 
-        var storeFactory = cache.cacheStoreFactory[factoryKind];
+        const storeFactory = cache.cacheStoreFactory[factoryKind];
 
         if (storeFactory) {
-            var beanClassName = $generatorJava.dataSourceClassName(res, storeFactory);
+            const beanClassName = $generatorJava.dataSourceClassName(res, storeFactory);
 
             if (beanClassName && !_.includes(datasources, beanClassName)) {
                 datasources.push(beanClassName);
@@ -1252,9 +1490,8 @@ $generatorJava.clusterDataSources = function (caches, res) {
         }
     });
 
-    if (storeFound) {
+    if (storeFound)
         res.endBlock('}');
-    }
 
     return res;
 };
@@ -1268,7 +1505,7 @@ $generatorJava.clusterDataSources = function (caches, res) {
  * @param res Resulting output with generated code.
  * @returns {*} Java code for cache store configuration.
  */
-$generatorJava.cacheStore = function (cache, domains, cacheVarName, res) {
+$generatorJava.cacheStore = function(cache, domains, cacheVarName, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1276,14 +1513,14 @@ $generatorJava.cacheStore = function (cache, domains, cacheVarName, res) {
         cacheVarName = $generatorJava.nextVariableName('cache', cache);
 
     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) {
-            var storeFactoryDesc = $generatorCommon.STORE_FACTORIES[factoryKind];
+            const storeFactoryDesc = $generatorCommon.STORE_FACTORIES[factoryKind];
 
-            var varName = 'storeFactory' + storeFactoryDesc.suffix;
+            const varName = 'storeFactory' + storeFactoryDesc.suffix;
 
             if (factoryKind === 'CacheJdbcPojoStoreFactory') {
                 // Generate POJO store factory.
@@ -1308,7 +1545,7 @@ $generatorJava.cacheStore = function (cache, domains, cacheVarName, res) {
 
                 res.needEmptyLine = true;
 
-                var domainConfigs = _.filter(domains, function (domain) {
+                const domainConfigs = _.filter(domains, function(domain) {
                     return $generatorCommon.domainQueryMetadata(domain) === 'Configuration' &&
                         $generatorCommon.isDefinedAndNotEmpty(domain.databaseTable);
                 });
@@ -1318,7 +1555,7 @@ $generatorJava.cacheStore = function (cache, domains, cacheVarName, res) {
 
                     res.needEmptyLine = true;
 
-                    _.forEach(domainConfigs, function (domain) {
+                    _.forEach(domainConfigs, function(domain) {
                         if ($generatorCommon.isDefinedAndNotEmpty(domain.databaseTable))
                             res.line('jdbcTypes.add(jdbcType' + $generatorJava.extractType(domain.valueType) + '(' + cacheVarName + '.getName()));');
                     });
@@ -1373,8 +1610,7 @@ $generatorJava.cacheStore = function (cache, domains, cacheVarName, res) {
                 res.line(cacheVarName + '.setCacheStoreFactory(' + varName + ');');
             }
             else
-                $generatorJava.beanProperty(res, cacheVarName, storeFactory, 'cacheStoreFactory', varName,
-                    storeFactoryDesc.className, storeFactoryDesc.fields, true);
+                $generatorJava.beanProperty(res, cacheVarName, storeFactory, 'cacheStoreFactory', varName, storeFactoryDesc.className, storeFactoryDesc.fields, true);
 
             res.needEmptyLine = true;
         }
@@ -1403,7 +1639,7 @@ $generatorJava.cacheStore = function (cache, domains, cacheVarName, res) {
 };
 
 // Generate cache concurrency group.
-$generatorJava.cacheConcurrency = function (cache, varName, res) {
+$generatorJava.cacheConcurrency = function(cache, varName, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1413,7 +1649,7 @@ $generatorJava.cacheConcurrency = function (cache, varName, res) {
     $generatorJava.property(res, varName, cache, 'maxConcurrentAsyncOperations', null, null, 500);
     $generatorJava.property(res, varName, cache, 'defaultLockTimeout', null, null, 0);
     $generatorJava.enumProperty(res, varName, cache, 'atomicWriteOrderMode', 'org.apache.ignite.cache.CacheAtomicWriteOrderMode');
-    $generatorJava.enumProperty(res, varName, cache, 'writeSynchronizationMode', 'org.apache.ignite.cache.CacheWriteSynchronizationMode', null, null, "PRIMARY_SYNC");
+    $generatorJava.enumProperty(res, varName, cache, 'writeSynchronizationMode', 'org.apache.ignite.cache.CacheWriteSynchronizationMode', null, null, 'PRIMARY_SYNC');
 
     res.needEmptyLine = true;
 
@@ -1421,7 +1657,7 @@ $generatorJava.cacheConcurrency = function (cache, varName, res) {
 };
 
 // Generate cache rebalance group.
-$generatorJava.cacheRebalance = function (cache, varName, res) {
+$generatorJava.cacheRebalance = function(cache, varName, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1451,7 +1687,7 @@ $generatorJava.cacheRebalance = function (cache, varName, res) {
 };
 
 // Generate cache server near cache group.
-$generatorJava.cacheServerNearCache = function (cache, varName, res) {
+$generatorJava.cacheServerNearCache = function(cache, varName, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1488,7 +1724,7 @@ $generatorJava.cacheServerNearCache = function (cache, varName, res) {
 };
 
 // Generate cache statistics group.
-$generatorJava.cacheStatistics = function (cache, varName, res) {
+$generatorJava.cacheStatistics = function(cache, varName, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1504,13 +1740,13 @@ $generatorJava.cacheStatistics = function (cache, varName, res) {
 };
 
 // Generate domain model query fields.
-$generatorJava.domainModelQueryFields = function (res, domain) {
-    var fields = domain.fields;
+$generatorJava.domainModelQueryFields = function(res, domain) {
+    const fields = domain.fields;
 
     if (fields && fields.length > 0) {
         $generatorJava.declareVariable(res, 'fields', 'java.util.LinkedHashMap', 'java.util.LinkedHashMap', 'java.lang.String', 'java.lang.String');
 
-        _.forEach(fields, function (field) {
+        _.forEach(fields, function(field) {
             res.line('fields.put("' + field.name + '", "' + $generatorCommon.JavaTypes.fullClassName(field.className) + '");');
         });
 
@@ -1523,13 +1759,13 @@ $generatorJava.domainModelQueryFields = function (res, domain) {
 };
 
 // Generate domain model query aliases.
-$generatorJava.domainModelQueryAliases = function (res, domain) {
-    var aliases = domain.aliases;
+$generatorJava.domainModelQueryAliases = function(res, domain) {
+    const aliases = domain.aliases;
 
     if (aliases && aliases.length > 0) {
         $generatorJava.declareVariable(res, 'aliases', 'java.util.Map', 'java.util.HashMap', 'java.lang.String', 'java.lang.String');
 
-        _.forEach(aliases, function (alias) {
+        _.forEach(aliases, function(alias) {
             res.line('aliases.put("' + alias.field + '", "' + alias.alias + '");');
         });
 
@@ -1542,20 +1778,20 @@ $generatorJava.domainModelQueryAliases = function (res, domain) {
 };
 
 // Generate domain model indexes.
-$generatorJava.domainModelQueryIndexes = function (res, domain) {
-    var indexes = domain.indexes;
+$generatorJava.domainModelQueryIndexes = function(res, domain) {
+    const indexes = domain.indexes;
 
     if (indexes && indexes.length > 0) {
         res.needEmptyLine = true;
 
         $generatorJava.declareVariable(res, 'indexes', 'java.util.List', 'java.util.ArrayList', 'org.apache.ignite.cache.QueryIndex');
 
-        _.forEach(indexes, function (index) {
-            var fields = index.fields;
+        _.forEach(indexes, function(index) {
+            const fields = index.fields;
 
             // One row generation for 1 field index.
             if (fields && fields.length === 1) {
-                var field = index.fields[0];
+                const field = index.fields[0];
 
                 res.line('indexes.add(new ' + res.importClass('org.apache.ignite.cache.QueryIndex') +
                     '("' + field.name + '", ' +
@@ -1597,8 +1833,8 @@ $generatorJava.domainModelQueryIndexes = function (res, domain) {
 };
 
 // Generate domain model db fields.
-$generatorJava.domainModelDatabaseFields = function (res, domain, fieldProperty) {
-    var dbFields = domain[fieldProperty];
+$generatorJava.domainModelDatabaseFields = function(res, domain, fieldProperty) {
+    const dbFields = domain[fieldProperty];
 
     if (dbFields && dbFields.length > 0) {
         res.needEmptyLine = true;
@@ -1607,14 +1843,14 @@ $generatorJava.domainModelDatabaseFields = function (res, domain, fieldProperty)
 
         res.startBlock('jdbcType.' + $generatorCommon.toJavaName('set', fieldProperty) + '(');
 
-        var lastIx = dbFields.length - 1;
+        const lastIx = dbFields.length - 1;
 
         res.importClass('org.apache.ignite.cache.store.jdbc.JdbcTypeField');
 
-        _.forEach(dbFields, function (field, ix) {
+        _.forEach(dbFields, function(field, ix) {
             res.line('new JdbcTypeField(' +
                 'Types.' + field.databaseFieldType + ', ' + '"' + field.databaseFieldName + '", ' +
-                res.importClass(field.javaFieldType) + '.class, ' + '"' + field.javaFieldName + '"'+ ')' + (ix < lastIx ? ',' : ''));
+                res.importClass(field.javaFieldType) + '.class, ' + '"' + field.javaFieldName + '"' + ')' + (ix < lastIx ? ',' : ''));
         });
 
         res.endBlock(');');
@@ -1624,14 +1860,14 @@ $generatorJava.domainModelDatabaseFields = function (res, domain, fieldProperty)
 };
 
 // Generate domain model general group.
-$generatorJava.domainModelGeneral = function (domain, res) {
+$generatorJava.domainModelGeneral = function(domain, res) {
     if (!res)
         res = $generatorCommon.builder();
 
     switch ($generatorCommon.domainQueryMetadata(domain)) {
         case 'Annotations':
             if ($generatorCommon.isDefinedAndNotEmpty(domain.keyType) || $generatorCommon.isDefinedAndNotEmpty(domain.valueType)) {
-                var types = [];
+                const types = [];
 
                 if ($generatorCommon.isDefinedAndNotEmpty(domain.keyType))
                     types.push($generatorJava.toJavaCode(res.importClass(domain.keyType), 'class'));
@@ -1643,13 +1879,8 @@ $generatorJava.domainModelGeneral = function (domain, res) {
                 else
                     types.push('???');
 
-                if ($generatorCommon.isDefinedAndNotEmpty(types)) {
-                    res.startBlock('cache.setIndexedTypes(');
-
-                    res.line(types.join(', '));
-
-                    res.endBlock(');');
-                }
+                if ($generatorCommon.isDefinedAndNotEmpty(types))
+                    $generatorJava.fxVarArgs(res, 'cache.setIndexedTypes', false, types);
             }
 
             break;
@@ -1666,6 +1897,8 @@ $generatorJava.domainModelGeneral = function (domain, res) {
             }
 
             break;
+
+        default:
     }
 
     res.needEmptyLine = true;
@@ -1674,7 +1907,7 @@ $generatorJava.domainModelGeneral = function (domain, res) {
 };
 
 // Generate domain model for query group.
-$generatorJava.domainModelQuery = function (domain, res) {
+$generatorJava.domainModelQuery = function(domain, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1690,7 +1923,7 @@ $generatorJava.domainModelQuery = function (domain, res) {
 };
 
 // Generate domain model for store group.
-$generatorJava.domainStore = function (domain, withTypes, res) {
+$generatorJava.domainStore = function(domain, withTypes, res) {
     if (!res)
         res = $generatorCommon.builder();
 
@@ -1711,11 +1944,11 @@ $generatorJava.domainStore = function (domain, withTypes, res) {
 };
 
 // Generate domain model configs.
-$generatorJava.cacheDomains = function (domains, varName, res) {
+$generatorJava.cacheDomains = function(domains, varName, 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);
     });
@@ -1724,7 +1957,7 @@ $generatorJava.cacheDomains = function (domains, varName, res) {
     if ($generatorCommon.isDefinedAndNotEmpty(domainConfigs)) {
         $generatorJava.declareVariable(res, 'queryEntities', 'java.util.Collection', 'java.util.ArrayList', 'org.apache.ignite.cache.QueryEntity');
 
-        _.forEach(domainConfigs, function (domain) {
+        _.forEach(domainConfigs, function(domain) {
             if ($generatorCommon.isDefinedAndNotEmpty(domain.fields))
                 res.line('queryEntities.add(queryEntity' + $generatorJava.extractType(domain.valueType) + '());');
         });
@@ -1756,20 +1989,20 @@ $generatorJava.cache = function(cache, varName, res) {
 };
 
 // Generation of cache domain model in separate methods.
-$generatorJava.clusterDomains = function (caches, res) {
-    var domains = [];
+$generatorJava.clusterDomains = function(caches, res) {
+    const domains = [];
 
-    var typeVarName = 'jdbcType';
-    var metaVarName = 'qryMeta';
+    const typeVarName = 'jdbcType';
+    const metaVarName = 'qryMeta';
 
-    _.forEach(caches, function (cache) {
-        _.forEach(cache.domains, function (domain) {
-            if (_.isNil(_.find(domains, function (m) {
-                    return m === domain.valueType;
-                }))) {
+    _.forEach(caches, function(cache) {
+        _.forEach(cache.domains, function(domain) {
+            if (_.isNil(_.find(domains, function(m) {
+                return m === domain.valueType;
+            }))) {
                 $generatorJava.resetVariables(res);
 
-                var type = $generatorJava.extractType(domain.valueType);
+                const type = $generatorJava.extractType(domain.valueType);
 
                 if ($generatorCommon.isDefinedAndNotEmpty(domain.databaseTable)) {
                     res.line('/**');
@@ -1833,18 +2066,15 @@ $generatorJava.clusterDomains = function (caches, res) {
  * @param obj Object to process.
  * @param names Known names to generate next unique name.
  */
-$generatorJava.nextVariableName = function (prefix, obj, names) {
-    var nextName = $generatorCommon.toJavaName(prefix, obj.name);
+$generatorJava.nextVariableName = function(prefix, obj, names) {
+    let nextName = $generatorCommon.toJavaName(prefix, obj.name);
 
-    var checkNextName = function (name) {
-        return name === nextName + (ix === 0 ? '' : '_' + ix);
-    };
+    let ix = 0;
 
-    var ix = 0;
+    const checkNextName = (name) => name === nextName + (ix === 0 ? '' : '_' + ix);
 
-    while (_.find(names, checkNextName)) {
-        ix ++;
-    }
+    while (_.find(names, (name) => checkNextName(name)))
+        ix++;
 
     if (ix > 0)
         nextName = nextName + '_' + ix;
@@ -1853,15 +2083,15 @@ $generatorJava.nextVariableName = function (prefix, obj, names) {
 };
 
 // Generate cluster caches.
-$generatorJava.clusterCaches = function (caches, igfss, isSrvCfg, res) {
-    function clusterCache(res, cache, names) {
+$generatorJava.clusterCaches = function(caches, igfss, isSrvCfg, res) {
+    function clusterCache(cache, names) {
         res.emptyLineIfNeeded();
 
-        var cacheName = $generatorJava.nextVariableName('cache', cache, names);
+        const cacheName = $generatorJava.nextVariableName('cache', cache, names);
 
         $generatorJava.resetVariables(res);
 
-        var hasDatasource = $generatorCommon.cacheHasDatasource(cache);
+        const hasDatasource = $generatorCommon.cacheHasDatasource(cache);
 
         res.line('/**');
         res.line(' * Create configuration for cache "' + cache.name + '".');
@@ -1889,13 +2119,13 @@ $generatorJava.clusterCaches = function (caches, igfss, isSrvCfg, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    var names = [];
+    const names = [];
 
     if ($generatorCommon.isDefinedAndNotEmpty(caches)) {
         res.emptyLineIfNeeded();
 
-        _.forEach(caches, function (cache) {
-            clusterCache(res, cache, names);
+        _.forEach(caches, function(cache) {
+            clusterCache(cache, names);
         });
 
         res.needEmptyLine = true;
@@ -1904,9 +2134,9 @@ $generatorJava.clusterCaches = function (caches, igfss, isSrvCfg, res) {
     if (isSrvCfg && $generatorCommon.isDefinedAndNotEmpty(igfss)) {
         res.emptyLineIfNeeded();
 
-        _.forEach(igfss, function (igfs) {
-            clusterCache(res, $generatorCommon.igfsDataCache(igfs), names);
-            clusterCache(res, $generatorCommon.igfsMetaCache(igfs), names);
+        _.forEach(igfss, function(igfs) {
+            clusterCache($generatorCommon.igfsDataCache(igfs), names);
+            clusterCache($generatorCommon.igfsMetaCache(igfs), names);
         });
 
         res.needEmptyLine = true;
@@ -1916,33 +2146,31 @@ $generatorJava.clusterCaches = function (caches, igfss, isSrvCfg, res) {
 };
 
 // Generate cluster caches.
-$generatorJava.clusterCacheUse = function (caches, igfss, res) {
+$generatorJava.clusterCacheUse = function(caches, igfss, res) {
     function clusterCacheInvoke(cache, names) {
-        names.push($generatorJava.nextVariableName('cache', cache, names) + '()');
+        names.push($generatorJava.nextVariableName('cache', cache, names));
     }
 
     if (!res)
         res = $generatorCommon.builder();
 
-    var names = [];
+    const cacheNames = [];
 
-    _.forEach(caches, function (cache) {
-        clusterCacheInvoke(cache, names);
+    _.forEach(caches, function(cache) {
+        clusterCacheInvoke(cache, cacheNames);
     });
 
-    var igfsNames = [];
+    const igfsNames = [];
 
-    _.forEach(igfss, function (igfs) {
+    _.forEach(igfss, function(igfs) {
         clusterCacheInvoke($generatorCommon.igfsDataCache(igfs), igfsNames);
         clusterCacheInvoke($generatorCommon.igfsMetaCache(igfs), igfsNames);
     });
 
-    if (names.length > 0 || igfsNames.length > 0) {
-        _.forEach(igfsNames, function (igfsName) {
-            names.push(igfsName);
-        });
+    const allCacheNames = cacheNames.concat(igfsNames);
 
-        res.line('cfg.setCacheConfiguration(' + names.join(', ') + ');');
+    if (allCacheNames.length) {
+        res.line('cfg.setCacheConfiguration(' + allCacheNames.join('(), ') + '());');
 
         res.needEmptyLine = true;
     }
@@ -1951,7 +2179,7 @@ $generatorJava.clusterCacheUse = function (caches, igfss, res) {
 };
 
 // Get class name from fully specified class path.
-$generatorJava.extractType = function (fullType) {
+$generatorJava.extractType = function(fullType) {
     return fullType.substring(fullType.lastIndexOf('.') + 1);
 };
 
@@ -1965,11 +2193,11 @@ $generatorJava.extractType = function (fullType) {
  * @param includeKeyFields If 'true' then include key fields into value POJO.
  * @param res Resulting output with generated code.
  */
-$generatorJava.javaClassCode = function (domain, key, pkg, useConstructor, includeKeyFields, res) {
+$generatorJava.javaClassCode = function(domain, key, pkg, useConstructor, includeKeyFields, res) {
     if (!res)
         res = $generatorCommon.builder();
 
-    var type = $generatorJava.extractType(key ? domain.keyType : domain.valueType);
+    const type = $generatorJava.extractType(key ? domain.keyType : domain.valueType);
 
     // Class comment.
     res.line('/**');
@@ -1984,19 +2212,18 @@ $generatorJava.javaClassCode = function (domain, key, pkg, useConstructor, inclu
     res.line('private static final long serialVersionUID = 0L;');
     res.needEmptyLine = true;
 
-    var allFields = (key || includeKeyFields) ? domain.keyFields.slice() : [];
+    const allFields = (key || includeKeyFields) ? domain.keyFields.slice() : [];
 
-    if (!key)
-        _.forEach(domain.valueFields, function (valFld) {
-            if (_.findIndex(allFields, function(fld) {
-                return fld.javaFieldName === valFld.javaFieldName;
-            }) < 0)
+    if (!key) {
+        _.forEach(domain.valueFields, (valFld) => {
+            if (_.findIndex(allFields, (fld) => fld.javaFieldName === valFld.javaFieldName) < 0)
                 allFields.push(valFld);
         });
+    }
 
     // Generate allFields declaration.
-    _.forEach(allFields, function (field) {
-        var fldName = field.javaFieldName;
+    _.forEach(allFields, function(field) {
+        const fldName = field.javaFieldName;
 
         res.line('/** Value for ' + fldName + '. */');
 
@@ -2029,9 +2256,7 @@ $generatorJava.javaClassCode = function (domain, key, pkg, useConstructor, inclu
 
         res.startBlock();
 
-        _.forEach(allFields, function (field) {
-            res.line('this.' + field.javaFieldName +' = ' + field.javaFieldName + ';');
-        });
+        _.forEach(allFields, (field) => res.line('this.' + field.javaFieldName + ' = ' + field.javaFieldName + ';'));
 
         res.endBlock('}');
 
@@ -2039,10 +2264,10 @@ $generatorJava.javaClassCode = function (domain, key, pkg, useConstructor, inclu
     }
 
     // Generate getters and setters methods.
-    _.forEach(allFields, function (field) {
-        var fldName = field.javaFieldName;
+    _.forEach(allFields, function(field) {
+        const fldName = field.javaFieldName;
 
-        var fldType = res.importClass(field.javaFieldType);
+        const fldType = res.importClass(field.javaFieldType);
 
         res.line('/**');
         res.line(' * Gets ' + fldName + '.');
@@ -2083,16 +2308,16 @@ $generatorJava.javaClassCode = function (domain, key, pkg, useConstructor, inclu
 
     res.line(type + ' that = (' + type + ')o;');
 
-    _.forEach(allFields, function (field) {
+    _.forEach(allFields, function(field) {
         res.needEmptyLine = true;
 
-        var javaName = field.javaFieldName;
-        var javaType = field.javaFieldType;
+        const javaName = field.javaFieldName;
+        const javaType = field.javaFieldType;
 
         if ($generatorCommon.JavaTypes.isJavaPrimitive(javaType)) {
-            if ('float' === javaType)
+            if (javaType === 'float')
                 res.startBlock('if (Float.compare(' + javaName + ', that.' + javaName + ') != 0)');
-            else if ('double' === javaType)
+            else if (javaType === 'double')
                 res.startBlock('if (Double.compare(' + javaName + ', that.' + javaName + ') != 0)');
             else
                 res.startBlock('if (' + javaName + ' != that.' + javaName + ')');
@@ -2115,34 +2340,35 @@ $generatorJava.javaClassCode = function (domain, key, pkg, useConstructor, inclu
     res.line('/** {@inheritDoc} */');
     res.startBlock('@Override public int hashCode() {');
 
-    var first = true;
-    var tempVar = false;
+    let first = true;
+    let tempVar = false;
 
-    _.forEach(allFields, function (field) {
-        var javaName = field.javaFieldName;
-        var javaType = field.javaFieldType;
+    _.forEach(allFields, function(field) {
+        const javaName = field.javaFieldName;
+        const javaType = field.javaFieldType;
 
         if (!first)
             res.needEmptyLine = true;
 
         if ($generatorCommon.JavaTypes.isJavaPrimitive(javaType)) {
-            if ('boolean' === javaType)
+            if (javaType === 'boolean')
                 res.line(first ? 'int res = ' + javaName + ' ? 1 : 0;' : 'res = 31 * res + (' + javaName + ' ? 1 : 0);');
-            else if ('byte' === javaType || 'short' === javaType)
+            else if (javaType === 'byte' || javaType === 'short')
                 res.line(first ? 'int res = (int)' + javaName + ';' : 'res = 31 * res + (int)' + javaName + ';');
-            else if ('int' === javaType)
+            else if (javaType === 'int')
                 res.line(first ? 'int res = ' + javaName + ';' : 'res = 31 * res + ' + javaName + ';');
-            else if ('long' === javaType)
+            else if (javaType === 'long') {
                 res.line(first
                     ? 'int res = (int)(' + javaName + ' ^ (' + javaName + ' >>> 32));'
                     : 'res = 31 * res + (int)(' + javaName + ' ^ (' + javaName + ' >>> 32));');
-            else if ('float' === javaType)
+            }
+            else if (javaType === 'float') {
                 res.line(first
                     ? 'int res = ' + javaName + ' != +0.0f ? Float.floatToIntBits(' + javaName + ') : 0;'
                     : 'res = 31 * res + (' + javaName + ' != +0.0f ? Float.floatToIntBits(' + javaName + ') : 0);');
-            else if ('double' === javaType) {
-                res.line((tempVar ? 'ig_hash_temp' : 'long ig_hash_temp') +
-                        ' = Double.doubleToLongBits(' + javaName + ');');
+            }
+            else if (javaType === 'double') {
+                res.line((tempVar ? 'ig_hash_temp' : 'long ig_hash_temp') + ' = Double.doubleToLongBits(' + javaName + ');');
 
                 res.needEmptyLine = true;
 
@@ -2150,12 +2376,14 @@ $generatorJava.javaClassCode = function (domain, key, pkg, useConstructor, inclu
                         ? 'int res = (int)(ig_hash_temp ^ (ig_hash_temp >>> 32));'
                         : 'res = 31 * res + (int)(ig_hash_temp ^ (ig_hash_temp >>> 32));');
 
-                    tempVar = true;
+                tempVar = true;
             }
         }
-        else
-            res.line(first ? 'int res = ' + javaName + ' != null ? ' + javaName + '.hashCode() : 0;'
+        else {
+            res.line(first
+                ? 'int res = ' + javaName + ' != null ? ' + javaName + '.hashCode() : 0;'
                 : 'res = 31 * res + (' + javaName + ' != null ? ' + javaName + '.hashCode() : 0);');
+        }
 
         first = false;
     });
@@ -2171,7 +2399,7 @@ $generatorJava.javaClassCode = function (domain, key, pkg, useConstructor, inclu
 
     res.startBlock('return \"' + type + ' [" + ');
 
-    _.forEach(allFields, function (field, idx) {
+    _.forEach(allFields, function(field, idx) {
         res.line('\"' + field.javaFieldName + '=\" + ' + field.javaFieldName + (idx < allFields.length - 1 ? ' + ", " + ' : ' +'));
     });
 
@@ -2190,8 +2418,8 @@ $generatorJava.javaClassCode = function (domain, key, pkg, useConstructor, inclu
  * @param useConstructor If 'true' then generate constructors.
  * @param includeKeyFields If 'true' then include key fields into value POJO.
  */
-$generatorJava.pojos = function (caches, useConstructor, includeKeyFields) {
-    var pojos = [];
+$generatorJava.pojos = function(caches, useConstructor, includeKeyFields) {
+    const pojos = [];
 
     _.forEach(caches, function(cache) {
         _.forEach(cache.domains, function(domain) {
@@ -2199,7 +2427,7 @@ $generatorJava.pojos = function (caches, useConstructor, includeKeyFields) {
             if (!_.find(pojos, {valueType: domain.valueType}) &&
                 // Skip domain models without value fields.
                 $generatorCommon.isDefinedAndNotEmpty(domain.valueFields)) {
-                var pojo = {};
+                const pojo = {};
 
                 // Key class generation only if key is not build in java class.
                 if (!_.isNil(domain.keyFields) && domain.keyFields.length > 0) {
@@ -2225,11 +2453,11 @@ $generatorJava.pojos = function (caches, useConstructor, includeKeyFields) {
  * @returns Field java type name.
  */
 $generatorJava.javaTypeName = function(type) {
-    var ix = $generatorJava.javaBuiltInClasses.indexOf(type);
+    const ix = $generatorJava.javaBuiltInClasses.indexOf(type);
 
-    var resType = ix >= 0 ? $generatorJava.javaBuiltInFullNameClasses[ix] : type;
+    const resType = ix >= 0 ? $generatorJava.javaBuiltInFullNameClasses[ix] : type;
 
-    return resType.indexOf("java.lang.") >= 0 ? resType.substring(10) : resType;
+    return resType.indexOf('java.lang.') >= 0 ? resType.substring(10) : resType;
 };
 
 /**
@@ -2251,7 +2479,7 @@ $generatorJava.clusterSsl = function(cluster, res) {
         cluster.sslContextFactory.trustStorePassword = $generatorCommon.isDefinedAndNotEmpty(cluster.sslContextFactory.trustStoreFilePath) ?
             'props.getProperty("ssl.trust.storage.password").toCharArray()' : null;
 
-        var propsDesc = $generatorCommon.isDefinedAndNotEmpty(cluster.sslContextFactory.trustManagers) ?
+        const propsDesc = $generatorCommon.isDefinedAndNotEmpty(cluster.sslContextFactory.trustManagers) ?
             $generatorCommon.SSL_CONFIGURATION_TRUST_MANAGER_FACTORY.fields :
             $generatorCommon.SSL_CONFIGURATION_TRUST_FILE_FACTORY.fields;
 
@@ -2279,8 +2507,8 @@ $generatorJava.igfss = function(igfss, varName, res) {
     if ($generatorCommon.isDefinedAndNotEmpty(igfss)) {
         res.emptyLineIfNeeded();
 
-        var arrayName = 'fileSystems';
-        var igfsInst = 'igfs';
+        const arrayName = 'fileSystems';
+        const igfsInst = 'igfs';
 
         res.line(res.importClass('org.apache.ignite.configuration.FileSystemConfiguration') + '[] ' + arrayName + ' = new FileSystemConfiguration[' + igfss.length + '];');
 
@@ -2323,7 +2551,7 @@ $generatorJava.igfsIPC = function(igfs, varName, res) {
         varName = $generatorJava.nextVariableName('igfs', igfs);
 
     if (igfs.ipcEndpointEnabled) {
-        var desc = $generatorCommon.IGFS_IPC_CONFIGURATION;
+        const desc = $generatorCommon.IGFS_IPC_CONFIGURATION;
 
         $generatorJava.beanProperty(res, varName, igfs.ipcEndpointConfiguration, 'ipcEndpointConfiguration', 'ipcEndpointCfg',
             desc.className, desc.fields, true);
@@ -2397,10 +2625,10 @@ $generatorJava.igfsSecondFS = function(igfs, varName, res) {
         varName = $generatorJava.nextVariableName('igfs', igfs);
 
     if (igfs.secondaryFileSystemEnabled) {
-        var secondFs = igfs.secondaryFileSystem || {};
+        const secondFs = igfs.secondaryFileSystem || {};
 
-        var nameDefined = $generatorCommon.isDefinedAndNotEmpty(secondFs.userName);
-        var cfgDefined = $generatorCommon.isDefinedAndNotEmpty(secondFs.cfgPath);
+        const nameDefined = $generatorCommon.isDefinedAndNotEmpty(secondFs.userName);
+        const cfgDefined = $generatorCommon.isDefinedAndNotEmpty(secondFs.cfgPath);
 
         res.line(varName + '.setSecondaryFileSystem(new ' +
             res.importClass('org.apache.ignite.hadoop.fs.IgniteHadoopIgfsSecondaryFileSystem') + '(' +
@@ -2437,7 +2665,7 @@ $generatorJava.igfsGeneral = function(igfs, varName, res) {
         $generatorJava.property(res, varName, igfs, 'name');
         $generatorJava.property(res, varName, igfs, 'dataCacheName');
         $generatorJava.property(res, varName, igfs, 'metaCacheName');
-        $generatorJava.enumProperty(res, varName, igfs, 'defaultMode', 'org.apache.ignite.igfs.IgfsMode', null, "DUAL_ASYNC");
+        $generatorJava.enumProperty(res, varName, igfs, 'defaultMode', 'org.apache.ignite.igfs.IgfsMode', null, 'DUAL_ASYNC');
 
         res.needEmptyLine = true;
     }
@@ -2478,8 +2706,8 @@ $generatorJava.igfsMisc = function(igfs, varName, res) {
 
         $generatorJava.declareVariable(res, 'pathModes', 'java.util.Map', 'java.util.HashMap', 'String', 'org.apache.ignite.igfs.IgfsMode');
 
-        _.forEach(igfs.pathModes, function (pair) {
-            res.line('pathModes.put("' + pair.path + '", IgfsMode.' + pair.mode +');');
+        _.forEach(igfs.pathModes, function(pair) {
+            res.line('pathModes.put("' + pair.path + '", IgfsMode.' + pair.mode + ');');
         });
 
         res.needEmptyLine = true;
@@ -2492,13 +2720,15 @@ $generatorJava.igfsMisc = function(igfs, varName, res) {
     return res;
 };
 
-$generatorJava.clusterConfiguration = function (cluster, clientNearCfg, res) {
+$generatorJava.clusterConfiguration = function(cluster, clientNearCfg, res) {
     $generatorJava.clusterGeneral(cluster, clientNearCfg, res);
 
     $generatorJava.clusterAtomics(cluster.atomicConfiguration, res);
 
     $generatorJava.clusterBinary(cluster.binaryConfiguration, res);
 
+    $generatorJava.clusterCollision(cluster.collision, res);
+
     $generatorJava.clusterCommunication(cluster, res);
 
     $generatorJava.clusterConnector(cluster.connector, res);
@@ -2507,6 +2737,10 @@ $generatorJava.clusterConfiguration = function (cluster, clientNearCfg, res) {
 
     $generatorJava.clusterEvents(cluster, res);
 
+    $generatorJava.clusterFailover(cluster, res);
+
+    $generatorJava.clusterLogger(cluster.logger, res);
+
     $generatorJava.clusterMarshaller(cluster, res);
 
     $generatorJava.clusterMetrics(cluster, res);
@@ -2519,7 +2753,7 @@ $generatorJava.clusterConfiguration = function (cluster, clientNearCfg, res) {
 
     $generatorJava.clusterTransactions(cluster.transactionConfiguration, res);
 
-    var isSrvCfg = _.isNil(clientNearCfg);
+    const isSrvCfg = _.isNil(clientNearCfg);
 
     if (isSrvCfg)
         $generatorJava.clusterCacheUse(cluster.caches, cluster.igfss, res);
@@ -2529,11 +2763,13 @@ $generatorJava.clusterConfiguration = function (cluster, clientNearCfg, res) {
     if (isSrvCfg)
         $generatorJava.igfss(cluster.igfss, 'cfg', res);
 
+    $generatorJava.clusterUserAttributes(cluster, res);
+
     return res;
 };
 
 // Generate loading of secret properties file.
-$generatorJava.tryLoadSecretProperties = function (cluster, res) {
+$generatorJava.tryLoadSecretProperties = function(cluster, res) {
     if ($generatorCommon.secretPropertiesNeeded(cluster)) {
         res.importClass('org.apache.ignite.configuration.IgniteConfiguration');
 
@@ -2560,13 +2796,13 @@ $generatorJava.tryLoadSecretProperties = function (cluster, res) {
  * @param javaClass Class name for generate factory class otherwise generate code snippet.
  * @param clientNearCfg Optional near cache configuration for client node.
  */
-$generatorJava.cluster = function (cluster, pkg, javaClass, clientNearCfg) {
-    var res = $generatorCommon.builder();
+$generatorJava.cluster = function(cluster, pkg, javaClass, clientNearCfg) {
+    const res = $generatorCommon.builder();
 
-    var isSrvCfg = _.isNil(clientNearCfg);
+    const isSrvCfg = _.isNil(clientNearCfg);
 
     if (cluster) {
-        var resCfg = $generatorJava.clusterConfiguration(cluster, clientNearCfg, $generatorCommon.builder());
+        const resCfg = $generatorJava.clusterConfiguration(cluster, clientNearCfg, $generatorCommon.builder());
 
         res.mergeProps(resCfg);
 
@@ -2635,7 +2871,7 @@ $generatorJava.cluster = function (cluster, pkg, javaClass, clientNearCfg) {
 
         res.endBlock('}');
 
-        return 'package ' + pkg + ';\n\n' + res.generateImports() + '\n\n' + res.generateStaticImports()  + '\n\n' + res.asString();
+        return 'package ' + pkg + ';\n\n' + res.generateImports() + '\n\n' + res.generateStaticImports() + '\n\n' + res.asString();
     }
 
     return res.asString();
@@ -2647,15 +2883,15 @@ $generatorJava.cluster = function (cluster, pkg, javaClass, clientNearCfg) {
  * @param storeFactory Store factory for data source class name generation.
  * @returns {*} Data source class name.
  */
-$generatorJava.dataSourceClassName = function (res, storeFactory) {
-    var dialect = storeFactory.connectVia ? (storeFactory.connectVia === 'DataSource' ? storeFactory.dialect : null) : storeFactory.dialect;
+$generatorJava.dataSourceClassName = function(res, storeFactory) {
+    const dialect = storeFactory.connectVia ? (storeFactory.connectVia === 'DataSource' ? storeFactory.dialect : null) : storeFactory.dialect;
 
     if (dialect) {
-        var dataSourceBean = storeFactory.dataSourceBean;
+        const dataSourceBean = storeFactory.dataSourceBean;
 
-        var dsClsName = $generatorCommon.dataSourceClassName(dialect);
+        const dsClsName = $generatorCommon.dataSourceClassName(dialect);
 
-        var varType = res.importClass(dsClsName);
+        const varType = res.importClass(dsClsName);
 
         return $generatorCommon.toJavaName(varType, dataSourceBean);
     }
@@ -2675,14 +2911,12 @@ const PREDEFINED_QUERIES = [
         clearQuery: 'DELETE FROM CARS.PARKING',
         insertCntConsts: [{name: 'DEMO_MAX_PARKING_CNT', val: 5, comment: 'How many parkings to generate.'}],
         insertPattern: ['INSERT INTO CARS.PARKING(ID, NAME, CAPACITY) VALUES(?, ?, ?)'],
-        fillInsertParameters: function (res) {
+        fillInsertParameters(res) {
             res.line('stmt.setInt(1, id);');
             res.line('stmt.setString(2, "Parking #" + (id + 1));');
             res.line('stmt.setInt(3, 10 + rnd.nextInt(20));');
         },
-        selectQuery: [
-            "SELECT * FROM PARKING WHERE CAPACITY >= 20"
-        ]
+        selectQuery: ['SELECT * FROM PARKING WHERE CAPACITY >= 20']
     },
     {
         schema: 'CARS',
@@ -2698,14 +2932,12 @@ const PREDEFINED_QUERIES = [
             {name: 'DEMO_MAX_PARKING_CNT', val: 5, comment: 'How many parkings to generate.'}
         ],
         insertPattern: ['INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(?, ?, ?)'],
-        fillInsertParameters: function (res) {
+        fillInsertParameters(res) {
             res.line('stmt.setInt(1, id);');
             res.line('stmt.setInt(2, rnd.nextInt(DEMO_MAX_PARKING_CNT));');
             res.line('stmt.setString(3, "Car #" + (id + 1));');
         },
-        selectQuery: [
-            "SELECT * FROM CAR WHERE PARKINGID = 2"
-        ]
+        selectQuery: ['SELECT * FROM CAR WHERE PARKINGID = 2']
     },
     {
         type: 'COUNTRY',
@@ -2716,14 +2948,12 @@ const PREDEFINED_QUERIES = [
         clearQuery: 'DELETE FROM COUNTRY',
         insertCntConsts: [{name: 'DEMO_MAX_COUNTRY_CNT', val: 5, comment: 'How many countries to generate.'}],
         insertPattern: ['INSERT INTO COUNTRY(ID, NAME, POPULATION) VALUES(?, ?, ?)'],
-        fillInsertParameters: function (res) {
+        fillInsertParameters(res) {
             res.line('stmt.setInt(1, id);');
             res.line('stmt.setString(2, "Country #" + (id + 1));');
             res.line('stmt.setInt(3, 10000000 + rnd.nextInt(100000000));');
         },
-        selectQuery: [
-            "SELECT * FROM COUNTRY WHERE POPULATION BETWEEN 15000000 AND 25000000"
-        ]
+        selectQuery: ['SELECT * FROM COUNTRY WHERE POPULATION BETWEEN 15000000 AND 25000000']
     },
     {
         type: 'DEPARTMENT',
@@ -2738,14 +2968,12 @@ const PREDEFINED_QUERIES = [
             {name: 'DEMO_MAX_COUNTRY_CNT', val: 5, comment: 'How many countries to generate.'}
         ],
         insertPattern: ['INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(?, ?, ?)'],
-        fillInsertParameters: function (res) {
+        fillInsertParameters(res) {
             res.line('stmt.setInt(1, id);');
             res.line('stmt.setInt(2, rnd.nextInt(DEMO_MAX_COUNTRY_CNT));');
             res.line('stmt.setString(3, "Department #" + (id + 1));');
         },
-        selectQuery: [
-            "SELECT * FROM DEPARTMENT"
-        ]
+        selectQuery: ['SELECT * FROM DEPARTMENT']
     },
     {
         type: 'EMPLOYEE',
@@ -2766,28 +2994,28 @@ const PREDEFINED_QUERIES = [
             {name: 'DEMO_MAX_EMPLOYEE_CNT', val: 10, comment: 'How many employees to generate.'},
             {name: 'DEMO_MAX_DEPARTMENT_CNT', val: 5, comment: 'How many departments to generate.'}
         ],
-        specialGeneration: function (res, conVar) {
-            //$generatorJava.declareVariableCustom(res, 'stmt', 'java.sql.PreparedStatement', conVar +
+        specialGeneration(res, conVar) {
+            // $generatorJava.declareVariableCustom(res, 'stmt', 'java.sql.PreparedStatement', conVar +
             //    '.prepareStatement("INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)")');
             //
-            //res.startBlock('for (int id = 0; id < DEMO_MAX_DEPARTMENT_CNT; id ++) {');
-            //res.line('stmt.setInt(1, id);');
-            //res.line('stmt.setInt(2, id);');
-            //res.line('stmt.setString(3, "First name manager #" + (id + 1));');
-            //res.line('stmt.setString(4, "Last name manager#" + (id + 1));');
-            //res.line('stmt.setString(5, "Email manager#" + (id + 1));');
-            //res.line('stmt.setString(6, "Phone number manager#" + (id + 1));');
-            //res.line('stmt.setString(7, "2014-01-01");');
-            //res.line('stmt.setString(8, "Job manager #" + (id + 1));');
-            //res.line('stmt.setDouble(9, 1000.0 + rnd.nextInt(500));');
+            // res.startBlock('for (int id = 0; id < DEMO_MAX_DEPARTMENT_CNT; id ++) {');
+            // res.line('stmt.setInt(1, id);');
+            // res.line('stmt.setInt(2, id);');
+            // res.line('stmt.setString(3, "First name manager #" + (id + 1));');
+            // res.line('stmt.setString(4, "Last name manager#" + (id + 1));');
+            // res.line('stmt.setString(5, "Email manager#" + (id + 1));');
+            // res.line('stmt.setString(6, "Phone number manager#" + (id + 1));');
+            // res.line('stmt.setString(7, "2014-01-01");');
+            // res.line('stmt.setString(8, "Job manager #" + (id + 1));');
+            // res.line('stmt.setDouble(9, 1000.0 + rnd.nextInt(500));');
             //
-            //res.needEmptyLine = true;
+            // res.needEmptyLine = true;
             //
-            //res.line('stmt.executeUpdate();');
+            // res.line('stmt.executeUpdate();');
             //
-            //res.endBlock('}');
+            // res.endBlock('}');
             //
-            //res.needEmptyLine = true;
+            // res.needEmptyLine = true;
 
             $generatorJava.declareVariableCustom(res, 'stmt', 'java.sql.PreparedStatement', conVar +
                 '.prepareStatement("INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")');
@@ -2817,23 +3045,22 @@ const PREDEFINED_QUERIES = [
 
             res.needEmptyLine = true;
         },
-        selectQuery: [
-            "SELECT * FROM EMPLOYEE WHERE SALARY > 700"
-        ]
+        selectQuery: ['SELECT * FROM EMPLOYEE WHERE SALARY > 700']
     }
 ];
 
 // Generate creation and execution of prepared statement.
 function _prepareStatement(res, conVar, query, select) {
     if (query) {
-        var lines = query.split('\n');
+        const lines = query.split('\n');
 
-        _.forEach(lines, function (line, ix) {
-            if (ix == 0)
-                if (lines.length == 1)
+        _.forEach(lines, function(line, ix) {
+            if (ix === 0) {
+                if (lines.length === 1)
                     res.line(conVar + '.prepareStatement("' + line + '").execute' + (select ? 'Query' : 'Update') + '();');
                 else
                     res.startBlock(conVar + '.prepareStatement("' + line + '" +');
+            }
             else
                 res.line('"' + line + '"' + (ix === lines.length - 1 ? ').execute' + (select ? 'Query' : 'Update') + '();' : ' +'));
         });
@@ -2849,14 +3076,15 @@ function _prepareStatement(res, conVar, query, select) {
 // Generate creation and execution of cache query.
 function _multilineQuery(res, query, prefix, postfix) {
     if (query) {
-        var lines = query.split('\n');
+        const lines = query.split('\n');
 
-        _.forEach(lines, function (line, ix) {
-            if (ix == 0)
-                if (lines.length == 1)
+        _.forEach(lines, function(line, ix) {
+            if (ix === 0) {
+                if (lines.length === 1)
                     res.line(prefix + '"' + line + '"' + postfix);
                 else
                     res.startBlock(prefix + '"' + line + '" +');
+            }
             else
                 res.line('"' + line + '"' + (ix === lines.length - 1 ? postfix : ' +'));
         });
@@ -2879,7 +3107,7 @@ $generatorJava.isDemoConfigured = function(cluster, demo) {
             (desc) => domain.valueType.toUpperCase().endsWith(desc.type))));
 };
 
-$generatorJava.generateDemo = function (cluster, res, factoryCls) {
+$generatorJava.generateDemo = function(cluster, res, factoryCls) {
     const cachesWithDataSource = _.filter(cluster.caches, (cache) => {
         if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) {
             const storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind];
@@ -2892,22 +3120,22 @@ $generatorJava.generateDemo = function (cluster, res, factoryCls) {
     });
 
     // Prepare array of cache and his demo domain model list. Every domain is contained only in first cache.
-    var demoTypes = _.filter(_.map(cachesWithDataSource, (cache, idx) => {
+    const demoTypes = _.filter(_.map(cachesWithDataSource, (cache, idx) => {
         return {
-            cache: cache,
+            cache,
             domains: _.filter(cache.domains, (domain) =>
                 $generatorCommon.isDefinedAndNotEmpty(domain.valueFields) &&
                     !_.find(cachesWithDataSource, (checkCache, checkIx) => checkIx < idx && _.find(checkCache.domains, domain))
             )
-        }
+        };
     }), (cache) => $generatorCommon.isDefinedAndNotEmpty(cache.domains));
 
     if ($generatorCommon.isDefinedAndNotEmpty(demoTypes)) {
-        var typeByDs = {};
+        const typeByDs = {};
 
         // Group domain modes by data source
-        _.forEach(demoTypes, function (type) {
-            var ds = type.cache.cacheStoreFactory[type.cache.cacheStoreFactory.kind].dataSourceBean;
+        _.forEach(demoTypes, function(type) {
+            const ds = type.cache.cacheStoreFactory[type.cache.cacheStoreFactory.kind].dataSourceBean;
 
             if (!typeByDs[ds])
                 typeByDs[ds] = [type];
@@ -2915,16 +3143,14 @@ $generatorJava.generateDemo = function (cluster, res, factoryCls) {
                 typeByDs[ds].push(type);
         });
 
-        var rndDefined = false;
+        let rndDefined = false;
 
-        var generatedConsts = [];
+        const generatedConsts = [];
 
-        _.forEach(typeByDs, function (types) {
-            _.forEach(types, function (type) {
-                _.forEach(type.domains, function (domain) {
-                    var desc = _.find(PREDEFINED_QUERIES, function (desc) {
-                        return domain.valueType.toUpperCase().endsWith(desc.type);
-                    });
+        _.forEach(typeByDs, function(types) {
+            _.forEach(types, function(type) {
+                _.forEach(type.domains, function(domain) {
+                    const desc = _.find(PREDEFINED_QUERIES, (d) => domain.valueType.toUpperCase().endsWith(d.type));
 
                     if (desc) {
                         if (!rndDefined && desc.rndRequired) {
@@ -2934,7 +3160,7 @@ $generatorJava.generateDemo = function (cluster, res, factoryCls) {
                             rndDefined = true;
                         }
 
-                        _.forEach(desc.insertCntConsts, function (cnt) {
+                        _.forEach(desc.insertCntConsts, function(cnt) {
                             if (!_.includes(generatedConsts, cnt.name)) {
                                 res.line('/** ' + cnt.comment + ' */');
                                 res.line('private static final int ' + cnt.name + ' = ' + cnt.val + ';');
@@ -2954,16 +3180,1

<TRUNCATED>

[22/50] [abbrv] ignite git commit: ignite-3212 Remove tx from map if 'onStarted' failed.

Posted by sb...@apache.org.
ignite-3212 Remove tx from map if 'onStarted' failed.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a70ff4c4
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a70ff4c4
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a70ff4c4

Branch: refs/heads/ignite-1232
Commit: a70ff4c40d9f149510b148467b1dd6ce3ad5db0d
Parents: 5e91594
Author: sboikov <sb...@gridgain.com>
Authored: Thu Jun 23 12:13:05 2016 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Thu Jun 23 12:13:05 2016 +0300

----------------------------------------------------------------------
 .../internal/processors/cache/transactions/IgniteTxManager.java  | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a70ff4c4/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index e8d20b6..63c9919 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -568,6 +568,10 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
             ", tx=" + tx + ']';
 
         if (isCompleted(tx)) {
+            ConcurrentMap<GridCacheVersion, IgniteInternalTx> txIdMap = transactionMap(tx);
+
+            txIdMap.remove(tx.xidVersion(), tx);
+
             if (log.isDebugEnabled())
                 log.debug("Attempt to start a completed transaction (will ignore): " + tx);
 


[25/50] [abbrv] ignite git commit: IGNITE-3113: CPP: Binary containers documentation. This closes #711.

Posted by sb...@apache.org.
IGNITE-3113: CPP: Binary containers documentation. This closes #711.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/93445607
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/93445607
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/93445607

Branch: refs/heads/ignite-1232
Commit: 934456070d336fe2a5081f44429ec22d8fc22603
Parents: 5e91594
Author: isapego <is...@gridgain.com>
Authored: Thu Jun 23 15:49:45 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Thu Jun 23 15:49:45 2016 +0300

----------------------------------------------------------------------
 .../include/ignite/binary/binary_containers.h   | 191 +++++++++++++++----
 .../include/ignite/binary/binary_raw_reader.h   |  25 ++-
 .../include/ignite/binary/binary_raw_writer.h   |  13 ++
 .../include/ignite/binary/binary_reader.h       |  13 ++
 .../include/ignite/binary/binary_writer.h       |  13 ++
 .../platforms/cpp/common/include/ignite/date.h  |   2 +-
 .../cpp/common/include/ignite/ignite_error.h    |  19 +-
 .../cpp/common/include/ignite/timestamp.h       |   2 +-
 .../platforms/cpp/common/src/ignite_error.cpp   |  12 +-
 .../cpp/core/include/ignite/cache/cache.h       | 186 ++++++++++++++++--
 .../cpp/core/include/ignite/cache/cache_entry.h |  14 +-
 .../include/ignite/cache/query/query_argument.h |  33 ++--
 .../include/ignite/cache/query/query_cursor.h   |  17 +-
 .../ignite/cache/query/query_fields_cursor.h    |  11 +-
 .../ignite/cache/query/query_fields_row.h       |  22 ++-
 .../include/ignite/cache/query/query_scan.h     |  10 +-
 .../core/include/ignite/cache/query/query_sql.h |  15 +-
 .../ignite/cache/query/query_sql_fields.h       |  15 +-
 .../platforms/cpp/core/include/ignite/ignite.h  |  21 +-
 .../core/include/ignite/ignite_configuration.h  |   4 +-
 .../cpp/core/include/ignite/ignition.h          |   2 +-
 .../include/ignite/transactions/transaction.h   |  68 ++++++-
 .../ignite/transactions/transaction_consts.h    |  84 ++++++--
 .../ignite/transactions/transaction_metrics.h   |  13 +-
 .../include/ignite/transactions/transactions.h  |  36 +++-
 modules/platforms/cpp/core/namespaces.dox       |   2 +-
 modules/platforms/cpp/cpp.dxg                   |   4 +-
 27 files changed, 687 insertions(+), 160 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/binary/include/ignite/binary/binary_containers.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/binary/binary_containers.h b/modules/platforms/cpp/binary/include/ignite/binary/binary_containers.h
index 946101c..8f26416 100644
--- a/modules/platforms/cpp/binary/include/ignite/binary/binary_containers.h
+++ b/modules/platforms/cpp/binary/include/ignite/binary/binary_containers.h
@@ -37,37 +37,51 @@ namespace ignite
     {
         /**
          * Binary string array writer.
+         *
+         * Can be used to write array of strings one by one.
+         *
+         * Use Write() method to write array string by string, then finilize
+         * the writing by calling Close() method. Once the Close() method have
+         * been called, instance is not usable and will throw an IgniteError
+         * on any subsequent attempt to use it.
          */
         class IGNITE_IMPORT_EXPORT BinaryStringArrayWriter
         {
         public:
             /**
              * Constructor.
-             * 
+             * Internal call. Should not be used by user.
+             *
+             * @param impl Writer implementation.
              * @param id Identifier.
-             * @param impl Writer.
              */
             BinaryStringArrayWriter(impl::binary::BinaryWriterImpl* impl, int32_t id);
 
             /**
-             * Write string.
+             * Write null-terminated string.
+             *
+             * @param val Null-terminated character sequence to write.
              *
-             * @param val Null-terminated character sequence.
+             * @throw IgniteError if the writer instance is closed already.
              */
             void Write(const char* val);
 
             /**
              * Write string.
              *
-             * @param val String.
-             * @param len String length (characters).
+             * @param val String to write.
+             * @param len String length in bytes.
+             *
+             * @throw IgniteError if the writer instance is closed already.
              */
             void Write(const char* val, int32_t len);
 
             /**
              * Write string.
              *
-             * @param val String.
+             * @param val String to write.
+             *
+             * @throw IgniteError if the writer instance is closed already.
              */
             void Write(const std::string& val)
             {
@@ -76,18 +90,32 @@ namespace ignite
 
             /**
              * Close the writer.
+             *
+             * This method should be called to finilize writing
+             * of the array.
+             *
+             * @throw IgniteError if the writer instance is closed already.
              */
             void Close();
+
         private:
             /** Implementation delegate. */
             impl::binary::BinaryWriterImpl* impl; 
 
-            /** Idnetifier. */
+            /** Identifier. */
             const int32_t id;    
         };
 
         /**
-         * Binary collection writer.
+         * Binary array writer.
+         *
+         * Can be used to write array of values of the specific type one by
+         * one.
+         *
+         * Use Write() method to write array value by value, then finilize
+         * the writing by calling Close() method. Once the Close() method have
+         * been called, instance is not usable and will throw an IgniteError
+         * on any subsequent attempt to use it.
          */
         template<typename T>
         class IGNITE_IMPORT_EXPORT BinaryArrayWriter
@@ -95,11 +123,13 @@ namespace ignite
         public:
             /**
              * Constructor.
+             * Internal call. Should not be used by user.
              *
-             * @param impl Writer.
+             * @param impl Writer implementation.
              * @param id Identifier.
              */
-            BinaryArrayWriter(impl::binary::BinaryWriterImpl* impl, int32_t id) : impl(impl), id(id)
+            BinaryArrayWriter(impl::binary::BinaryWriterImpl* impl, int32_t id) :
+                impl(impl), id(id)
             {
                 // No-op.
             }
@@ -107,7 +137,9 @@ namespace ignite
             /**
              * Write a value.
              *
-             * @param val Value.
+             * @param val Value to write.
+             *
+             * @throw IgniteError if the writer instance is closed already.
              */
             void Write(const T& val)
             {
@@ -116,11 +148,17 @@ namespace ignite
 
             /**
              * Close the writer.
+             *
+             * This method should be called to finilize writing
+             * of the array.
+             *
+             * @throw IgniteError if the writer instance is closed already.
              */
             void Close()
             {
                 impl->CommitContainer(id);
             }
+
         private:
             /** Implementation delegate. */
             impl::binary::BinaryWriterImpl* impl; 
@@ -131,6 +169,14 @@ namespace ignite
 
         /**
          * Binary collection writer.
+         *
+         * Can be used to write collection of values of the specific type one by
+         * one.
+         *
+         * Use Write() method to write collection value by value, then finilize
+         * the writing by calling Close() method. Once the Close() method have
+         * been called, instance is not usable and will throw an IgniteError
+         * on any subsequent attempt to use it.
          */
         template<typename T>
         class IGNITE_IMPORT_EXPORT BinaryCollectionWriter
@@ -138,11 +184,13 @@ namespace ignite
         public:
             /**
              * Constructor.
+             * Internal call. Should not be used by user.
              *
-             * @param impl Writer.
+             * @param impl Writer implementation.
              * @param id Identifier.
              */
-            BinaryCollectionWriter(impl::binary::BinaryWriterImpl* impl, int32_t id) : impl(impl), id(id)
+            BinaryCollectionWriter(impl::binary::BinaryWriterImpl* impl, int32_t id) :
+                impl(impl), id(id)
             {
                 // No-op.
             }
@@ -150,7 +198,9 @@ namespace ignite
             /**
              * Write a value.
              *
-             * @param val Value.
+             * @param val Value to write.
+             *
+             * @throw IgniteError if the writer instance is closed already.
              */
             void Write(const T& val)
             {
@@ -159,6 +209,11 @@ namespace ignite
 
             /**
              * Close the writer.
+             *
+             * This method should be called to finilize writing
+             * of the collection.
+             *
+             * @throw IgniteError if the writer instance is closed already.
              */
             void Close()
             {
@@ -174,6 +229,13 @@ namespace ignite
 
         /**
          * Binary map writer.
+         *
+         * Can be used to write map element by element.
+         *
+         * Use Write() method to write map value by value, then finilize
+         * the writing by calling Close() method. Once the Close() method have
+         * been called, instance is not usable and will throw an IgniteError
+         * on any subsequent attempt to use it.
          */
         template<typename K, typename V>
         class IGNITE_IMPORT_EXPORT BinaryMapWriter
@@ -181,19 +243,24 @@ namespace ignite
         public:
             /**
              * Constructor.
+             * Internal call. Should not be used by user.
              *
-             * @param impl Writer.
+             * @param impl Writer implementation.
+             * @param id Identifier.
              */
-            BinaryMapWriter(impl::binary::BinaryWriterImpl* impl, int32_t id) : impl(impl), id(id)
+            BinaryMapWriter(impl::binary::BinaryWriterImpl* impl, int32_t id) :
+                impl(impl), id(id)
             {
                 // No-op.
             }
 
             /**
-             * Write a value.
+             * Write a map entry.
+             *
+             * @param key Key element of the map entry.
+             * @param val Value element of the map entry.
              *
-             * @param key Key.
-             * @param val Value.
+             * @throw IgniteError if the writer instance is closed already.
              */
             void Write(const K& key, const V& val)
             {
@@ -202,6 +269,10 @@ namespace ignite
 
             /**
              * Close the writer.
+             *
+             * This method should be called to finilize writing of the map.
+             *
+             * @throw IgniteError if the writer instance is closed already.
              */
             void Close()
             {
@@ -217,14 +288,20 @@ namespace ignite
 
         /**
          * Binary string array reader.
+         *
+         * Can be used to read array of strings string by string.
+         *
+         * Use GetNext() method to read array value by value while HasNext()
+         * method returns true.
          */
         class IGNITE_IMPORT_EXPORT BinaryStringArrayReader
         {
         public:
             /**
              * Constructor.
+             * Internal call. Should not be used by user.
              *
-             * @param impl Reader.
+             * @param impl Reader implementation.
              * @param id Identifier.
              * @param size Array size.
              */
@@ -240,20 +317,24 @@ namespace ignite
             /**
              * Get next element.
              *
-             * @param res Array to store data to. 
+             * @param res Buffer to store data to. 
              * @param len Expected length of string. NULL terminator will be set in case len is 
              *     greater than real string length.
              * @return Actual amount of elements read. If "len" argument is less than actual
              *     array size or resulting array is set to null, nothing will be written
              *     to resulting array and returned value will contain required array length.
              *     -1 will be returned in case array in stream was null.
+             *
+             * @throw IgniteError if there is no element to read.
              */
             int32_t GetNext(char* res, int32_t len);
 
             /**
              * Get next element.
              *
-             * @return String. 
+             * @return String.
+             *
+             * @throw IgniteError if there is no element to read.
              */
             std::string GetNext()
             {
@@ -279,22 +360,30 @@ namespace ignite
             int32_t GetSize() const;
 
             /**
-             * Whether array is NULL.
+             * Check whether array is NULL.
+             *
+             * @return True if the array is NULL.
              */
             bool IsNull() const;
+
         private:
             /** Implementation delegate. */
             impl::binary::BinaryReaderImpl* impl;  
 
             /** Identifier. */
-            const int32_t id;    
+            const int32_t id;
 
             /** Size. */
-            const int32_t size;                              
+            const int32_t size;
         };
 
         /**
          * Binary array reader.
+         *
+         * Can be used to read array of values of the specific type one by one.
+         *
+         * Use GetNext() method to read array value by value while HasNext()
+         * method returns true.
          */
         template<typename T>
         class BinaryArrayReader
@@ -302,8 +391,9 @@ namespace ignite
         public:
             /**
              * Constructor.
+             * Internal call. Should not be used by user.
              *
-             * @param impl Reader.
+             * @param impl Reader implementation.
              * @param id Identifier.
              * @param size Array size.
              */
@@ -327,6 +417,8 @@ namespace ignite
              * Read next element.
              *
              * @return Next element.
+             *
+             * @throw IgniteError if there is no element to read.
              */
             T GetNext()
             {
@@ -344,7 +436,9 @@ namespace ignite
             }
 
             /**
-             * Whether array is NULL.
+             * Check whether array is NULL.
+             *
+             * @return True if the array is NULL.
              */
             bool IsNull()
             {
@@ -363,6 +457,12 @@ namespace ignite
 
         /**
          * Binary collection reader.
+         *
+         * Can be used to read collection of values of the specific type
+         * one by one.
+         *
+         * Use GetNext() method to read array value by value while HasNext()
+         * method returns true.
          */
         template<typename T>
         class BinaryCollectionReader
@@ -370,8 +470,9 @@ namespace ignite
         public:
             /**
              * Constructor.
+             * Internal call. Should not be used by user.
              *
-             * @param impl Reader.
+             * @param impl Reader implementation.
              * @param id Identifier.
              * @param type Collection type.
              * @param size Collection size.
@@ -396,6 +497,8 @@ namespace ignite
              * Read next element.
              *
              * @return Next element.
+             *
+             * @throw IgniteError if there is no element to read.
              */
             T GetNext()
             {
@@ -405,7 +508,8 @@ namespace ignite
             /**
              * Get collection type.
              *
-             * @return Type.
+             * @return Collection type. See CollectionType for the list of
+             *     available values and their description.
              */
             CollectionType GetType()
             {
@@ -423,7 +527,9 @@ namespace ignite
             }
 
             /**
-             * Whether collection is NULL.
+             * Check whether collection is NULL.
+             *
+             * @return True if the collection is NULL.
              */
             bool IsNull()
             {
@@ -445,6 +551,11 @@ namespace ignite
 
         /**
          * Binary map reader.
+         *
+         * Can be used to read map entry by entry.
+         *
+         * Use GetNext() method to read array value by value while HasNext()
+         * method returns true.
          */
         template<typename K, typename V>
         class BinaryMapReader
@@ -452,8 +563,9 @@ namespace ignite
         public:
             /**
              * Constructor.
+             * Internal call. Should not be used by user.
              *
-             * @param impl Reader.
+             * @param impl Reader implementation.
              * @param id Identifier.
              * @param type Map type.
              * @param size Map size.
@@ -477,8 +589,12 @@ namespace ignite
             /**
              * Read next element.
              *
-             * @param key Key.
-             * @param val Value.
+             * @param key Pointer to buffer where key element should be stored.
+             *     Should not be null.
+             * @param val Pointer to buffer where value element should be
+             *     stored. Should not be null.
+             *
+             * @throw IgniteError if there is no element to read.
              */
             void GetNext(K* key, V* val)
             {
@@ -488,7 +604,8 @@ namespace ignite
             /**
              * Get map type.
              *
-             * @return Type.
+             * @return Map type. See MapType for the list of available values
+             *     and their description.
              */
             MapType GetType()
             {
@@ -506,7 +623,9 @@ namespace ignite
             }
 
             /**
-             * Whether map is NULL.
+             * Check whether map is NULL.
+             *
+             * @return True if the map is NULL.
              */
             bool IsNull()
             {

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/binary/include/ignite/binary/binary_raw_reader.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/binary/binary_raw_reader.h b/modules/platforms/cpp/binary/include/ignite/binary/binary_raw_reader.h
index 473be3d..3104437 100644
--- a/modules/platforms/cpp/binary/include/ignite/binary/binary_raw_reader.h
+++ b/modules/platforms/cpp/binary/include/ignite/binary/binary_raw_reader.h
@@ -41,6 +41,17 @@ namespace ignite
     {
         /**
          * Binary raw reader.
+         *
+         * This class implemented as a reference to an implementation so copying
+         * of this class instance will only create another reference to the same
+         * underlying object.
+         *
+         * @note User should not store copy of this instance as it can be
+         *     invalidated as soon as the initially passed to user instance has
+         *     been destructed. For example this means that if user received an
+         *     instance of this class as a function argument then he should not
+         *     store and use copy of this class out of the scope of this
+         *     function.
          */
         class IGNITE_IMPORT_EXPORT BinaryRawReader
         {
@@ -48,6 +59,8 @@ namespace ignite
             /**
              * Constructor.
              *
+             * Internal method. Should not be used by user.
+             *
              * @param impl Implementation.
              */
             BinaryRawReader(ignite::impl::binary::BinaryReaderImpl* impl);
@@ -205,14 +218,14 @@ namespace ignite
             int32_t ReadDoubleArray(double* res, int32_t len);
 
             /**
-             * Read Guid. Maps to "UUID" type in Java.
+             * Read Guid. Maps to "java.util.UUID" type in Java.
              *
              * @return Result.
              */
             Guid ReadGuid();
 
             /**
-             * Read array of Guids. Maps to "UUID[]" type in Java.
+             * Read array of Guids. Maps to "java.util.UUID[]" type in Java.
              *
              * @param res Array to store data to.
              * @param len Expected length of array.             
@@ -224,14 +237,14 @@ namespace ignite
             int32_t ReadGuidArray(Guid* res, int32_t len);
 
             /**
-             * Read Date. Maps to "Date" type in Java.
+             * Read Date. Maps to "java.util.Date" type in Java.
              *
              * @return Result.
              */
             Date ReadDate();
 
             /**
-             * Read array of Dates. Maps to "Date[]" type in Java.
+             * Read array of Dates. Maps to "java.util.Date[]" type in Java.
              *
              * @param res Array to store data to.
              * @param len Expected length of array.             
@@ -243,14 +256,14 @@ namespace ignite
             int32_t ReadDateArray(Date* res, int32_t len);
 
             /**
-             * Read Timestamp. Maps to "Timestamp" type in Java.
+             * Read Timestamp. Maps to "java.sql.Timestamp" type in Java.
              *
              * @return Result.
              */
             Timestamp ReadTimestamp();
 
             /**
-             * Read array of Timestamps. Maps to "Timestamp[]" type in Java.
+             * Read array of Timestamps. Maps to "java.sql.Timestamp[]" type in Java.
              *
              * @param res Array to store data to.
              * @param len Expected length of array.             

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/binary/include/ignite/binary/binary_raw_writer.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/binary/binary_raw_writer.h b/modules/platforms/cpp/binary/include/ignite/binary/binary_raw_writer.h
index 41cfef7..c960406 100644
--- a/modules/platforms/cpp/binary/include/ignite/binary/binary_raw_writer.h
+++ b/modules/platforms/cpp/binary/include/ignite/binary/binary_raw_writer.h
@@ -40,6 +40,17 @@ namespace ignite
     {
         /**
          * Binary raw writer.
+         *
+         * This class implemented as a reference to an implementation so copying
+         * of this class instance will only create another reference to the same
+         * underlying object.
+         *
+         * @note User should not store copy of this instance as it can be
+         *     invalidated as soon as the initially passed to user instance has
+         *     been destructed. For example this means that if user received an
+         *     instance of this class as a function argument then he should not
+         *     store and use copy of this class out of the scope of this
+         *     function.
          */
         class IGNITE_IMPORT_EXPORT BinaryRawWriter
         {
@@ -47,6 +58,8 @@ namespace ignite
             /**
              * Constructor.
              *
+             * Internal method. Should not be used by user.
+             *
              * @param impl Implementation.
              */
             BinaryRawWriter(ignite::impl::binary::BinaryWriterImpl* impl);

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/binary/include/ignite/binary/binary_reader.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/binary/binary_reader.h b/modules/platforms/cpp/binary/include/ignite/binary/binary_reader.h
index 3e5bbb1..ac70f39 100644
--- a/modules/platforms/cpp/binary/include/ignite/binary/binary_reader.h
+++ b/modules/platforms/cpp/binary/include/ignite/binary/binary_reader.h
@@ -39,6 +39,17 @@ namespace ignite
     {
         /**
          * Binary reader.
+         *
+         * This class implemented as a reference to an implementation so copying
+         * of this class instance will only create another reference to the same
+         * underlying object.
+         *
+         * @note User should not store copy of this instance as it can be
+         *     invalidated as soon as the initially passed to user instance has
+         *     been destructed. For example this means that if user received an
+         *     instance of this class as a function argument then he should not
+         *     store and use copy of this class out of the scope of this
+         *     function.
          */
         class IGNITE_IMPORT_EXPORT BinaryReader
         {
@@ -46,6 +57,8 @@ namespace ignite
             /**
              * Constructor.
              *
+             * Internal method. Should not be used by user.
+             *
              * @param impl Implementation.
              */
             BinaryReader(ignite::impl::binary::BinaryReaderImpl* impl);

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/binary/include/ignite/binary/binary_writer.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/binary/binary_writer.h b/modules/platforms/cpp/binary/include/ignite/binary/binary_writer.h
index 1bee82a..1923694 100644
--- a/modules/platforms/cpp/binary/include/ignite/binary/binary_writer.h
+++ b/modules/platforms/cpp/binary/include/ignite/binary/binary_writer.h
@@ -36,6 +36,17 @@ namespace ignite
     {
         /**
          * Binary writer.
+         *
+         * This class implemented as a reference to an implementation so copying
+         * of this class instance will only create another reference to the same
+         * underlying object.
+         *
+         * @note User should not store copy of this instance as it can be
+         *     invalidated as soon as the initially passed to user instance has
+         *     been destructed. For example this means that if user received an
+         *     instance of this class as a function argument then he should not
+         *     store and use copy of this class out of the scope of this
+         *     function.
          */
         class IGNITE_IMPORT_EXPORT BinaryWriter
         {
@@ -43,6 +54,8 @@ namespace ignite
             /**
              * Constructor.
              *
+             * Internal method. Should not be used by user.
+             *
              * @param impl Implementation.
              */
             BinaryWriter(ignite::impl::binary::BinaryWriterImpl* impl);

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/common/include/ignite/date.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/date.h b/modules/platforms/cpp/common/include/ignite/date.h
index 31fe5d0..ffdebd3 100644
--- a/modules/platforms/cpp/common/include/ignite/date.h
+++ b/modules/platforms/cpp/common/include/ignite/date.h
@@ -30,7 +30,7 @@
 namespace ignite
 {
     /**
-     * Date type.
+     * %Date type.
      */
     class IGNITE_IMPORT_EXPORT Date
     {

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/common/include/ignite/ignite_error.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/ignite_error.h b/modules/platforms/cpp/common/include/ignite/ignite_error.h
index edba67a..4c0e263 100644
--- a/modules/platforms/cpp/common/include/ignite/ignite_error.h
+++ b/modules/platforms/cpp/common/include/ignite/ignite_error.h
@@ -76,7 +76,7 @@ namespace ignite
 {
     namespace java
     {
-        /* Error constants. */
+        /* JNI error constants. */
         const int IGNITE_JNI_ERR_SUCCESS = 0;
         const int IGNITE_JNI_ERR_GENERIC = 1;
         const int IGNITE_JNI_ERR_JVM_INIT = 2;
@@ -84,7 +84,7 @@ namespace ignite
     }
 
     /**
-     * Ignite error information.
+     * %Ignite error information.
      */
     class IGNITE_IMPORT_EXPORT IgniteError : public std::exception
     {
@@ -119,7 +119,7 @@ namespace ignite
         /** Binary error. */
         static const int IGNITE_ERR_BINARY = 1002;
 
-        /** Generic Ignite error. */
+        /** Generic %Ignite error. */
         static const int IGNITE_ERR_GENERIC = 2000;
 
         /** Illegal argument passed. */
@@ -202,12 +202,13 @@ namespace ignite
         static void ThrowIfNeeded(IgniteError& err);
 
         /**
-         * Create empty error.
+         * Default constructor.
+         * Creates empty error. Code is IGNITE_SUCCESS and message is NULL.
          */
         IgniteError();
 
         /**
-         * Create error with specific code.
+         * Create error with specific code. Message is set to NULL.
          *
          * @param code Error code.
          */
@@ -232,7 +233,7 @@ namespace ignite
          * Assignment operator.
          *
          * @param other Other instance.
-         * @return Assignment result.
+         * @return *this.
          */
         IgniteError& operator=(const IgniteError& other);
 
@@ -251,7 +252,7 @@ namespace ignite
         /**
          * Get error message.
          *
-         * @return Error message.
+         * @return Error message. Can be NULL.
          */
         const char* GetText() const IGNITE_NO_THROW;
 
@@ -264,12 +265,12 @@ namespace ignite
         virtual const char* what() const IGNITE_NO_THROW;
 
         /**
-         * Set error.
+         * Initializes IgniteError instance from the JNI error.
          *
          * @param jniCode Error code.
          * @param jniCls Error class.
          * @param jniMsg Error message.
-         * @param err Error.
+         * @param err Error. Can not be NULL.
          */
         static void SetError(const int jniCode, const char* jniCls, const char* jniMsg, IgniteError* err);
     private:

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/common/include/ignite/timestamp.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/timestamp.h b/modules/platforms/cpp/common/include/ignite/timestamp.h
index 4528e53..14b83fa 100644
--- a/modules/platforms/cpp/common/include/ignite/timestamp.h
+++ b/modules/platforms/cpp/common/include/ignite/timestamp.h
@@ -32,7 +32,7 @@
 namespace ignite
 {
     /**
-     * Timestamp type.
+     * %Timestamp type.
      */
     class IGNITE_IMPORT_EXPORT Timestamp
     {

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/common/src/ignite_error.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/src/ignite_error.cpp b/modules/platforms/cpp/common/src/ignite_error.cpp
index 722214b..5acbed2 100644
--- a/modules/platforms/cpp/common/src/ignite_error.cpp
+++ b/modules/platforms/cpp/common/src/ignite_error.cpp
@@ -14,6 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <utility>
+
 #include <ignite/ignite_error.h>
 #include <ignite/common/utils.h>
 
@@ -61,14 +63,8 @@ namespace ignite
         {
             IgniteError tmp(other);
 
-            int tmpCode = code;
-            char* tmpMsg = msg;
-            
-            code = tmp.code;
-            msg = tmp.msg;
-
-            tmp.code = tmpCode;
-            tmp.msg = tmpMsg;
+            std::swap(code, tmp.code);
+            std::swap(msg, tmp.msg);
         }
 
         return *this;

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/cache/cache.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/cache.h b/modules/platforms/cpp/core/include/ignite/cache/cache.h
index e60c843..59b7a6a 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/cache.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/cache.h
@@ -46,6 +46,15 @@ namespace ignite
     {
         /**
          * Main entry point for all Data Grid APIs.
+         *
+         * Both key and value types should be default-constructable,
+         * copy-constructable and assignable. Also BinaryType class
+         * template should be specialized for both types.
+         *
+         * This class implemented as a reference to an implementation so copying
+         * of this class instance will only create another reference to the same
+         * underlying object. Underlying object released automatically once all
+         * the instances are destructed.
          */
         template<typename K, typename V>
         class IGNITE_IMPORT_EXPORT Cache
@@ -53,14 +62,23 @@ namespace ignite
         public:
             /**
              * Constructor.
+             *
+             * Internal method. Should not be used by user.
+             *
+             * @param impl Implementation.
              */
-            Cache(impl::cache::CacheImpl* impl) : impl(ignite::common::concurrent::SharedPointer<impl::cache::CacheImpl>(impl))
+            Cache(impl::cache::CacheImpl* impl) :
+                impl(impl)
             {
                 // No-op.
             }
 
             /**
-             * Name of this cache (null for default cache).
+             * Get name of this cache (null for default cache).
+             *
+             * This method should only be used on the valid instance.
+             *
+             * @return Name of this cache (null for default cache).
              */
             const char* GetName() const
             {
@@ -71,6 +89,8 @@ namespace ignite
              * Checks whether this cache contains no key-value mappings.
              * Semantically equals to Cache.Size(IGNITE_PEEK_MODE_PRIMARY) == 0.
              *
+             * This method should only be used on the valid instance.
+             *
              * @return True if cache is empty.
              */
             bool IsEmpty()
@@ -88,6 +108,8 @@ namespace ignite
              * Checks whether this cache contains no key-value mappings.
              * Semantically equals to Cache.Size(IGNITE_PEEK_MODE_PRIMARY) == 0.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param err Error.
              * @return True if cache is empty.
              */
@@ -99,6 +121,8 @@ namespace ignite
             /**
              * Check if cache contains mapping for this key.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key.
              * @return True if cache contains mapping for this key.
              */
@@ -116,6 +140,8 @@ namespace ignite
             /**
              * Check if cache contains mapping for this key.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key.
              * @param err Error.
              * @return True if cache contains mapping for this key.
@@ -130,6 +156,8 @@ namespace ignite
             /**
              * Check if cache contains mapping for these keys.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param keys Keys.
              * @return True if cache contains mapping for all these keys.
              */
@@ -147,6 +175,8 @@ namespace ignite
             /**
              * Check if cache contains mapping for these keys.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param keys Keys.
              * @param err Error.
              * @return True if cache contains mapping for all these keys.
@@ -165,6 +195,8 @@ namespace ignite
              * This method does not participate in any transactions, however, it may peek at transactional
              * value depending on the peek modes used.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key.
              * @param peekModes Peek modes.
              * @return Value.
@@ -187,6 +219,8 @@ namespace ignite
              * This method does not participate in any transactions, however, it may peek at transactional
              * value depending on the peek modes used.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key.
              * @param peekModes Peek modes.
              * @param err Error.
@@ -209,6 +243,8 @@ namespace ignite
              * will be loaded from persistent store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key.
              * @return Value.
              */
@@ -230,6 +266,8 @@ namespace ignite
              * will be loaded from persistent store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key.
              * @param err Error.
              * @return Value.
@@ -251,6 +289,8 @@ namespace ignite
              * will be loaded from persistent store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param keys Keys.
              * @return Map of key-value pairs.
              */
@@ -272,6 +312,8 @@ namespace ignite
              * will be loaded from persistent store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param keys Keys.
              * @param err Error.
              * @return Map of key-value pairs.
@@ -291,6 +333,8 @@ namespace ignite
              * If the cache previously contained a mapping for the key,
              * the old value is replaced by the specified value.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key with which the specified value is to be associated.
              * @param val Value to be associated with the specified key.
              */
@@ -308,6 +352,8 @@ namespace ignite
              * If the cache previously contained a mapping for the key,
              * the old value is replaced by the specified value.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key with which the specified value is to be associated.
              * @param val Value to be associated with the specified key.
              * @param err Error.
@@ -324,6 +370,8 @@ namespace ignite
              * If write-through is enabled, the stored values will be persisted to store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param vals Key-value pairs to store in cache.
              */
             void PutAll(const std::map<K, V>& vals)
@@ -340,6 +388,8 @@ namespace ignite
              * If write-through is enabled, the stored values will be persisted to store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param vals Key-value pairs to store in cache.
              * @param err Error.
              */
@@ -354,6 +404,8 @@ namespace ignite
              * Associates the specified value with the specified key in this cache,
              * returning an existing value if one existed.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key with which the specified value is to be associated.
              * @param val Value to be associated with the specified key.
              * @return The value associated with the key at the start of the
@@ -374,6 +426,8 @@ namespace ignite
              * Associates the specified value with the specified key in this cache,
              * returning an existing value if one existed.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key with which the specified value is to be associated.
              * @param val Value to be associated with the specified key.
              * @param err Error.
@@ -394,6 +448,8 @@ namespace ignite
              * Atomically replaces the value for a given key if and only if there is
              * a value currently mapped by the key.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key with which the specified value is to be associated.
              * @param val Value to be associated with the specified key.
              * @return The previous value associated with the specified key, or
@@ -414,6 +470,8 @@ namespace ignite
              * Atomically replaces the value for a given key if and only if there is
              * a value currently mapped by the key.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key with which the specified value is to be associated.
              * @param val Value to be associated with the specified key.
              * @param err Error.
@@ -433,6 +491,8 @@ namespace ignite
             /**
              * Atomically removes the entry for a key only if currently mapped to some value.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key with which the specified value is associated.
              * @return The value if one existed or null if no mapping existed for this key.
              */
@@ -450,6 +510,8 @@ namespace ignite
             /**
              * Atomically removes the entry for a key only if currently mapped to some value.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key with which the specified value is associated.
              * @param err Error.
              * @return The value if one existed or null if no mapping existed for this key.
@@ -468,6 +530,8 @@ namespace ignite
              * Atomically associates the specified key with the given value if it is not
              * already associated with a value.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key with which the specified value is to be associated.
              * @param val Value to be associated with the specified key.
              * @return True if a value was set.
@@ -487,6 +551,8 @@ namespace ignite
              * Atomically associates the specified key with the given value if it is not
              * already associated with a value.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key with which the specified value is to be associated.
              * @param val Value to be associated with the specified key.
              * @param err Error.
@@ -510,6 +576,8 @@ namespace ignite
              * If write-through is enabled, the stored value will be persisted to store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key to store in cache.
              * @param val Value to be associated with the given key.
              * @return Previously contained value regardless of whether put happened or not
@@ -537,6 +605,8 @@ namespace ignite
              * If write-through is enabled, the stored value will be persisted to store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key to store in cache.
              * @param val Value to be associated with the given key.
              * @param err Error.
@@ -562,6 +632,8 @@ namespace ignite
              * If write-through is enabled, the stored value will be persisted to store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key to store in cache.
              * @param val Value to be associated with the given key.
              * @return True if the value was replaced.
@@ -586,6 +658,8 @@ namespace ignite
              * If write-through is enabled, the stored value will be persisted to store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key to store in cache.
              * @param val Value to be associated with the given key.
              * @param err Error.
@@ -603,6 +677,8 @@ namespace ignite
              * old value passed as argument.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key to store in cache.
              * @param oldVal Old value to match.
              * @param newVal Value to be associated with the given key.
@@ -624,6 +700,8 @@ namespace ignite
              * old value passed as argument.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key to store in cache.
              * @param oldVal Old value to match.
              * @param newVal Value to be associated with the given key.
@@ -638,8 +716,12 @@ namespace ignite
             }
 
             /**
-             * Attempts to evict all entries associated with keys. Note, that entry will be evicted only
-             * if it's not used (not participating in any locks or transactions).
+             * Attempts to evict all entries associated with keys.
+             *
+             * @note Entry will be evicted only if it's not used (not
+             * participating in any locks or transactions).
+             *
+             * This method should only be used on the valid instance.
              *
              * @param keys Keys to evict from cache.
              */
@@ -653,8 +735,12 @@ namespace ignite
             }
 
             /**
-             * Attempts to evict all entries associated with keys. Note, that entry will be evicted only
-             * if it's not used (not participating in any locks or transactions).
+             * Attempts to evict all entries associated with keys.
+             *
+             * @note Entry will be evicted only if it's not used (not
+             * participating in any locks or transactions).
+             *
+             * This method should only be used on the valid instance.
              *
              * @param keys Keys to evict from cache.
              * @param err Error.
@@ -668,6 +754,8 @@ namespace ignite
 
             /**
              * Clear cache.
+             *
+             * This method should only be used on the valid instance.
              */
             void Clear()
             {
@@ -681,6 +769,8 @@ namespace ignite
             /**
              * Clear cache.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param err Error.
              */
             void Clear(IgniteError& err)
@@ -692,6 +782,8 @@ namespace ignite
              * Clear entry from the cache and swap storage, without notifying listeners or CacheWriters.
              * Entry is cleared only if it is not currently locked, and is not participating in a transaction.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key to clear.
              */
             void Clear(const K& key)
@@ -707,6 +799,8 @@ namespace ignite
              * Clear entry from the cache and swap storage, without notifying listeners or CacheWriters.
              * Entry is cleared only if it is not currently locked, and is not participating in a transaction.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key to clear.
              * @param err Error.
              */
@@ -721,6 +815,8 @@ namespace ignite
              * Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
              * Entry is cleared only if it is not currently locked, and is not participating in a transaction.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param keys Keys to clear.
              */
             void ClearAll(const std::set<K>& keys)
@@ -736,6 +832,8 @@ namespace ignite
              * Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
              * Entry is cleared only if it is not currently locked, and is not participating in a transaction.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param keys Keys to clear.
              * @param err Error.
              */
@@ -749,9 +847,12 @@ namespace ignite
             /**
              * Clear entry from the cache and swap storage, without notifying listeners or CacheWriters.
              * Entry is cleared only if it is not currently locked, and is not participating in a transaction.
-             * Note that this operation is local as it merely clears an entry from local cache, it does not
+             *
+             * @note This operation is local as it merely clears an entry from local cache, it does not
              * remove entries from remote caches.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key to clear.
              */
             void LocalClear(const K& key)
@@ -766,9 +867,12 @@ namespace ignite
             /**
              * Clear entry from the cache and swap storage, without notifying listeners or CacheWriters.
              * Entry is cleared only if it is not currently locked, and is not participating in a transaction.
-             * Note that this operation is local as it merely clears an entry from local cache, it does not
+             *
+             * @note This operation is local as it merely clears an entry from local cache, it does not
              * remove entries from remote caches.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key to clear.
              * @param err Error.
              */
@@ -782,9 +886,12 @@ namespace ignite
             /**
              * Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
              * Entry is cleared only if it is not currently locked, and is not participating in a transaction.
-             * Note that this operation is local as it merely clears entries from local cache, it does not
+             *
+             * @note This operation is local as it merely clears entries from local cache, it does not
              * remove entries from remote caches.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param keys Keys to clear.
              */
             void LocalClearAll(const std::set<K>& keys)
@@ -799,9 +906,12 @@ namespace ignite
             /**
              * Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
              * Entry is cleared only if it is not currently locked, and is not participating in a transaction.
-             * Note that this operation is local as it merely clears entries from local cache, it does not
+             *
+             * @note This operation is local as it merely clears entries from local cache, it does not
              * remove entries from remote caches.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param keys Keys to clear.
              * @param err Error.
              */
@@ -822,6 +932,8 @@ namespace ignite
              * If write-through is enabled, the value will be removed from store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key whose mapping is to be removed from cache.
              * @return False if there was no matching key.
              */
@@ -846,6 +958,8 @@ namespace ignite
              * If write-through is enabled, the value will be removed from store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key whose mapping is to be removed from cache.
              * @param err Error.
              * @return False if there was no matching key.
@@ -862,6 +976,8 @@ namespace ignite
              * If write-through is enabled, the value will be removed from store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key whose mapping is to be removed from cache.
              * @param val Value to match against currently cached value.
              * @return True if entry was removed, false otherwise.
@@ -882,6 +998,8 @@ namespace ignite
              * If write-through is enabled, the value will be removed from store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param key Key whose mapping is to be removed from cache.
              * @param val Value to match against currently cached value.
              * @param err Error.
@@ -899,6 +1017,8 @@ namespace ignite
              * If write-through is enabled, the value will be removed from store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param keys Keys whose mappings are to be removed from cache.
              */
             void RemoveAll(const std::set<K>& keys)
@@ -915,6 +1035,8 @@ namespace ignite
              * If write-through is enabled, the value will be removed from store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param keys Keys whose mappings are to be removed from cache.
              * @param err Error.
              */
@@ -930,6 +1052,8 @@ namespace ignite
              * If write-through is enabled, the value will be removed from store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param err Error.
              */
             void RemoveAll()
@@ -946,6 +1070,8 @@ namespace ignite
              * If write-through is enabled, the value will be removed from store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param err Error.
              */
             void RemoveAll(IgniteError& err)
@@ -956,6 +1082,8 @@ namespace ignite
             /**
              * Gets the number of all entries cached on this node.
              *
+             * This method should only be used on the valid instance.
+             *
              * @return Cache size on this node.
              */
             int32_t LocalSize()
@@ -966,6 +1094,8 @@ namespace ignite
             /**
              * Gets the number of all entries cached on this node.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param err Error.
              * @return Cache size on this node.
              */
@@ -977,6 +1107,8 @@ namespace ignite
             /**
              * Gets the number of all entries cached on this node.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param Peek modes.
              * @return Cache size on this node.
              */
@@ -994,6 +1126,8 @@ namespace ignite
             /**
              * Gets the number of all entries cached on this node.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param Peek modes.
              * @param err Error.
              * @return Cache size on this node.
@@ -1005,7 +1139,9 @@ namespace ignite
 
             /**
              * Gets the number of all entries cached across all nodes.
-             * NOTE: this operation is distributed and will query all participating nodes for their cache sizes.
+             * @note this operation is distributed and will query all participating nodes for their cache sizes.
+             *
+             * This method should only be used on the valid instance.
              *
              * @return Cache size across all nodes.
              */
@@ -1016,7 +1152,9 @@ namespace ignite
 
             /**
              * Gets the number of all entries cached across all nodes.
-             * NOTE: this operation is distributed and will query all participating nodes for their cache sizes.
+             * @note This operation is distributed and will query all participating nodes for their cache sizes.
+             *
+             * This method should only be used on the valid instance.
              *
              * @param err Error.
              * @return Cache size across all nodes.
@@ -1028,7 +1166,9 @@ namespace ignite
 
             /**
              * Gets the number of all entries cached across all nodes.
-             * NOTE: this operation is distributed and will query all participating nodes for their cache sizes.
+             * @note This operation is distributed and will query all participating nodes for their cache sizes.
+             *
+             * This method should only be used on the valid instance.
              *
              * @param Peek modes.
              * @return Cache size across all nodes.
@@ -1046,7 +1186,9 @@ namespace ignite
 
             /**
              * Gets the number of all entries cached across all nodes.
-             * NOTE: this operation is distributed and will query all participating nodes for their cache sizes.
+             * @note This operation is distributed and will query all participating nodes for their cache sizes.
+             *
+             * This method should only be used on the valid instance.
              *
              * @param Peek modes.
              * @param err Error.
@@ -1060,6 +1202,8 @@ namespace ignite
             /**
              * Perform SQL query.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param qry Query.
              * @return Query cursor.
              */
@@ -1077,6 +1221,8 @@ namespace ignite
             /**
              * Perform SQL query.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param qry Query.
              * @param err Error.
              * @return Query cursor.
@@ -1091,6 +1237,8 @@ namespace ignite
             /**
              * Perform text query.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param qry Query.
              * @return Query cursor.
              */
@@ -1108,6 +1256,8 @@ namespace ignite
             /**
              * Perform text query.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param qry Query.
              * @param err Error.
              * @return Query cursor.
@@ -1122,6 +1272,8 @@ namespace ignite
             /**
              * Perform scan query.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param qry Query.
              * @return Query cursor.
              */
@@ -1139,6 +1291,8 @@ namespace ignite
             /**
              * Perform scan query.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param qry Query.
              * @param err Error.
              * @return Query cursor.
@@ -1153,6 +1307,8 @@ namespace ignite
             /**
              * Perform sql fields query.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param qry Query.
              * @return Query cursor.
              */
@@ -1170,6 +1326,8 @@ namespace ignite
             /**
              * Perform sql fields query.
              *
+             * This method should only be used on the valid instance.
+             *
              * @param qry Query.
              * @param err Error.
              * @return Query cursor.

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h b/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h
index f709650..9810600 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h
@@ -30,7 +30,7 @@ namespace ignite
     namespace cache
     {
         /**
-         * Cache entry class template.
+         * %Cache entry class template.
          *
          * Both key and value types should be default-constructable,
          * copy-constructable and assignable.
@@ -67,10 +67,10 @@ namespace ignite
              *
              * @param other Other instance.
              */
-            CacheEntry(const CacheEntry& other)
+            CacheEntry(const CacheEntry& other) :
+                key(other.key), val(other.val)
             {
-                key = other.key;
-                val = other.val;
+                // No-op.
             }
 
             /**
@@ -82,10 +82,8 @@ namespace ignite
             {
                 if (this != &other)
                 {
-                    CacheEntry tmp(other);
-
-                    std::swap(key, tmp.key);
-                    std::swap(val, tmp.val);
+                    key = other.key;
+                    val = other.val;
                 }
 
                 return *this;

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/cache/query/query_argument.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_argument.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_argument.h
index 933bd60..65578ce 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_argument.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_argument.h
@@ -27,11 +27,11 @@
 #include "ignite/binary/binary_raw_writer.h"
 
 namespace ignite
-{    
+{
     namespace cache
     {
         namespace query
-        {            
+        {
             /**
              * Base class for all query arguments.
              */
@@ -49,18 +49,24 @@ namespace ignite
                 /**
                  * Copy argument. 
                  *
-                 * @return Copy.
+                 * @return Copy of this argument instance.
                  */
                 virtual QueryArgumentBase* Copy() const = 0;
 
                 /**
-                 * Write argument.
+                 * Write argument using provided writer.
+                 *
+                 * @param writer Writer to use to write this argument.
                  */
                 virtual void Write(ignite::binary::BinaryRawWriter& writer) = 0;
             };
 
             /**
-             * Query argument.
+             * Query argument class template.
+             *
+             * Template argument type should be copy-constructable and
+             * assignable. Also BinaryType class template should be specialized
+             * for this type.
              */
             template<typename T>
             class QueryArgument : public QueryArgumentBase
@@ -71,7 +77,8 @@ namespace ignite
                  *
                  * @param val Value.
                  */
-                QueryArgument(const T& val) : val(val)
+                QueryArgument(const T& val) :
+                    val(val)
                 {
                     // No-op.
                 }
@@ -81,26 +88,22 @@ namespace ignite
                  *
                  * @param other Other instance.
                  */
-                QueryArgument(const QueryArgument& other)
+                QueryArgument(const QueryArgument& other) :
+                    val(other.val)
                 {
-                    val = other.val;
+                    // No-op.
                 }
 
                 /**
                  * Assignment operator.
                  *
                  * @param other Other instance.
+                 * @return *this.
                  */
                 QueryArgument& operator=(const QueryArgument& other) 
                 {
                     if (this != &other)
-                    {
-                        QueryArgument tmp(other);
-
-                        T val0 = val;
-                        val = tmp.val;
-                        tmp.val = val0;
-                    }
+                        val = other.val;
 
                     return *this;
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
index 45eb54a..4c46662 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
@@ -42,7 +42,13 @@ namespace ignite
              * Query cursor class template.
              *
              * Both key and value types should be default-constructable,
-             * copy-constructable and assignable.
+             * copy-constructable and assignable. Also BinaryType class
+             * template should be specialized for both types.
+             *
+             * This class implemented as a reference to an implementation so copying
+             * of this class instance will only create another reference to the same
+             * underlying object. Underlying object released automatically once all
+             * the instances are destructed.
              */
             template<typename K, typename V>
             class QueryCursor
@@ -73,11 +79,12 @@ namespace ignite
 
                 /**
                  * Check whether next entry exists.
-                 * Throws IgniteError class instance in case of failure.
                  *
                  * This method should only be used on the valid instance.
                  *
                  * @return True if next entry exists.
+                 *
+                 * @throw IgniteError class instance in case of failure.
                  */
                 bool HasNext()
                 {
@@ -117,11 +124,12 @@ namespace ignite
 
                 /**
                  * Get next entry.
-                 * Throws IgniteError class instance in case of failure.
                  *
                  * This method should only be used on the valid instance.
                  *
                  * @return Next entry.
+                 *
+                 * @throw IgniteError class instance in case of failure.
                  */
                 CacheEntry<K, V> GetNext()
                 {
@@ -175,11 +183,12 @@ namespace ignite
 
                 /**
                  * Get all entries.
-                 * Throws IgniteError class instance in case of failure.
                  *
                  * This method should only be used on the valid instance.
                  *
                  * @param Vector where query entries will be stored.
+                 *
+                 * @throw IgniteError class instance in case of failure.
                  */
                 void GetAll(std::vector<CacheEntry<K, V>>& res)
                 {

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h
index 3952ece..3946e1c 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h
@@ -41,6 +41,11 @@ namespace ignite
         {
             /**
              * Query fields cursor.
+             *
+             * This class implemented as a reference to an implementation so copying
+             * of this class instance will only create another reference to the same
+             * underlying object. Underlying object released automatically once all
+             * the instances are destructed.
              */
             class QueryFieldsCursor
             {
@@ -70,11 +75,12 @@ namespace ignite
                 
                 /**
                  * Check whether next entry exists.
-                 * Throws IgniteError class instance in case of failure.
                  *
                  * This method should only be used on the valid instance.
                  *
                  * @return True if next entry exists.
+                 *
+                 * @throw IgniteError class instance in case of failure.
                  */
                 bool HasNext()
                 {
@@ -114,11 +120,12 @@ namespace ignite
 
                 /**
                  * Get next entry.
-                 * Throws IgniteError class instance in case of failure.
                  *
                  * This method should only be used on the valid instance.
                  *
                  * @return Next entry.
+                 *
+                 * @throw IgniteError class instance in case of failure.
                  */
                 QueryFieldsRow GetNext()
                 {

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
index 521da76..d3ac2de 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
@@ -40,6 +40,11 @@ namespace ignite
         {
             /**
              * Query fields cursor.
+             *
+             * This class implemented as a reference to an implementation so copying
+             * of this class instance will only create another reference to the same
+             * underlying object. Underlying object released automatically once all
+             * the instances are destructed.
              */
             class QueryFieldsRow
             {
@@ -47,8 +52,7 @@ namespace ignite
                 /**
                  * Default constructor.
                  *
-                 * Constructed instance is not valid and thus can not be used
-                 * as a cursor.
+                 * Constructed instance is not valid and thus can not be used.
                  */
                 QueryFieldsRow() : impl(0)
                 {
@@ -69,11 +73,12 @@ namespace ignite
 
                 /**
                  * Check whether next entry exists.
-                 * Throws IgniteError class instance in case of failure.
                  *
                  * This method should only be used on the valid instance.
                  *
                  * @return True if next entry exists.
+                 *
+                 * @throw IgniteError class instance in case of failure.
                  */
                 bool HasNext()
                 {
@@ -113,11 +118,16 @@ namespace ignite
 
                 /**
                  * Get next entry.
-                 * Throws IgniteError class instance in case of failure.
+                 *
+                 * Template argument type should be default-constructable,
+                 * copy-constructable and assignable. Also BinaryType class
+                 * template should be specialized for this type.
                  *
                  * This method should only be used on the valid instance.
                  *
                  * @return Next entry.
+                 *
+                 * @throw IgniteError class instance in case of failure.
                  */
                 template<typename T>
                 T GetNext()
@@ -135,6 +145,10 @@ namespace ignite
                  * Get next entry.
                  * Properly sets error param in case of failure.
                  *
+                 * Template argument type should be default-constructable,
+                 * copy-constructable and assignable. Also BinaryType class
+                 * template should be specialized for this type.
+                 *
                  * This method should only be used on the valid instance.
                  *
                  * @param err Used to set operation result.

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/cache/query/query_scan.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_scan.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_scan.h
index d4dd565..4228ba5 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_scan.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_scan.h
@@ -29,11 +29,11 @@
 #include "ignite/binary/binary_raw_writer.h"
 
 namespace ignite
-{    
+{
     namespace cache
     {
         namespace query
-        {         
+        {
             /**
              * Scan query.
              */
@@ -47,7 +47,7 @@ namespace ignite
                 {
                     // No-op.
                 }
-                
+
                 /**
                  * Constructor.
                  *
@@ -57,7 +57,7 @@ namespace ignite
                 {
                     // No-op.
                 }
-                
+
                 /**
                  * Get partition to scan.
                  *
@@ -117,7 +117,7 @@ namespace ignite
                 {
                     this->loc = loc;
                 }
-                
+
                 /**
                  * Write query info to the stream.
                  *

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/cache/query/query_sql.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_sql.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_sql.h
index d80fa51..f7a00fa 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_sql.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_sql.h
@@ -31,11 +31,11 @@
 #include "ignite/binary/binary_raw_writer.h"
 
 namespace ignite
-{    
+{
     namespace cache
     {
         namespace query
-        {         
+        {
             /**
              * Sql query.
              */
@@ -48,8 +48,8 @@ namespace ignite
                  * @param type Type name.
                  * @param sql SQL string.
                  */
-                SqlQuery(const std::string& type, const std::string& sql) : type(type), sql(sql), pageSize(1024), 
-                    loc(false), args()
+                SqlQuery(const std::string& type, const std::string& sql)
+                    : type(type), sql(sql), pageSize(1024),  loc(false), args()
                 {
                     // No-op.
                 }
@@ -59,7 +59,8 @@ namespace ignite
                  *
                  * @param other Other instance.
                  */
-                SqlQuery(const SqlQuery& other) : type(other.type), sql(other.sql), pageSize(other.pageSize),
+                SqlQuery(const SqlQuery& other) :
+                    type(other.type), sql(other.sql), pageSize(other.pageSize),
                     loc(other.loc), args()
                 {
                     args.reserve(other.args.size());
@@ -199,6 +200,10 @@ namespace ignite
                 /**
                  * Add argument.
                  *
+                 * Template argument type should be copy-constructable and
+                 * assignable. Also BinaryType class template should be specialized
+                 * for this type.
+                 *
                  * @param arg Argument.
                  */
                 template<typename T>

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
index 4792d34..e21fc93 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
@@ -47,7 +47,8 @@ namespace ignite
                  *
                  * @param sql SQL string.
                  */
-                SqlFieldsQuery(const std::string& sql) : sql(sql), pageSize(1024), loc(false), args()
+                SqlFieldsQuery(const std::string& sql) :
+                    sql(sql), pageSize(1024), loc(false), args()
                 {
                     // No-op.
                 }
@@ -58,7 +59,8 @@ namespace ignite
                  * @param sql SQL string.
                  * @param loc Whether query should be executed locally.
                  */
-                SqlFieldsQuery(const std::string& sql, bool loc) : sql(sql), pageSize(1024), loc(false), args()
+                SqlFieldsQuery(const std::string& sql, bool loc) :
+                    sql(sql), pageSize(1024), loc(false), args()
                 {
                     // No-op.
                 }
@@ -68,7 +70,8 @@ namespace ignite
                  *
                  * @param other Other instance.
                  */
-                SqlFieldsQuery(const SqlFieldsQuery& other) : sql(other.sql), pageSize(other.pageSize), loc(other.loc),
+                SqlFieldsQuery(const SqlFieldsQuery& other) :
+                    sql(other.sql), pageSize(other.pageSize), loc(other.loc),
                     args()
                 {
                     args.reserve(other.args.size());
@@ -106,7 +109,7 @@ namespace ignite
                     for (std::vector<QueryArgumentBase*>::iterator it = args.begin(); it != args.end(); ++it)
                         delete *it;
                 }
-                
+
                 /**
                  * Get SQL string.
                  *
@@ -170,6 +173,10 @@ namespace ignite
                 /**
                  * Add argument.
                  *
+                 * Template argument type should be copy-constructable and
+                 * assignable. Also BinaryType class template should be specialized
+                 * for this type.
+                 *
                  * @param arg Argument.
                  */
                 template<typename T>

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/ignite.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/ignite.h b/modules/platforms/cpp/core/include/ignite/ignite.h
index e4f9208..311dff2 100644
--- a/modules/platforms/cpp/core/include/ignite/ignite.h
+++ b/modules/platforms/cpp/core/include/ignite/ignite.h
@@ -31,7 +31,12 @@
 namespace ignite
 {
     /**
-     * Main interface to operate with Ignite.
+     * Main interface to operate with %Ignite.
+     *
+     * This class implemented as a reference to an implementation so copying
+     * of this class instance will only create another reference to the same
+     * underlying object. Underlying object released automatically once all
+     * the instances are destructed.
      */
     class IGNITE_IMPORT_EXPORT Ignite
     {
@@ -57,6 +62,8 @@ namespace ignite
         /**
          * Get cache.
          *
+         * This method should only be used on the valid instance.
+         *
          * @param name Cache name.
          * @return Cache.
          */
@@ -75,6 +82,8 @@ namespace ignite
         /**
          * Get cache.
          *
+         * This method should only be used on the valid instance.
+         *
          * @param name Cache name.
          * @param err Error;
          * @return Cache.
@@ -90,6 +99,8 @@ namespace ignite
         /**
          * Get or create cache.
          *
+         * This method should only be used on the valid instance.
+         *
          * @param name Cache name.
          * @return Cache.
          */
@@ -108,6 +119,8 @@ namespace ignite
         /**
          * Get or create cache.
          *
+         * This method should only be used on the valid instance.
+         *
          * @param name Cache name.
          * @param err Error;
          * @return Cache.
@@ -123,6 +136,8 @@ namespace ignite
         /**
          * Create cache.
          *
+         * This method should only be used on the valid instance.
+         *
          * @param name Cache name.
          * @return Cache.
          */
@@ -141,6 +156,8 @@ namespace ignite
         /**
          * Create cache.
          *
+         * This method should only be used on the valid instance.
+         *
          * @param name Cache name.
          * @param err Error;
          * @return Cache.
@@ -156,6 +173,8 @@ namespace ignite
         /**
          * Get transactions.
          *
+         * This method should only be used on the valid instance.
+         *
          * @return Transaction class instance.
          */
         transactions::Transactions GetTransactions();

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/ignite_configuration.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/ignite_configuration.h b/modules/platforms/cpp/core/include/ignite/ignite_configuration.h
index ee59c11..65c4550 100644
--- a/modules/platforms/cpp/core/include/ignite/ignite_configuration.h
+++ b/modules/platforms/cpp/core/include/ignite/ignite_configuration.h
@@ -32,7 +32,7 @@
 namespace ignite
 {
     /**
-     * Ignite configuration.
+     * %Ignite configuration.
      */
     struct IgniteConfiguration
     {
@@ -58,7 +58,7 @@ namespace ignite
         std::list<std::string> jvmOpts;
 
         /**
-         * Constructor.
+         * Default constructor.
          */
         IgniteConfiguration() : igniteHome(), springCfgPath(), jvmLibPath(), jvmClassPath(),
             jvmInitMem(512), jvmMaxMem(1024), jvmOpts()

http://git-wip-us.apache.org/repos/asf/ignite/blob/93445607/modules/platforms/cpp/core/include/ignite/ignition.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/ignition.h b/modules/platforms/cpp/core/include/ignite/ignition.h
index 31f5b0b..f88efe5 100644
--- a/modules/platforms/cpp/core/include/ignite/ignition.h
+++ b/modules/platforms/cpp/core/include/ignite/ignition.h
@@ -31,7 +31,7 @@
 namespace ignite
 {
     /**
-     * This class defines a factory for the main Ignite API.
+     * This class defines a factory for the main %Ignite API.
      */
     class IGNITE_IMPORT_EXPORT Ignition
     {


[19/50] [abbrv] ignite git commit: IGNITE-3351: Hadoop: Fixed HadoopClassLoader leak into IGFS thread pool.

Posted by sb...@apache.org.
IGNITE-3351: Hadoop: Fixed HadoopClassLoader leak into IGFS thread pool.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8e6473a0
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8e6473a0
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8e6473a0

Branch: refs/heads/ignite-1232
Commit: 8e6473a0488e4cf32bde84b2b0b4561ad5c4f157
Parents: bb7a672
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Wed Jun 22 12:18:38 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Wed Jun 22 16:54:28 2016 +0300

----------------------------------------------------------------------
 .../core/src/main/java/org/apache/ignite/internal/IgnitionEx.java | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8e6473a0/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
index 24249da..8062e6b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
@@ -1689,6 +1689,9 @@ public class IgnitionEx {
                 0,
                 new LinkedBlockingQueue<Runnable>());
 
+            // Pre-start all threads to avoid HadoopClassLoader leaks.
+            ((ThreadPoolExecutor)igfsExecSvc).prestartAllCoreThreads();
+
             // Note that we do not pre-start threads here as this pool may not be needed.
             callbackExecSvc = new IgniteStripedThreadPoolExecutor(
                 cfg.getAsyncCallbackPoolSize(),


[14/50] [abbrv] ignite git commit: IGNITE-3076 .NET: Add lifecycle events to IIgnite

Posted by sb...@apache.org.
IGNITE-3076 .NET: Add lifecycle events to IIgnite

This closes #683


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/5b4ac374
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/5b4ac374
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/5b4ac374

Branch: refs/heads/ignite-1232
Commit: 5b4ac3743aae8c638f2b70a528a15dc563ae0ffb
Parents: 8f28382
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Wed Jun 22 12:29:10 2016 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Wed Jun 22 12:29:10 2016 +0300

----------------------------------------------------------------------
 .../Apache.Ignite.Core.Tests/LifecycleTest.cs   |  9 ++++
 .../Apache.Ignite.Core.Tests/ReconnectTest.cs   |  9 ++++
 .../Apache.Ignite.Core.Tests/TestUtils.cs       |  4 +-
 .../Apache.Ignite.Core.csproj                   |  1 +
 .../dotnet/Apache.Ignite.Core/IIgnite.cs        | 25 +++++++++++
 .../dotnet/Apache.Ignite.Core/Ignition.cs       | 23 +++++++++-
 .../dotnet/Apache.Ignite.Core/Impl/Ignite.cs    | 38 +++++++++++++++-
 .../Apache.Ignite.Core/Impl/IgniteProxy.cs      | 37 +++++++++++++--
 .../Impl/LifecycleBeanHolder.cs                 |  2 +-
 .../Lifecycle/ClientReconnectEventArgs.cs       | 47 ++++++++++++++++++++
 10 files changed, 186 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5b4ac374/modules/platforms/dotnet/Apache.Ignite.Core.Tests/LifecycleTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/LifecycleTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/LifecycleTest.cs
index dd79d43..256ce46 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/LifecycleTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/LifecycleTest.cs
@@ -83,6 +83,7 @@ namespace Apache.Ignite.Core.Tests
         {
             // 1. Test start events.
             IIgnite grid = Start(CfgNoBeans);
+            Assert.AreEqual(2, grid.GetConfiguration().LifecycleBeans.Count);
 
             Assert.AreEqual(2, BeforeStartEvts.Count);
             CheckEvent(BeforeStartEvts[0], null, null, 0, null);
@@ -93,8 +94,15 @@ namespace Apache.Ignite.Core.Tests
             CheckEvent(AfterStartEvts[1], grid, grid, 0, null);
 
             // 2. Test stop events.
+            var stoppingCnt = 0;
+            var stoppedCnt = 0;
+            grid.Stopping += (sender, args) => { stoppingCnt++; };
+            grid.Stopped += (sender, args) => { stoppedCnt++; };
             Ignition.Stop(grid.Name, false);
 
+            Assert.AreEqual(1, stoppingCnt);
+            Assert.AreEqual(1, stoppedCnt);
+
             Assert.AreEqual(2, BeforeStartEvts.Count);
             Assert.AreEqual(2, AfterStartEvts.Count);
 
@@ -115,6 +123,7 @@ namespace Apache.Ignite.Core.Tests
         {
             // 1. Test .Net start events.
             IIgnite grid = Start(CfgBeans);
+            Assert.AreEqual(2, grid.GetConfiguration().LifecycleBeans.Count);
 
             Assert.AreEqual(4, BeforeStartEvts.Count);
             CheckEvent(BeforeStartEvts[0], null, null, 0, null);

http://git-wip-us.apache.org/repos/asf/ignite/blob/5b4ac374/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ReconnectTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ReconnectTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ReconnectTest.cs
index 2f8b205..6032ef3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ReconnectTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ReconnectTest.cs
@@ -47,6 +47,11 @@ namespace Apache.Ignite.Core.Tests
 
             using (var ignite = Ignition.Start(cfg))
             {
+                var reconnected = 0;
+                var disconnected = 0;
+                ignite.ClientDisconnected += (sender, args) => { disconnected++; };
+                ignite.ClientReconnected += (sender, args) => { reconnected += args.HasClusterRestarted ? 10 : 1; };
+
                 Assert.IsTrue(ignite.GetCluster().ClientReconnectTask.IsCompleted);
 
                 var cache = ignite.CreateCache<int, int>("c");
@@ -63,6 +68,8 @@ namespace Apache.Ignite.Core.Tests
                 var clientReconnectTask = inner.ClientReconnectTask;
 
                 Assert.AreEqual(ignite.GetCluster().ClientReconnectTask, clientReconnectTask);
+                Assert.AreEqual(1, disconnected);
+                Assert.AreEqual(0, reconnected);
 
                 // Resume process to reconnect
                 proc.Resume();
@@ -70,6 +77,8 @@ namespace Apache.Ignite.Core.Tests
                 clientReconnectTask.Wait();
 
                 Assert.AreEqual(1, cache[1]);
+                Assert.AreEqual(1, disconnected);
+                Assert.AreEqual(1, reconnected);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/5b4ac374/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs
index 4eef803..529b320 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs
@@ -273,10 +273,12 @@ namespace Apache.Ignite.Core.Tests
         {
             var handleRegistry = ((Ignite)grid).HandleRegistry;
 
+            expectedCount++;  // Skip default lifecycle bean
+
             if (WaitForCondition(() => handleRegistry.Count == expectedCount, timeout))
                 return;
 
-            var items = handleRegistry.GetItems();
+            var items = handleRegistry.GetItems().Where(x => !(x.Value is LifecycleBeanHolder)).ToList();
 
             if (items.Any())
                 Assert.Fail("HandleRegistry is not empty in grid '{0}':\n '{1}'", grid.Name,

http://git-wip-us.apache.org/repos/asf/ignite/blob/5b4ac374/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
index 34c5ddb..46dbd94 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -414,6 +414,7 @@
     <Compile Include="Impl\Unmanaged\UnmanagedTarget.cs" />
     <Compile Include="Impl\Unmanaged\UnmanagedUtils.cs" />
     <Compile Include="Interop\JavaObject.cs" />
+    <Compile Include="Lifecycle\ClientReconnectEventArgs.cs" />
     <Compile Include="Lifecycle\Package-Info.cs" />
     <Compile Include="Messaging\Package-Info.cs" />
     <Compile Include="Package-Info.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/5b4ac374/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs
index b45c625..a16ae3a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs
@@ -29,6 +29,7 @@ namespace Apache.Ignite.Core
     using Apache.Ignite.Core.Datastream;
     using Apache.Ignite.Core.DataStructures;
     using Apache.Ignite.Core.Events;
+    using Apache.Ignite.Core.Lifecycle;
     using Apache.Ignite.Core.Messaging;
     using Apache.Ignite.Core.Services;
     using Apache.Ignite.Core.Transactions;
@@ -274,5 +275,29 @@ namespace Apache.Ignite.Core
         /// </summary>
         /// <returns>Collection of names of currently available caches.</returns>
         ICollection<string> GetCacheNames();
+
+        /// <summary>
+        /// Occurs when node begins to stop. Node is fully functional at this point.
+        /// See also: <see cref="LifecycleEventType.BeforeNodeStop"/>.
+        /// </summary>
+        event EventHandler Stopping;
+
+        /// <summary>
+        /// Occurs when node has stopped. Node can't be used at this point.
+        /// See also: <see cref="LifecycleEventType.AfterNodeStop"/>.
+        /// </summary>
+        event EventHandler Stopped;
+
+        /// <summary>
+        /// Occurs when client node disconnects from the cluster. This event can only occur when this instance
+        /// runs in client mode (<see cref="IgniteConfiguration.ClientMode"/>).
+        /// </summary>
+        event EventHandler ClientDisconnected;
+
+        /// <summary>
+        /// Occurs when client node reconnects to the cluster. This event can only occur when this instance
+        /// runs in client mode (<see cref="IgniteConfiguration.ClientMode"/>).
+        /// </summary>
+        event EventHandler<ClientReconnectEventArgs> ClientReconnected;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5b4ac374/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
index c551735..7dc103c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
@@ -36,6 +36,7 @@ namespace Apache.Ignite.Core
     using Apache.Ignite.Core.Impl.Memory;
     using Apache.Ignite.Core.Impl.Unmanaged;
     using Apache.Ignite.Core.Lifecycle;
+    using Apache.Ignite.Core.Resource;
     using BinaryReader = Apache.Ignite.Core.Impl.Binary.BinaryReader;
     using UU = Apache.Ignite.Core.Impl.Unmanaged.UnmanagedUtils;
 
@@ -308,7 +309,10 @@ namespace Apache.Ignite.Core
         private static void PrepareLifecycleBeans(BinaryReader reader, PlatformMemoryStream outStream, 
             HandleRegistry handleRegistry)
         {
-            IList<LifecycleBeanHolder> beans = new List<LifecycleBeanHolder>();
+            IList<LifecycleBeanHolder> beans = new List<LifecycleBeanHolder>
+            {
+                new LifecycleBeanHolder(new InternalLifecycleBean())   // add internal bean for events
+            };
 
             // 1. Read beans defined in Java.
             int cnt = reader.ReadInt();
@@ -689,5 +693,22 @@ namespace Apache.Ignite.Core
             /// </summary>
             internal Ignite Ignite { get; set; }
         }
+
+        /// <summary>
+        /// Internal bean for event notification.
+        /// </summary>
+        private class InternalLifecycleBean : ILifecycleBean
+        {
+            /** */
+            #pragma warning disable 649   // unused field
+            [InstanceResource] private readonly IIgnite _ignite;
+
+            /** <inheritdoc /> */
+            public void OnLifecycleEvent(LifecycleEventType evt)
+            {
+                if (evt == LifecycleEventType.BeforeNodeStop)
+                    ((IgniteProxy) _ignite).Target.BeforeNodeStop();
+            }
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5b4ac374/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs
index 5e2a5d7..d516056 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs
@@ -356,12 +356,26 @@ namespace Apache.Ignite.Core.Impl
         }
 
         /// <summary>
+        /// Called before node has stopped.
+        /// </summary>
+        internal void BeforeNodeStop()
+        {
+            var handler = Stopping;
+            if (handler != null)
+                handler.Invoke(this, EventArgs.Empty);
+        }
+
+        /// <summary>
         /// Called after node has stopped.
         /// </summary>
         internal void AfterNodeStop()
         {
             foreach (var bean in _lifecycleBeans)
                 bean.OnLifecycleEvent(LifecycleEventType.AfterNodeStop);
+
+            var handler = Stopped;
+            if (handler != null)
+                handler.Invoke(this, EventArgs.Empty);
         }
 
         /** <inheritdoc /> */
@@ -651,6 +665,18 @@ namespace Apache.Ignite.Core.Impl
             }
         }
 
+        /** <inheritdoc /> */
+        public event EventHandler Stopping;
+
+        /** <inheritdoc /> */
+        public event EventHandler Stopped;
+
+        /** <inheritdoc /> */
+        public event EventHandler ClientDisconnected;
+
+        /** <inheritdoc /> */
+        public event EventHandler<ClientReconnectEventArgs> ClientReconnected;
+
         /// <summary>
         /// Gets or creates near cache.
         /// </summary>
@@ -757,18 +783,26 @@ namespace Apache.Ignite.Core.Impl
         /// <summary>
         /// Called when local client node has been disconnected from the cluster.
         /// </summary>
-        public void OnClientDisconnected()
+        internal void OnClientDisconnected()
         {
             _clientReconnectTaskCompletionSource = new TaskCompletionSource<bool>();
+
+            var handler = ClientDisconnected;
+            if (handler != null)
+                handler.Invoke(this, EventArgs.Empty);
         }
 
         /// <summary>
         /// Called when local client node has been reconnected to the cluster.
         /// </summary>
         /// <param name="clusterRestarted">Cluster restarted flag.</param>
-        public void OnClientReconnected(bool clusterRestarted)
+        internal void OnClientReconnected(bool clusterRestarted)
         {
             _clientReconnectTaskCompletionSource.TrySetResult(clusterRestarted);
+
+            var handler = ClientReconnected;
+            if (handler != null)
+                handler.Invoke(this, new ClientReconnectEventArgs(clusterRestarted));
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5b4ac374/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs
index 957018e..949d31c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs
@@ -31,6 +31,7 @@ namespace Apache.Ignite.Core.Impl
     using Apache.Ignite.Core.Events;
     using Apache.Ignite.Core.Impl.Binary;
     using Apache.Ignite.Core.Impl.Cluster;
+    using Apache.Ignite.Core.Lifecycle;
     using Apache.Ignite.Core.Messaging;
     using Apache.Ignite.Core.Services;
     using Apache.Ignite.Core.Transactions;
@@ -43,7 +44,7 @@ namespace Apache.Ignite.Core.Impl
     {
         /** */
         [NonSerialized]
-        private readonly IIgnite _ignite;
+        private readonly Ignite _ignite;
 
         /// <summary>
         /// Default ctor for marshalling.
@@ -57,7 +58,7 @@ namespace Apache.Ignite.Core.Impl
         /// Constructor.
         /// </summary>
         /// <param name="ignite">Grid.</param>
-        public IgniteProxy(IIgnite ignite)
+        public IgniteProxy(Ignite ignite)
         {
             _ignite = ignite;
         }
@@ -385,6 +386,34 @@ namespace Apache.Ignite.Core.Impl
         }
 
         /** <inheritdoc /> */
+        public event EventHandler Stopping
+        {
+            add { _ignite.Stopping += value; }
+            remove { _ignite.Stopping -= value; }
+        }
+
+        /** <inheritdoc /> */
+        public event EventHandler Stopped
+        {
+            add { _ignite.Stopped += value; }
+            remove { _ignite.Stopped -= value; }
+        }
+
+        /** <inheritdoc /> */
+        public event EventHandler ClientDisconnected
+        {
+            add { _ignite.ClientDisconnected += value; }
+            remove { _ignite.ClientDisconnected -= value; }
+        }
+
+        /** <inheritdoc /> */
+        public event EventHandler<ClientReconnectEventArgs> ClientReconnected
+        {
+            add { _ignite.ClientReconnected += value; }
+            remove { _ignite.ClientReconnected -= value; }
+        }
+
+        /** <inheritdoc /> */
         public IAtomicSequence GetAtomicSequence(string name, long initialValue, bool create)
         {
             return _ignite.GetAtomicSequence(name, initialValue, create);
@@ -405,7 +434,7 @@ namespace Apache.Ignite.Core.Impl
         /// <summary>
         /// Target grid.
         /// </summary>
-        internal IIgnite Target
+        internal Ignite Target
         {
             get
             {
@@ -416,7 +445,7 @@ namespace Apache.Ignite.Core.Impl
         /** <inheritdoc /> */
         public IBinaryType GetBinaryType(int typeId)
         {
-            return ((IClusterGroupEx)_ignite).GetBinaryType(typeId);
+            return _ignite.GetBinaryType(typeId);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5b4ac374/modules/platforms/dotnet/Apache.Ignite.Core/Impl/LifecycleBeanHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/LifecycleBeanHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/LifecycleBeanHolder.cs
index cce4ec5..7544bf1 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/LifecycleBeanHolder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/LifecycleBeanHolder.cs
@@ -23,7 +23,7 @@ namespace Apache.Ignite.Core.Impl
     /// <summary>
     /// Lifecycle bean holder.
     /// </summary>
-    internal class LifecycleBeanHolder : ILifecycleBean
+    internal class LifecycleBeanHolder
     {
         /** Target bean. */
         private readonly ILifecycleBean _target;

http://git-wip-us.apache.org/repos/asf/ignite/blob/5b4ac374/modules/platforms/dotnet/Apache.Ignite.Core/Lifecycle/ClientReconnectEventArgs.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Lifecycle/ClientReconnectEventArgs.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Lifecycle/ClientReconnectEventArgs.cs
new file mode 100644
index 0000000..57f537a
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Lifecycle/ClientReconnectEventArgs.cs
@@ -0,0 +1,47 @@
+\ufeff/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Lifecycle
+{
+    using System;
+
+    /// <summary>
+    /// Contains client reconnect event data.
+    /// </summary>
+    public class ClientReconnectEventArgs : EventArgs
+    {
+        /** */
+        private readonly bool _hasClusterRestarted;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ClientReconnectEventArgs"/> class.
+        /// </summary>
+        /// <param name="hasClusterRestarted">Cluster restarted flag.</param>
+        public ClientReconnectEventArgs(bool hasClusterRestarted)
+        {
+            _hasClusterRestarted = hasClusterRestarted;
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether this cluster has been restarted during reconnect.
+        /// </summary>
+        public bool HasClusterRestarted
+        {
+            get { return _hasClusterRestarted; }
+        }
+    }
+}


[08/50] [abbrv] ignite git commit: IGNITE-3277 Cleanup pom.xml.

Posted by sb...@apache.org.
IGNITE-3277 Cleanup pom.xml.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0c5db20b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0c5db20b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0c5db20b

Branch: refs/heads/ignite-1232
Commit: 0c5db20be936997b7fa07dd26840424d1633bdae
Parents: f177d43
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Tue Jun 21 15:08:47 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Tue Jun 21 15:08:47 2016 +0700

----------------------------------------------------------------------
 modules/clients/pom.xml | 8 --------
 1 file changed, 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/0c5db20b/modules/clients/pom.xml
----------------------------------------------------------------------
diff --git a/modules/clients/pom.xml b/modules/clients/pom.xml
index 5b328e0..fa25d18 100644
--- a/modules/clients/pom.xml
+++ b/modules/clients/pom.xml
@@ -83,14 +83,6 @@
         </dependency>
 
         <dependency>
-            <groupId>net.sf.json-lib</groupId>
-            <artifactId>json-lib</artifactId>
-            <version>2.4</version>
-            <classifier>jdk15</classifier>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
             <groupId>org.apache.ignite</groupId>
             <artifactId>ignite-core</artifactId>
             <version>${project.version}</version>


[32/50] [abbrv] ignite git commit: IGNITE-3339 - Fixed entry evictions. Fixes #817

Posted by sb...@apache.org.
IGNITE-3339 - Fixed entry evictions. Fixes #817


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8ec6db5e
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8ec6db5e
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8ec6db5e

Branch: refs/heads/ignite-1232
Commit: 8ec6db5e86702857ba3493bc086880aad757c1dc
Parents: 1986b77
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Fri Jun 24 16:29:41 2016 -0700
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Fri Jun 24 16:29:41 2016 -0700

----------------------------------------------------------------------
 .../distributed/near/GridNearGetFuture.java     |   8 +-
 .../transactions/IgniteTxLocalAdapter.java      |  12 +-
 .../cache/transactions/IgniteTxManager.java     |  16 +-
 .../IgniteCacheTxIteratorSelfTest.java          | 241 +++++++++++++++++++
 .../testsuites/IgniteCacheTestSuite5.java       |   2 +
 5 files changed, 266 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8ec6db5e/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
index 290c08e..b7fcbbd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
@@ -62,8 +62,6 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteUuid;
 import org.jetbrains.annotations.Nullable;
 
-import static org.apache.ignite.transactions.TransactionIsolation.READ_COMMITTED;
-
 /**
  *
  */
@@ -636,7 +634,7 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
             catch (GridCacheEntryRemovedException ignored) {
                 // Retry.
             }
-            catch (GridDhtInvalidPartitionException e) {
+            catch (GridDhtInvalidPartitionException ignored) {
                 return false;
             }
             catch (IgniteCheckedException e) {
@@ -645,7 +643,9 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
                 return false;
             }
             finally {
-                if (dhtEntry != null && (tx == null || (!tx.implicit() && tx.isolation() == READ_COMMITTED)))
+                if (dhtEntry != null)
+                    // Near cache is enabled, so near entry will be enlisted in the transaction.
+                    // Always touch DHT entry in this case.
                     dht.context().evicts().touch(dhtEntry, topVer);
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ec6db5e/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
index d51d873..d9aca4a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
@@ -1395,11 +1395,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter implements Ig
                             log.debug("Got removed entry in transaction getAllAsync(..) (will retry): " + key);
                     }
                     finally {
-                        if (cacheCtx.isNear() && entry != null && readCommitted()) {
-                            if (cacheCtx.affinity().belongs(cacheCtx.localNode(), entry.partition(), topVer)) {
-                                if (entry.markObsolete(xidVer))
-                                    cacheCtx.cache().removeEntry(entry);
+                        if (entry != null && readCommitted()) {
+                            if (cacheCtx.isNear()) {
+                                if (cacheCtx.affinity().belongs(cacheCtx.localNode(), entry.partition(), topVer)) {
+                                    if (entry.markObsolete(xidVer))
+                                        cacheCtx.cache().removeEntry(entry);
+                                }
                             }
+                            else
+                                entry.context().evicts().touch(entry, topVer);
                         }
                     }
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ec6db5e/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index 4ec280f..e8d20b6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -1236,7 +1236,7 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
      * @param tx Transaction to finish.
      * @param commit {@code True} if transaction is committed, {@code false} if rolled back.
      */
-    public void fastFinishTx(IgniteInternalTx tx, boolean commit) {
+    public void fastFinishTx(GridNearTxLocal tx, boolean commit) {
         assert tx != null;
         assert tx.writeMap().isEmpty();
         assert tx.optimistic() || tx.readMap().isEmpty();
@@ -1247,16 +1247,22 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
             // 1. Notify evictions.
             notifyEvitions(tx);
 
-            // 2. Remove obsolete entries.
+            // 2. Evict near entries.
+            if (!tx.readMap().isEmpty()) {
+                for (IgniteTxEntry entry : tx.readMap().values())
+                    tx.evictNearEntry(entry, false);
+            }
+
+            // 3. Remove obsolete entries.
             removeObsolete(tx);
 
-            // 3. Remove from per-thread storage.
+            // 4. Remove from per-thread storage.
             clearThreadMap(tx);
 
-            // 4. Clear context.
+            // 5. Clear context.
             resetContext();
 
-            // 5. Update metrics.
+            // 6. Update metrics.
             if (!tx.dht() && tx.local()) {
                 if (!tx.system()) {
                     if (commit)

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ec6db5e/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheTxIteratorSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheTxIteratorSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheTxIteratorSelfTest.java
new file mode 100644
index 0000000..769a5f6
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheTxIteratorSelfTest.java
@@ -0,0 +1,241 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMemoryMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.eviction.fifo.FifoEvictionPolicy;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.configuration.TransactionConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
+
+import javax.cache.Cache;
+
+/**
+ *
+ */
+public class IgniteCacheTxIteratorSelfTest extends GridCommonAbstractTest {
+    /** */
+    public static final String CACHE_NAME = "testCache";
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        final IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        final TransactionConfiguration txCfg = new TransactionConfiguration();
+
+        txCfg.setDefaultTxIsolation(TransactionIsolation.READ_COMMITTED);
+
+        cfg.setTransactionConfiguration(txCfg);
+
+        return cfg;
+    }
+
+    /**
+     * @return Cache configuration.
+     */
+    private CacheConfiguration<String, TestClass> cacheConfiguration(
+        CacheMode mode,
+        CacheAtomicityMode atomMode,
+        CacheMemoryMode memMode,
+        boolean nearEnabled,
+        boolean useEvictPlc
+    ) {
+        final CacheConfiguration<String, TestClass> ccfg = new CacheConfiguration<>(CACHE_NAME);
+
+        ccfg.setAtomicityMode(atomMode);
+        ccfg.setCacheMode(mode);
+        ccfg.setMemoryMode(memMode);
+        ccfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+
+        if (nearEnabled)
+            ccfg.setNearConfiguration(new NearCacheConfiguration<String, TestClass>());
+
+        if (memMode == CacheMemoryMode.ONHEAP_TIERED && useEvictPlc) {
+            ccfg.setOffHeapMaxMemory(10 * 1024 * 1024);
+            ccfg.setEvictionPolicy(new FifoEvictionPolicy(50));
+        }
+
+        return ccfg;
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    public void testModesSingleNode() throws Exception {
+        checkModes(1);
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    public void testModesMultiNode() throws Exception {
+        checkModes(3);
+    }
+
+    /**
+     * @throws Exception if failed.
+     */
+    public void checkModes(int gridCnt) throws Exception {
+        startGrids(gridCnt);
+
+        try {
+            for (CacheMode mode : CacheMode.values()) {
+                for (CacheAtomicityMode atomMode : CacheAtomicityMode.values()) {
+                    for (CacheMemoryMode memMode : CacheMemoryMode.values()) {
+                        if (mode == CacheMode.PARTITIONED) {
+                            // Near cache makes sense only for partitioned cache.
+                            checkTxCache(CacheMode.PARTITIONED, atomMode, memMode, true, false);
+                        }
+
+                        if (memMode == CacheMemoryMode.ONHEAP_TIERED)
+                            checkTxCache(mode, atomMode, CacheMemoryMode.ONHEAP_TIERED, false, true);
+
+                        checkTxCache(mode, atomMode, memMode, false, false);
+                    }
+                }
+            }
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void checkTxCache(
+        CacheMode mode,
+        CacheAtomicityMode atomMode,
+        CacheMemoryMode memMode,
+        boolean nearEnabled,
+        boolean useEvicPlc
+    ) throws Exception {
+        final Ignite ignite = grid(0);
+
+        final CacheConfiguration<String, TestClass> ccfg = cacheConfiguration(
+            mode,
+            atomMode,
+            memMode,
+            nearEnabled,
+            useEvicPlc);
+
+        final IgniteCache<String, TestClass> cache = ignite.createCache(ccfg);
+
+        info("Checking cache [mode=" + mode + ", atomMode=" + atomMode + ", memMode=" + memMode +
+            ", near=" + nearEnabled + ']');
+
+        try {
+            for (int i = 0; i < 30; i++) {
+                final TestClass val = new TestClass("data");
+                final String key = "key-" + i;
+
+                cache.put(key, val);
+
+                assertEquals(i + 1, cache.size());
+
+                for (TransactionIsolation iso : TransactionIsolation.values()) {
+                    for (TransactionConcurrency con : TransactionConcurrency.values()) {
+                        try (Transaction transaction = ignite.transactions().txStart(con, iso)) {
+                            assertEquals(val, cache.get(key));
+
+                            transaction.commit();
+                        }
+
+                        int cnt = iterateOverKeys(cache);
+
+                        assertEquals("Failed [con=" + con + ", iso=" + iso + ']', i + 1, cnt);
+
+                        assertEquals("Failed [con=" + con + ", iso=" + iso + ']', i + 1, cache.size());
+                    }
+                }
+            }
+        }
+        finally {
+            grid(0).destroyCache(CACHE_NAME);
+        }
+    }
+
+    /**
+     * @param cache Cache.
+     */
+    @SuppressWarnings("TypeMayBeWeakened")
+    private int iterateOverKeys(final IgniteCache<String, TestClass> cache) {
+        int cnt = 0;
+
+        for (final Cache.Entry<String, TestClass> ignore : cache)
+            cnt++;
+
+        return cnt;
+    }
+
+    /**
+     *
+     */
+    private static class TestClass {
+        /** */
+        private String data;
+
+        /**
+         * @param data Data.
+         */
+        private TestClass(String data) {
+            this.data = data;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean equals(final Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            final TestClass testCls = (TestClass)o;
+
+            return data != null ? data.equals(testCls.data) : testCls.data == null;
+
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int hashCode() {
+            return data != null ? data.hashCode() : 0;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public String toString() {
+            return S.toString(TestClass.class, this);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/8ec6db5e/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
index 41e0ed1..7582f5c 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
@@ -29,6 +29,7 @@ import org.apache.ignite.internal.processors.cache.distributed.CacheLateAffinity
 import org.apache.ignite.internal.processors.cache.distributed.CacheLateAffinityAssignmentNodeJoinValidationTest;
 import org.apache.ignite.internal.processors.cache.distributed.CacheLateAffinityAssignmentTest;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheSyncRebalanceModeSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheTxIteratorSelfTest;
 import org.apache.ignite.internal.processors.cache.store.IgniteCacheWriteBehindNoUpdateSelfTest;
 
 /**
@@ -56,6 +57,7 @@ public class IgniteCacheTestSuite5 extends TestSuite {
         suite.addTestSuite(IgniteCacheSyncRebalanceModeSelfTest.class);
 
         suite.addTest(IgniteCacheReadThroughEvictionsVariationsSuite.suite());
+        suite.addTestSuite(IgniteCacheTxIteratorSelfTest.class);
 
         return suite;
     }


[17/50] [abbrv] ignite git commit: Merge remote-tracking branch 'remotes/upstream/gridgain-7.6.1'

Posted by sb...@apache.org.
Merge remote-tracking branch 'remotes/upstream/gridgain-7.6.1'


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/41f81da8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/41f81da8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/41f81da8

Branch: refs/heads/ignite-1232
Commit: 41f81da8f7efe629affc1cfae52ed1d8820a1043
Parents: 5b4ac37 8ce29a9
Author: Anton Vinogradov <av...@apache.org>
Authored: Wed Jun 22 13:01:23 2016 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Wed Jun 22 13:01:23 2016 +0300

----------------------------------------------------------------------
 .../configuration/HadoopConfiguration.java      | 35 +++++++
 .../processors/hadoop/HadoopJobInfo.java        |  3 +-
 .../ignite/internal/util/IgniteUtils.java       | 45 +++++++--
 .../ignite/spi/discovery/tcp/ServerImpl.java    |  7 +-
 .../spi/discovery/tcp/TcpDiscoveryImpl.java     |  3 +-
 .../cluster/GridAddressResolverSelfTest.java    | 97 ++++++++++++++++++++
 .../vm/TcpDiscoveryVmIpFinderSelfTest.java      | 75 +++++++++++++++
 .../testsuites/IgniteKernalSelfTestSuite.java   |  2 +
 .../processors/hadoop/HadoopClassLoader.java    | 26 +++++-
 .../processors/hadoop/HadoopDefaultJobInfo.java |  8 +-
 .../hadoop/jobtracker/HadoopJobTracker.java     | 14 ++-
 .../child/HadoopChildProcessRunner.java         |  2 +-
 .../processors/hadoop/v2/HadoopV2Job.java       | 14 ++-
 .../hadoop/HadoopClassLoaderTest.java           |  2 +-
 .../processors/hadoop/HadoopSnappyTest.java     |  2 +-
 .../processors/hadoop/HadoopTasksV1Test.java    |  2 +-
 .../processors/hadoop/HadoopTasksV2Test.java    |  2 +-
 .../processors/hadoop/HadoopV2JobSelfTest.java  |  2 +-
 .../collections/HadoopAbstractMapTest.java      |  6 +-
 19 files changed, 312 insertions(+), 35 deletions(-)
----------------------------------------------------------------------



[41/50] [abbrv] ignite git commit: Ignite Web Console beta2.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/controllers/clusters-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/controllers/clusters-controller.js b/modules/web-console/src/main/js/controllers/clusters-controller.js
index 8aecc9f..3277397 100644
--- a/modules/web-console/src/main/js/controllers/clusters-controller.js
+++ b/modules/web-console/src/main/js/controllers/clusters-controller.js
@@ -19,15 +19,15 @@
 import consoleModule from 'controllers/common-module';
 
 consoleModule.controller('clustersController', [
-    '$rootScope', '$scope', '$http', '$state', '$timeout', '$common', '$confirm', '$clone', '$loading', '$cleanup', '$unsavedChangesGuard', 'igniteEventGroups', 'DemoInfo',
-    function ($root, $scope, $http, $state, $timeout, $common, $confirm, $clone, $loading, $cleanup, $unsavedChangesGuard, igniteEventGroups, DemoInfo) {
+    '$rootScope', '$scope', '$http', '$state', '$timeout', '$common', '$confirm', '$clone', '$loading', '$cleanup', '$unsavedChangesGuard', 'igniteEventGroups', 'DemoInfo', '$table',
+    function($root, $scope, $http, $state, $timeout, $common, $confirm, $clone, $loading, $cleanup, $unsavedChangesGuard, igniteEventGroups, DemoInfo, $table) {
         $unsavedChangesGuard.install($scope);
 
-        var emptyCluster = {empty: true};
+        const emptyCluster = {empty: true};
 
-        var __original_value;
+        let __original_value;
 
-        var blank = {
+        const blank = {
             atomicConfiguration: {},
             binaryConfiguration: {},
             communication: {},
@@ -36,7 +36,109 @@ consoleModule.controller('clustersController', [
             marshaller: {},
             sslContextFactory: {},
             swapSpaceSpi: {},
-            transactionConfiguration: {}
+            transactionConfiguration: {},
+            collision: {}
+        };
+
+        const pairFields = {
+            attributes: {id: 'Attribute', idPrefix: 'Key', searchCol: 'name', valueCol: 'key', dupObjName: 'name', group: 'attributes'},
+            'collision.JobStealing.stealingAttributes': {id: 'CAttribute', idPrefix: 'Key', searchCol: 'name', valueCol: 'key', dupObjName: 'name', group: 'collision'}
+        };
+
+        const showPopoverMessage = $common.showPopoverMessage;
+
+        $scope.tablePairValid = function(item, field, index) {
+            const pairField = pairFields[field.model];
+
+            const pairValue = $table.tablePairValue(field, index);
+
+            if (pairField) {
+                const model = _.get(item, field.model);
+
+                if ($common.isDefined(model)) {
+                    const idx = _.findIndex(model, (pair) => {
+                        return pair[pairField.searchCol] === pairValue[pairField.valueCol];
+                    });
+
+                    // Found duplicate by key.
+                    if (idx >= 0 && idx !== index)
+                        return showPopoverMessage($scope.ui, pairField.group, $table.tableFieldId(index, pairField.idPrefix + pairField.id), 'Attribute with such ' + pairField.dupObjName + ' already exists!');
+                }
+            }
+
+            return true;
+        };
+
+        $scope.tableSave = function(field, index, stopEdit) {
+            if ($table.tablePairSaveVisible(field, index))
+                return $table.tablePairSave($scope.tablePairValid, $scope.backupItem, field, index, stopEdit);
+
+            return true;
+        };
+
+        $scope.tableReset = (trySave) => {
+            const field = $table.tableField();
+
+            if (trySave && $common.isDefined(field) && !$scope.tableSave(field, $table.tableEditedRowIndex(), true))
+                return false;
+
+            $table.tableReset();
+
+            return true;
+        };
+
+        $scope.tableNewItem = function(field) {
+            if ($scope.tableReset(true)) {
+                if (field.type === 'failoverSpi') {
+                    if ($common.isDefined($scope.backupItem.failoverSpi))
+                        $scope.backupItem.failoverSpi.push({});
+                    else
+                        $scope.backupItem.failoverSpi = {};
+                }
+                else
+                    $table.tableNewItem(field);
+            }
+        };
+
+        $scope.tableNewItemActive = $table.tableNewItemActive;
+
+        $scope.tableStartEdit = function(item, field, index) {
+            if ($scope.tableReset(true))
+                $table.tableStartEdit(item, field, index, $scope.tableSave);
+        };
+
+        $scope.tableEditing = $table.tableEditing;
+
+        $scope.tableRemove = function(item, field, index) {
+            if ($scope.tableReset(true))
+                $table.tableRemove(item, field, index);
+        };
+
+        $scope.tablePairSave = $table.tablePairSave;
+        $scope.tablePairSaveVisible = $table.tablePairSaveVisible;
+
+        $scope.attributesTbl = {
+            type: 'attributes',
+            model: 'attributes',
+            focusId: 'Attribute',
+            ui: 'table-pair',
+            keyName: 'name',
+            valueName: 'value',
+            save: $scope.tableSave
+        };
+
+        $scope.stealingAttributesTbl = {
+            type: 'attributes',
+            model: 'collision.JobStealing.stealingAttributes',
+            focusId: 'CAttribute',
+            ui: 'table-pair',
+            keyName: 'name',
+            valueName: 'value',
+            save: $scope.tableSave
+        };
+
+        $scope.removeFailoverConfiguration = function(idx) {
+            $scope.backupItem.failoverSpi.splice(idx, 1);
         };
 
         // We need to initialize backupItem with empty object in order to properly used from angular directives.
@@ -50,15 +152,13 @@ consoleModule.controller('clustersController', [
         $scope.saveBtnTipText = $common.saveBtnTipText;
         $scope.widthIsSufficient = $common.widthIsSufficient;
 
-        var showPopoverMessage = $common.showPopoverMessage;
-
-        $scope.contentVisible = function () {
-            var item = $scope.backupItem;
+        $scope.contentVisible = function() {
+            const item = $scope.backupItem;
 
             return !item.empty && (!item._id || _.find($scope.displayedRows, {_id: item._id}));
         };
 
-        $scope.toggleExpanded = function () {
+        $scope.toggleExpanded = function() {
             $scope.ui.expanded = !$scope.ui.expanded;
 
             $common.hidePopover();
@@ -77,14 +177,14 @@ consoleModule.controller('clustersController', [
 
         $scope.swapSpaceSpis = [
             {value: 'FileSwapSpaceSpi', label: 'File-based swap'},
-            {value: undefined, label: 'Not set'}
+            {value: null, label: 'Not set'}
         ];
 
         $scope.eventGroups = igniteEventGroups;
 
         $scope.clusters = [];
 
-        function _clusterLbl (cluster) {
+        function _clusterLbl(cluster) {
             return cluster.name + ', ' + _.find($scope.discoveries, {value: cluster.discovery.kind}).label;
         }
 
@@ -93,46 +193,36 @@ consoleModule.controller('clustersController', [
                 $scope.selectItem($scope.clusters[0]);
         }
 
-        function clusterCaches(item) {
-            return _.reduce($scope.caches, function (memo, cache) {
-                if (item && _.includes(item.caches, cache.value)) {
-                    memo.push(cache.cache);
-                }
-
-                return memo;
-            }, []);
-        }
-
         $loading.start('loadingClustersScreen');
 
         // When landing on the page, get clusters and show them.
         $http.post('/api/v1/configuration/clusters/list')
-            .success(function (data) {
+            .success(function(data) {
                 $scope.spaces = data.spaces;
+                $scope.clusters = data.clusters;
+                $scope.caches = _.map(data.caches, (cache) => ({value: cache._id, label: cache.name, cache}));
+                $scope.igfss = _.map(data.igfss, (igfs) => ({value: igfs._id, label: igfs.name, igfs}));
 
-                _.forEach(data.clusters, function (cluster) {
+                _.forEach($scope.clusters, (cluster) => {
                     cluster.label = _clusterLbl(cluster);
-                });
 
-                $scope.clusters = data.clusters;
+                    if (!cluster.collision || !cluster.collision.kind)
+                        cluster.collision = {kind: 'Noop', JobStealing: {stealingEnabled: true}, PriorityQueue: {starvationPreventionEnabled: true}};
 
-                $scope.caches = _.map(data.caches, function (cache) {
-                    return {value: cache._id, label: cache.name, cache: cache};
-                });
+                    if (!cluster.failoverSpi)
+                        cluster.failoverSpi = [];
 
-                $scope.igfss = _.map(data.igfss, function (igfs) {
-                    return {value: igfs._id, label: igfs.name, igfs: igfs};
+                    if (!cluster.logger)
+                        cluster.logger = {Log4j: { mode: 'Default'}};
                 });
 
-                if ($state.params.id)
-                    $scope.createItem($state.params.id);
+                if ($state.params.linkId)
+                    $scope.createItem($state.params.linkId);
                 else {
-                    var lastSelectedCluster = angular.fromJson(sessionStorage.lastSelectedCluster);
+                    const lastSelectedCluster = angular.fromJson(sessionStorage.lastSelectedCluster);
 
                     if (lastSelectedCluster) {
-                        var idx = _.findIndex($scope.clusters, function (cluster) {
-                            return cluster._id === lastSelectedCluster;
-                        });
+                        const idx = _.findIndex($scope.clusters, (cluster) => cluster._id === lastSelectedCluster);
 
                         if (idx >= 0)
                             $scope.selectItem($scope.clusters[idx]);
@@ -147,39 +237,35 @@ consoleModule.controller('clustersController', [
                 }
 
                 $scope.$watch('ui.inputForm.$valid', function(valid) {
-                    if (valid && __original_value === JSON.stringify($cleanup($scope.backupItem))) {
+                    if (valid && _.isEqual(__original_value, $cleanup($scope.backupItem)))
                         $scope.ui.inputForm.$dirty = false;
-                    }
                 });
 
-                $scope.$watch('backupItem', function (val) {
-                    var form = $scope.ui.inputForm;
+                $scope.$watch('backupItem', function(val) {
+                    const form = $scope.ui.inputForm;
 
-                    if (form.$pristine || (form.$valid && __original_value === JSON.stringify($cleanup(val))))
+                    if (form.$pristine || (form.$valid && _.isEqual(__original_value, $cleanup(val))))
                         form.$setPristine();
                     else
                         form.$setDirty();
                 }, true);
 
-                if ($root.IgniteDemoMode) {
-                    if (sessionStorage.showDemoInfo !== 'true') {
-                        sessionStorage.showDemoInfo = 'true';
+                if ($root.IgniteDemoMode && sessionStorage.showDemoInfo !== 'true') {
+                    sessionStorage.showDemoInfo = 'true';
 
-                        DemoInfo.show();
-                    }
+                    DemoInfo.show();
                 }
-
             })
-            .catch(function (errMsg) {
+            .catch(function(errMsg) {
                 $common.showError(errMsg);
             })
-            .finally(function () {
+            .finally(function() {
                 $scope.ui.ready = true;
                 $scope.ui.inputForm.$setPristine();
                 $loading.finish('loadingClustersScreen');
             });
 
-        $scope.selectItem = function (item, backup) {
+        $scope.selectItem = function(item, backup) {
             function selectItem() {
                 $scope.selectedItem = item;
 
@@ -198,11 +284,11 @@ consoleModule.controller('clustersController', [
                 else if (item)
                     $scope.backupItem = angular.copy(item);
                 else
-                    $scope.backupItem = emptyCluster ;
+                    $scope.backupItem = emptyCluster;
 
                 $scope.backupItem = angular.merge({}, blank, $scope.backupItem);
 
-                __original_value = JSON.stringify($cleanup($scope.backupItem));
+                __original_value = $cleanup($scope.backupItem);
 
                 if ($common.getQueryVariable('new'))
                     $state.go('base.configuration.clusters');
@@ -211,202 +297,150 @@ consoleModule.controller('clustersController', [
             $common.confirmUnsavedChanges($scope.backupItem && $scope.ui.inputForm.$dirty, selectItem);
         };
 
-        function prepareNewItem(id) {
-            var newItem = {
-                discovery: {
-                    kind: 'Multicast',
-                    Vm: {addresses: ['127.0.0.1:47500..47510']},
-                    Multicast: {addresses: ['127.0.0.1:47500..47510']}
-                },
-                binaryConfiguration: {
-                    typeConfigurations: [],
-                    compactFooter: true
-                },
-                communication: {
-                    tcpNoDelay: true
-                },
-                connector: {
-                    noDelay: true
-                }
-            };
-
-            newItem = angular.merge({}, blank, newItem);
-
-            newItem.caches = id && _.find($scope.caches, {value: id}) ? [id] : [];
-            newItem.igfss = id && _.find($scope.igfss, {value: id}) ? [id] : [];
-            newItem.space = $scope.spaces[0]._id;
-
-            return newItem;
+        $scope.linkId = () => $scope.backupItem._id ? $scope.backupItem._id : 'create';
+
+        function prepareNewItem(linkId) {
+            return angular.merge({}, blank, {
+                space: $scope.spaces[0]._id,
+                discovery: {kind: 'Multicast', Vm: {addresses: ['127.0.0.1:47500..47510']}, Multicast: {addresses: ['127.0.0.1:47500..47510']}},
+                binaryConfiguration: {typeConfigurations: [], compactFooter: true},
+                communication: {tcpNoDelay: true},
+                connector: {noDelay: true},
+                collision: {kind: 'Noop', JobStealing: {stealingEnabled: true}, PriorityQueue: {starvationPreventionEnabled: true}},
+                failoverSpi: [],
+                logger: {Log4j: { mode: 'Default'}},
+                caches: linkId && _.find($scope.caches, {value: linkId}) ? [linkId] : [],
+                igfss: linkId && _.find($scope.igfss, {value: linkId}) ? [linkId] : []
+            });
         }
 
         // Add new cluster.
-        $scope.createItem = function(id) {
-            $timeout(function () {
-                $common.ensureActivePanel($scope.ui, "general", 'clusterName');
-            });
+        $scope.createItem = function(linkId) {
+            $timeout(() => $common.ensureActivePanel($scope.ui, 'general', 'clusterName'));
 
-            $scope.selectItem(undefined, prepareNewItem(id));
+            $scope.selectItem(null, prepareNewItem(linkId));
         };
 
-        $scope.indexOfCache = function (cacheId) {
-            return _.findIndex($scope.caches, function (cache) {
-                return cache.value === cacheId;
-            });
+        $scope.indexOfCache = function(cacheId) {
+            return _.findIndex($scope.caches, (cache) => cache.value === cacheId);
         };
 
-        // Check cluster logical consistency.
-        function validate(item) {
-            $common.hidePopover();
-
-            if ($common.isEmptyString(item.name))
-                return showPopoverMessage($scope.ui, 'general', 'clusterName', 'Cluster name should not be empty!');
-
-            var form = $scope.ui.inputForm;
-            var errors = form.$error;
-            var errKeys = Object.keys(errors);
-
-            if (errKeys && errKeys.length > 0) {
-                var firstErrorKey = errKeys[0];
-
-                var firstError = errors[firstErrorKey][0];
-                var actualError = firstError.$error[firstErrorKey][0];
-
-                var errNameFull = actualError.$name;
-                var errNameShort = errNameFull;
-
-                if (errNameShort.endsWith('TextInput'))
-                    errNameShort = errNameShort.substring(0, errNameShort.length - 9);
+        function clusterCaches(item) {
+            return _.filter(_.map($scope.caches, (scopeCache) => scopeCache.cache),
+                (cache) => _.includes(item.caches, cache._id));
+        }
 
-                var extractErrorMessage = function (errName) {
-                    try {
-                        return errors[firstErrorKey][0].$errorMessages[errName][firstErrorKey];
-                    }
-                    catch(ignored) {
-                        try {
-                            msg = form[firstError.$name].$errorMessages[errName][firstErrorKey];
-                        }
-                        catch(ignited) {
-                            return false;
-                        }
-                    }
-                };
+        function checkCacheDatasources(item) {
+            const caches = clusterCaches(item);
 
-                var msg = extractErrorMessage(errNameFull) || extractErrorMessage(errNameShort) || 'Invalid value!';
+            const checkRes = $common.checkCachesDataSources(caches);
 
-                return showPopoverMessage($scope.ui, firstError.$name, errNameFull, msg);
+            if (!checkRes.checked) {
+                return showPopoverMessage($scope.ui, 'general', 'caches',
+                    'Found caches "' + checkRes.firstCache.name + '" and "' + checkRes.secondCache.name + '" ' +
+                    'with the same data source bean name "' + checkRes.firstCache.cacheStoreFactory[checkRes.firstCache.cacheStoreFactory.kind].dataSourceBean +
+                    '" and different databases: "' + $common.cacheStoreJdbcDialectsLabel(checkRes.firstDB) + '" in "' + checkRes.firstCache.name + '" and "' +
+                    $common.cacheStoreJdbcDialectsLabel(checkRes.secondDB) + '" in "' + checkRes.secondCache.name + '"', 10000);
             }
 
-            var caches = _.filter(_.map($scope.caches, function (scopeCache) {
-                return scopeCache.cache;
-            }), function (cache) {
-                return _.includes($scope.backupItem.caches, cache._id);
-            });
+            return true;
+        }
 
-            var checkRes = $common.checkCachesDataSources(caches);
+        function checkCacheSQLSchemas(item) {
+            const caches = clusterCaches(item);
+
+            const checkRes = $common.checkCacheSQLSchemas(caches);
 
             if (!checkRes.checked) {
                 return showPopoverMessage($scope.ui, 'general', 'caches',
                     'Found caches "' + checkRes.firstCache.name + '" and "' + checkRes.secondCache.name + '" ' +
-                    'with the same data source bean name "' + checkRes.firstCache.cacheStoreFactory[checkRes.firstCache.cacheStoreFactory.kind].dataSourceBean +
-                    '" and different databases: "' + $common.cacheStoreJdbcDialectsLabel(checkRes.firstDB) + '" in "' + checkRes.firstCache.name + '" and "' +
-                    $common.cacheStoreJdbcDialectsLabel(checkRes.secondDB) + '" in "' + checkRes.secondCache.name + '"', 10000);
+                    'with the same SQL schema name "' + checkRes.firstCache.sqlSchema + '"', 10000);
             }
 
-            var b = item.binaryConfiguration;
+            return true;
+        }
+
+        function checkBinaryConfiguration(item) {
+            const b = item.binaryConfiguration;
 
             if ($common.isDefined(b)) {
                 if (!_.isEmpty(b.typeConfigurations)) {
-                    var sameName = function (t, ix) {
-                        return ix < typeIx && t.typeName === type.typeName;
-                    };
-
-                    for (var typeIx = 0; typeIx < b.typeConfigurations.length; typeIx++) {
-                        var type = b.typeConfigurations[typeIx];
+                    for (let typeIx = 0; typeIx < b.typeConfigurations.length; typeIx++) {
+                        const type = b.typeConfigurations[typeIx];
 
                         if ($common.isEmptyString(type.typeName))
                             return showPopoverMessage($scope.ui, 'binary', 'typeName' + typeIx, 'Type name should be specified!');
 
-                        if (_.find(b.typeConfigurations, sameName))
+                        if (_.find(b.typeConfigurations, (t, ix) => ix < typeIx && t.typeName === type.typeName))
                             return showPopoverMessage($scope.ui, 'binary', 'typeName' + typeIx, 'Type with such name is already specified!');
                     }
                 }
             }
 
-            var c = item.communication;
+            return true;
+        }
+
+        function checkCommunicationConfiguration(item) {
+            const c = item.communication;
 
             if ($common.isDefined(c)) {
                 if ($common.isDefined(c.unacknowledgedMessagesBufferSize)) {
-                    if ($common.isDefined(c.messageQueueLimit))
-                        if (c.unacknowledgedMessagesBufferSize < 5 * c.messageQueueLimit)
-                            return showPopoverMessage($scope.ui, 'communication', 'unacknowledgedMessagesBufferSize', 'Maximum number of stored unacknowledged messages should be at least 5 * message queue limit!');
+                    if ($common.isDefined(c.messageQueueLimit) && c.unacknowledgedMessagesBufferSize < 5 * c.messageQueueLimit)
+                        return showPopoverMessage($scope.ui, 'communication', 'unacknowledgedMessagesBufferSize', 'Maximum number of stored unacknowledged messages should be at least 5 * message queue limit!');
 
-                    if ($common.isDefined(c.ackSendThreshold))
-                        if (c.unacknowledgedMessagesBufferSize < 5 * c.ackSendThreshold)
-                            return showPopoverMessage($scope.ui, 'communication', 'unacknowledgedMessagesBufferSize', 'Maximum number of stored unacknowledged messages should be at least 5 * ack send threshold!');
+                    if ($common.isDefined(c.ackSendThreshold) && c.unacknowledgedMessagesBufferSize < 5 * c.ackSendThreshold)
+                        return showPopoverMessage($scope.ui, 'communication', 'unacknowledgedMessagesBufferSize', 'Maximum number of stored unacknowledged messages should be at least 5 * ack send threshold!');
                 }
 
                 if (c.sharedMemoryPort === 0)
                     return showPopoverMessage($scope.ui, 'communication', 'sharedMemoryPort', 'Shared memory port should be more than "0" or equals to "-1"!');
             }
 
-            var r = item.connector;
-
-            if ($common.isDefined(r)) {
-                if (r.sslEnabled && $common.isEmptyString(r.sslFactory))
-                    return showPopoverMessage($scope.ui, 'connector', 'connectorSslFactory', 'SSL factory should not be empty!');
-            }
+            return true;
+        }
 
-            var d = item.discovery;
+        function checkDiscoveryConfiguration(item) {
+            const d = item.discovery;
 
             if (d) {
-                if ((d.maxAckTimeout != undefined ? d.maxAckTimeout : 600000) < (d.ackTimeout || 5000))
+                if ((_.isNil(d.maxAckTimeout) ? 600000 : d.maxAckTimeout) < (d.ackTimeout || 5000))
                     return showPopoverMessage($scope.ui, 'discovery', 'ackTimeout', 'Acknowledgement timeout should be less than max acknowledgement timeout!');
 
                 if (d.kind === 'Vm' && d.Vm && d.Vm.addresses.length === 0)
                     return showPopoverMessage($scope.ui, 'general', 'addresses', 'Addresses are not specified!');
-
-                if (d.kind === 'S3' && d.S3 && $common.isEmptyString(d.S3.bucketName))
-                    return showPopoverMessage($scope.ui, 'general', 'bucketName', 'Bucket name should not be empty!');
-
-                if (d.kind === 'Cloud' && d.Cloud) {
-                    if ($common.isEmptyString(d.Cloud.identity))
-                        return showPopoverMessage($scope.ui, 'general', 'identity', 'Identity should not be empty!');
-
-                    if ($common.isEmptyString(d.Cloud.provider))
-                        return showPopoverMessage($scope.ui, 'general', 'provider', 'Provider should not be empty!');
-                }
-
-                if (d.kind === 'GoogleStorage' && d.GoogleStorage) {
-                    if ($common.isEmptyString(d.GoogleStorage.projectName))
-                        return showPopoverMessage($scope.ui, 'general', 'projectName', 'Project name should not be empty!');
-
-                    if ($common.isEmptyString(d.GoogleStorage.bucketName))
-                        return showPopoverMessage($scope.ui, 'general', 'bucketName', 'Bucket name should not be empty!');
-
-                    if ($common.isEmptyString(d.GoogleStorage.serviceAccountP12FilePath))
-                        return showPopoverMessage($scope.ui, 'general', 'serviceAccountP12FilePath', 'Private key path should not be empty!');
-
-                    if ($common.isEmptyString(d.GoogleStorage.serviceAccountId))
-                        return showPopoverMessage($scope.ui, 'general', 'serviceAccountId', 'Account ID should not be empty!');
-                }
             }
 
-            var swapKind = item.swapSpaceSpi && item.swapSpaceSpi.kind;
+            return true;
+        }
+
+        function checkSwapConfiguration(item) {
+            const swapKind = item.swapSpaceSpi && item.swapSpaceSpi.kind;
 
             if (swapKind && item.swapSpaceSpi[swapKind]) {
-                var swap = item.swapSpaceSpi[swapKind];
+                const swap = item.swapSpaceSpi[swapKind];
 
-                var sparsity = swap.maximumSparsity;
+                const sparsity = swap.maximumSparsity;
 
                 if ($common.isDefined(sparsity) && (sparsity < 0 || sparsity >= 1))
                     return showPopoverMessage($scope.ui, 'swap', 'maximumSparsity', 'Maximum sparsity should be more or equal 0 and less than 1!');
 
-                var readStripesNumber = swap.readStripesNumber;
+                const readStripesNumber = swap.readStripesNumber;
 
-                if (readStripesNumber && !(readStripesNumber == -1 || (readStripesNumber & (readStripesNumber - 1)) == 0))
+                if (readStripesNumber && !(readStripesNumber === -1 || (readStripesNumber & (readStripesNumber - 1)) === 0))
                     return showPopoverMessage($scope.ui, 'swap', 'readStripesNumber', 'Read stripe size must be positive and power of two!');
             }
 
+            return true;
+        }
+
+        function checkSslConfiguration(item) {
+            const r = item.connector;
+
+            if ($common.isDefined(r)) {
+                if (r.sslEnabled && $common.isEmptyString(r.sslFactory))
+                    return showPopoverMessage($scope.ui, 'connector', 'connectorSslFactory', 'SSL factory should not be empty!');
+            }
+
             if (item.sslEnabled) {
                 if (!$common.isDefined(item.sslContextFactory) || $common.isEmptyString(item.sslContextFactory.keyStoreFilePath))
                     return showPopoverMessage($scope.ui, 'sslConfiguration', 'keyStoreFilePath', 'Key store file should not be empty!');
@@ -415,23 +449,49 @@ consoleModule.controller('clustersController', [
                     return showPopoverMessage($scope.ui, 'sslConfiguration', 'sslConfiguration-title', 'Trust storage file or managers should be configured!');
             }
 
-            if (!swapKind && item.caches) {
-                for (var i = 0; i < item.caches.length; i++) {
-                    var idx = $scope.indexOfCache(item.caches[i]);
+            return true;
+        }
 
-                    if (idx >= 0) {
-                        var cache = $scope.caches[idx];
+        function checkPoolSizes(item) {
+            if (item.rebalanceThreadPoolSize && item.systemThreadPoolSize && item.systemThreadPoolSize <= item.rebalanceThreadPoolSize)
+                return showPopoverMessage($scope.ui, 'pools', 'rebalanceThreadPoolSize', 'Rebalance thread pool size exceed or equals System thread pool size!');
 
-                        if (cache.cache.swapEnabled)
-                            return showPopoverMessage($scope.ui, 'swap', 'swapSpaceSpi',
-                                'Swap space SPI is not configured, but cache "' + cache.label + '" configured to use swap!');
-                    }
-                }
-            }
+            return true;
+        }
 
-            if (item.rebalanceThreadPoolSize && item.systemThreadPoolSize && item.systemThreadPoolSize <= item.rebalanceThreadPoolSize)
-                return showPopoverMessage($scope.ui, 'pools', 'rebalanceThreadPoolSize',
-                    'Rebalance thread pool size exceed or equals System thread pool size!');
+        // Check cluster logical consistency.
+        function validate(item) {
+            $common.hidePopover();
+
+            if ($common.isEmptyString(item.name))
+                return showPopoverMessage($scope.ui, 'general', 'clusterName', 'Cluster name should not be empty!');
+
+            if (!$common.checkFieldValidators($scope.ui))
+                return false;
+
+            if (!checkCacheSQLSchemas(item))
+                return false;
+
+            if (!checkCacheDatasources(item))
+                return false;
+
+            if (!checkBinaryConfiguration(item))
+                return false;
+
+            if (!checkCommunicationConfiguration(item))
+                return false;
+
+            if (!checkDiscoveryConfiguration(item))
+                return false;
+
+            if (!checkSwapConfiguration(item))
+                return false;
+
+            if (!checkSslConfiguration(item))
+                return false;
+
+            if (!checkPoolSizes(item))
+                return false;
 
             return true;
         }
@@ -439,12 +499,12 @@ consoleModule.controller('clustersController', [
         // Save cluster in database.
         function save(item) {
             $http.post('/api/v1/configuration/clusters/save', item)
-                .success(function (_id) {
+                .success(function(_id) {
                     item.label = _clusterLbl(item);
 
                     $scope.ui.inputForm.$setPristine();
 
-                    var idx = _.findIndex($scope.clusters, (cluster) => cluster._id === _id);
+                    const idx = _.findIndex($scope.clusters, (cluster) => cluster._id === _id);
 
                     if (idx >= 0)
                         angular.merge($scope.clusters[idx], item);
@@ -453,6 +513,20 @@ consoleModule.controller('clustersController', [
                         $scope.clusters.push(item);
                     }
 
+                    _.forEach($scope.caches, (cache) => {
+                        if (_.includes(item.caches, cache.value))
+                            cache.cache.clusters = _.union(cache.cache.clusters, [_id]);
+                        else
+                            _.remove(cache.cache.clusters, (id) => id === _id);
+                    });
+
+                    _.forEach($scope.igfss, (igfs) => {
+                        if (_.includes(item.igfss, igfs.value))
+                            igfs.igfs.clusters = _.union(igfs.igfs.clusters, [_id]);
+                        else
+                            _.remove(igfs.igfs.clusters, (id) => id === _id);
+                    });
+
                     $scope.selectItem(item);
 
                     $common.showInfo('Cluster "' + item.name + '" saved.');
@@ -461,10 +535,10 @@ consoleModule.controller('clustersController', [
         }
 
         // Save cluster.
-        $scope.saveItem = function () {
-            var item = $scope.backupItem;
+        $scope.saveItem = function() {
+            const item = $scope.backupItem;
 
-            var swapSpi = $common.autoClusterSwapSpiConfiguration(item, clusterCaches(item));
+            const swapSpi = $common.autoClusterSwapSpiConfiguration(item, clusterCaches(item));
 
             if (swapSpi)
                 angular.extend(item, swapSpi);
@@ -474,16 +548,14 @@ consoleModule.controller('clustersController', [
         };
 
         function _clusterNames() {
-            return _.map($scope.clusters, function (cluster) {
-                return cluster.name;
-            });
+            return _.map($scope.clusters, (cluster) => cluster.name);
         }
 
         // Clone cluster with new name.
-        $scope.cloneItem = function () {
+        $scope.cloneItem = function() {
             if (validate($scope.backupItem)) {
-                $clone.confirm($scope.backupItem.name, _clusterNames()).then(function (newName) {
-                    var item = angular.copy($scope.backupItem);
+                $clone.confirm($scope.backupItem.name, _clusterNames()).then(function(newName) {
+                    const item = angular.copy($scope.backupItem);
 
                     delete item._id;
                     item.name = newName;
@@ -494,51 +566,58 @@ consoleModule.controller('clustersController', [
         };
 
         // Remove cluster from db.
-        $scope.removeItem = function () {
-            var selectedItem = $scope.selectedItem;
+        $scope.removeItem = function() {
+            const selectedItem = $scope.selectedItem;
 
             $confirm.confirm('Are you sure you want to remove cluster: "' + selectedItem.name + '"?')
-                .then(function () {
-                    var _id = selectedItem._id;
+                .then(function() {
+                    const _id = selectedItem._id;
 
-                    $http.post('/api/v1/configuration/clusters/remove', {_id: _id})
-                        .success(function () {
+                    $http.post('/api/v1/configuration/clusters/remove', {_id})
+                        .success(function() {
                             $common.showInfo('Cluster has been removed: ' + selectedItem.name);
 
-                            var clusters = $scope.clusters;
+                            const clusters = $scope.clusters;
 
-                            var idx = _.findIndex(clusters, function (cluster) {
-                                return cluster._id === _id;
-                            });
+                            const idx = _.findIndex(clusters, (cluster) => cluster._id === _id);
 
                             if (idx >= 0) {
                                 clusters.splice(idx, 1);
 
                                 if (clusters.length > 0)
                                     $scope.selectItem(clusters[0]);
-                                else
+                                else {
                                     $scope.backupItem = emptyCluster;
+                                    $scope.ui.inputForm.$setPristine();
+                                }
+
+                                _.forEach($scope.caches, (cache) => _.remove(cache.cache.clusters, (id) => id === _id));
+                                _.forEach($scope.igfss, (igfs) => _.remove(igfs.igfs.clusters, (id) => id === _id));
                             }
                         })
-                        .error(function (errMsg) {
+                        .error(function(errMsg) {
                             $common.showError(errMsg);
                         });
                 });
         };
 
         // Remove all clusters from db.
-        $scope.removeAllItems = function () {
+        $scope.removeAllItems = function() {
             $confirm.confirm('Are you sure you want to remove all clusters?')
-                .then(function () {
+                .then(function() {
                     $http.post('/api/v1/configuration/clusters/remove/all')
-                        .success(function () {
+                        .success(function() {
                             $common.showInfo('All clusters have been removed');
 
                             $scope.clusters = [];
+
+                            _.forEach($scope.caches, (cache) => cache.cache.clusters = []);
+                            _.forEach($scope.igfss, (igfs) => igfs.igfs.clusters = []);
+
                             $scope.backupItem = emptyCluster;
                             $scope.ui.inputForm.$setPristine();
                         })
-                        .error(function (errMsg) {
+                        .error(function(errMsg) {
                             $common.showError(errMsg);
                         });
                 });


[33/50] [abbrv] ignite git commit: Ignite Web Console beta2.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/serve/routes/public.js
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/serve/routes/public.js b/modules/web-console/src/main/js/serve/routes/public.js
index 0009e6a..207289a 100644
--- a/modules/web-console/src/main/js/serve/routes/public.js
+++ b/modules/web-console/src/main/js/serve/routes/public.js
@@ -112,12 +112,16 @@ module.exports.factory = function(express, passport, nodemailer, settings, mail,
                     account.resetPasswordToken = _randomString();
 
                     return account.save()
-                        .then(() => mail.send(account, `Thanks for signing up for ${settings.smtp.username}.`,
-                            `Hello ${account.firstName} ${account.lastName}!<br><br>` +
-                            `You are receiving this email because you have signed up to use <a href="http://${req.headers.host}">${settings.smtp.username}</a>.<br><br>` +
-                            'If you have not done the sign up and do not know what this email is about, please ignore it.<br>' +
-                            'You may reset the password by clicking on the following link, or paste this into your browser:<br><br>' +
-                            `http://${req.headers.host}/password/reset?token=${account.resetPasswordToken}`));
+                        .then(() => {
+                            const resetLink = `http://${req.headers.host}/password/reset?token=${account.resetPasswordToken}`;
+
+                            mail.send(account, `Thanks for signing up for ${settings.smtp.username}.`,
+                                `Hello ${account.firstName} ${account.lastName}!<br><br>` +
+                                `You are receiving this email because you have signed up to use <a href="http://${req.headers.host}">${settings.smtp.username}</a>.<br><br>` +
+                                'If you have not done the sign up and do not know what this email is about, please ignore it.<br>' +
+                                'You may reset the password by clicking on the following link, or paste this into your browser:<br><br>' +
+                                `<a href="${resetLink}">${resetLink}</a>`);
+                        });
                 })
                 .catch((err) => {
                     res.status(401).send(err.message);
@@ -166,14 +170,17 @@ module.exports.factory = function(express, passport, nodemailer, settings, mail,
 
                     return user.save();
                 })
-                .then((user) => mail.send(user, 'Password Reset',
-                    `Hello ${user.firstName} ${user.lastName}!<br><br>` +
-                    'You are receiving this because you (or someone else) have requested the reset of the password for your account.<br><br>' +
-                    'Please click on the following link, or paste this into your browser to complete the process:<br><br>' +
-                    'http://' + req.headers.host + '/password/reset?token=' + user.resetPasswordToken + '<br><br>' +
-                    'If you did not request this, please ignore this email and your password will remain unchanged.',
-                    'Failed to send email with reset link!')
-                )
+                .then((user) => {
+                    const resetLink = `http://${req.headers.host}/password/reset?token=${user.resetPasswordToken}`;
+
+                    mail.send(user, 'Password Reset',
+                        `Hello ${user.firstName} ${user.lastName}!<br><br>` +
+                        'You are receiving this because you (or someone else) have requested the reset of the password for your account.<br><br>' +
+                        'Please click on the following link, or paste this into your browser to complete the process:<br><br>' +
+                        `<a href="${resetLink}">${resetLink}</a><br><br>` +
+                        'If you did not request this, please ignore this email and your password will remain unchanged.',
+                        'Failed to send email with reset link!');
+                })
                 .then(() => res.status(200).send('An email has been sent with further instructions.'))
                 .catch((err) => {
                     // TODO IGNITE-843 Send email to admin

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/views/configuration/clusters.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/views/configuration/clusters.jade b/modules/web-console/src/main/js/views/configuration/clusters.jade
index 6e29d86..6450163 100644
--- a/modules/web-console/src/main/js/views/configuration/clusters.jade
+++ b/modules/web-console/src/main/js/views/configuration/clusters.jade
@@ -43,12 +43,15 @@ include ../../app/helpers/jade/mixins.jade
                         div(ng-show='ui.expanded')
                             ignite-configuration-clusters-atomic
                             ignite-configuration-clusters-binary
+                            ignite-configuration-clusters-collision
                             ignite-configuration-clusters-communication
                             ignite-configuration-clusters-connector
                             ignite-configuration-clusters-deployment
                             ignite-configuration-clusters-discovery
                             ignite-configuration-clusters-events
+                            ignite-configuration-clusters-failover
                             ignite-configuration-clusters-igfs
+                            ignite-configuration-clusters-logger
                             ignite-configuration-clusters-marshaller
                             ignite-configuration-clusters-metrics
                             ignite-configuration-clusters-ssl
@@ -56,5 +59,6 @@ include ../../app/helpers/jade/mixins.jade
                             ignite-configuration-clusters-thread
                             ignite-configuration-clusters-time
                             ignite-configuration-clusters-transactions
+                            ignite-configuration-user-attributes
 
                             +advanced-options-toggle-default

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/views/configuration/domains-import.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/views/configuration/domains-import.jade b/modules/web-console/src/main/js/views/configuration/domains-import.jade
index 46385f9..23b9434 100644
--- a/modules/web-console/src/main/js/views/configuration/domains-import.jade
+++ b/modules/web-console/src/main/js/views/configuration/domains-import.jade
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
+include ../../app/helpers/jade/mixins.jade
+
 mixin chk(mdl, change, tip)
     input(type='checkbox' ng-model=mdl ng-change=change bs-tooltip='' data-title=tip data-trigger='hover' data-placement='top')
 
@@ -22,174 +24,187 @@ mixin td-ellipses-lbl(w, lbl)
         label #{lbl}
 
 .modal.modal-domain-import.center(role='dialog')
-    .modal-dialog
+    .modal-dialog.domains-import-dialog
         .modal-content(ignite-loading='importDomainFromDb' ignite-loading-text='{{importDomain.loadingOptions.text}}')
             #errors-container.modal-header.header
                 button.close(ng-click='$hide()' aria-hidden='true') &times;
                 h4.modal-title(ng-if='!importDomain.demo') Import domain models from database
                 h4.modal-title(ng-if='importDomain.demo') Import domain models from demo database
-            .import-domain-model-wizard-page(ng-if='importDomain.action == "drivers" && !importDomain.jdbcDriversNotFound' style='margin-bottom: 321px')
-            .import-domain-model-wizard-page(ng-if='importDomain.action == "drivers" && importDomain.jdbcDriversNotFound' style='margin-bottom: 220px')
-                | Domain model could not be imported
-                ul
-                    li Agent failed to find JDBC drivers
-                    li Copy required JDBC drivers into agent '\jdbc-drivers' folder and try again
-                    li Refer to agent README.txt for more information
-            .import-domain-model-wizard-page(ng-show='importDomain.action == "connect" && importDomain.demo' style='margin-bottom: 211px')
-                div(ng-if='demoConnection.db == "H2"')
-                    label Demo description:
+            .modal-body
+                .import-domain-model-wizard-page(ng-if='importDomain.action == "drivers" && !importDomain.jdbcDriversNotFound')
+                .import-domain-model-wizard-page(ng-if='importDomain.action == "drivers" && importDomain.jdbcDriversNotFound')
+                    | Domain model could not be imported
                     ul
-                        li In-memory H2 database server will be started inside agent
-                        li Database will be populated with sample tables
-                        li You could test domain model generation with this demo database
-                        li Click "Next" to continue
-                div(ng-if='demoConnection.db != "H2"')
-                    label Demo could not be started
+                        li Agent failed to find JDBC drivers
+                        li Copy required JDBC drivers into agent 'jdbc-drivers' folder and try again
+                        li Refer to agent README.txt for more information
+                .import-domain-model-wizard-page(ng-show='importDomain.action == "connect" && importDomain.demo')
+                    div(ng-if='demoConnection.db == "H2"')
+                        label Demo description:
                         ul
-                            li Agent failed to resolve H2 database jar
-                            li Copy h2-x.x.x.jar into agent '\jdbc-drivers' folder and try again
-                            li Refer to agent README.txt for more information
-            .import-domain-model-wizard-page(ng-show='importDomain.action == "connect" && !importDomain.demo' style='margin-bottom: 90px')
-                form.form-horizontal(name='connectForm' novalidate)
-                    .settings-row
-                        label.col-xs-4.col-sm-2.col-md-2 Driver JAR:
-                        .col-xs-8.col-sm-10.col-md-10
-                            i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Select appropriate JAR with JDBC driver<br> To add another driver you need to place it into "/jdbc-drivers" folder of Ignite Web Agent<br> Refer to Ignite Web Agent README.txt for for more information')
-                            .input-tip
-                                button.select-toggle.form-control(id='jdbcDriverJar' bs-select data-container='.modal-domain-import' ng-model='ui.selectedJdbcDriverJar' ng-class='{placeholder: !(jdbcDriverJars && jdbcDriverJars.length > 0)}' placeholder='Choose JDBC driver' bs-options='item.value as item.label for item in jdbcDriverJars')
-                    .settings-row
-                        label.col-xs-4.col-sm-2.col-md-2 JDBC Driver:
-                        .col-xs-8.col-sm-10.col-md-10
-                            i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Fully qualified class name of JDBC driver that will be used to connect to database')
-                            .input-tip
-                                input.form-control(id='jdbcDriverClass' type='text' ng-model='selectedPreset.jdbcDriverClass' placeholder='JDBC driver fully qualified class name' required=true)
-                    .settings-row
-                        label.col-xs-4.col-sm-2.col-md-2 JDBC URL:
-                        .col-xs-8.col-sm-10.col-md-10
-                            i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='JDBC URL for connecting to database<br>Refer to your database documentation for details')
-                            .input-tip
-                                input.form-control(id='jdbcUrl' type='text' ng-model='selectedPreset.jdbcUrl' placeholder='JDBC URL' required=true)
-                    .settings-row
-                        label.col-xs-4.col-sm-2.col-md-2 User:
-                        .col-xs-8.col-sm-10.col-md-10
-                            i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='User name for connecting to database')
-                            .input-tip
-                                input.form-control(id='user' type='text' ng-model='selectedPreset.user')
-                    .settings-row
-                        label.col-xs-4.col-sm-2.col-md-2 Password:
-                        .col-xs-8.col-sm-10.col-md-10
-                            i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Password for connecting to database<br>Note, password would not be saved in preferences for security reasons')
-                            .input-tip
-                                input.form-control(id='password' type='password' ng-model='selectedPreset.password' on-enter='importDomainNext()')
-                    .settings-row
-                        .checkbox
-                            label
-                                input(id='tablesOnly' type='checkbox' ng-model='selectedPreset.tablesOnly')
-                                | Tables only
-                            i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='If selected, then only tables metadata will be parsed<br>Otherwise table and view metadata will be parsed')
-            .import-domain-model-wizard-page(ng-show='importDomain.action == "schemas"')
-                table.table.metadata(st-table='importDomain.displayedSchemas' st-safe-src='importDomain.schemas')
-                    thead
-                        tr
-                            th.header(colspan='2')
-                                .col-sm-4.pull-right(style='margin-bottom: 5px')
-                                    input.form-control(type='text' st-search='name' placeholder='Filter schemas...' ng-model='importDomain.displayedSchemasFilter' ng-change='selectSchema()')
-                        tr
-                            th(width='30px')
-                                +chk('importDomain.allSchemasSelected',  'selectAllSchemas()', 'Select all schemas')
-                            th
-                                label Schema
+                            li In-memory H2 database server will be started inside agent
+                            li Database will be populated with sample tables
+                            li You could test domain model generation with this demo database
+                            li Click "Next" to continue
+                    div(ng-if='demoConnection.db != "H2"')
+                        label Demo could not be started
+                            ul
+                                li Agent failed to resolve H2 database jar
+                                li Copy h2-x.x.x.jar into agent 'jdbc-drivers' folder and try again
+                                li Refer to agent README.txt for more information
+                .import-domain-model-wizard-page(ng-show='importDomain.action == "connect" && !importDomain.demo')
+                    form.form-horizontal(name='connectForm' novalidate)
+                        .settings-row
+                            label.col-xs-4.col-sm-2.col-md-2 Driver JAR:
+                            .col-xs-8.col-sm-10.col-md-10
+                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Select appropriate JAR with JDBC driver<br> To add another driver you need to place it into "/jdbc-drivers" folder of Ignite Web Agent<br> Refer to Ignite Web Agent README.txt for for more information')
+                                .input-tip
+                                    button.select-toggle.form-control(id='jdbcDriverJar' bs-select data-container='.modal-domain-import' ng-model='ui.selectedJdbcDriverJar' ng-class='{placeholder: !(jdbcDriverJars && jdbcDriverJars.length > 0)}' placeholder='Choose JDBC driver' bs-options='item.value as item.label for item in jdbcDriverJars')
+                        .settings-row
+                            label.col-xs-4.col-sm-2.col-md-2 JDBC Driver:
+                            .col-xs-8.col-sm-10.col-md-10
+                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Fully qualified class name of JDBC driver that will be used to connect to database')
+                                .input-tip
+                                    input.form-control(id='jdbcDriverClass' type='text' ng-model='selectedPreset.jdbcDriverClass' placeholder='JDBC driver fully qualified class name' required=true)
+                        .settings-row
+                            label.col-xs-4.col-sm-2.col-md-2 JDBC URL:
+                            .col-xs-8.col-sm-10.col-md-10
+                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='JDBC URL for connecting to database<br>Refer to your database documentation for details')
+                                .input-tip
+                                    input.form-control(id='jdbcUrl' type='text' ng-model='selectedPreset.jdbcUrl' placeholder='JDBC URL' required=true)
+                        .settings-row
+                            label.col-xs-4.col-sm-2.col-md-2 User:
+                            .col-xs-8.col-sm-10.col-md-10
+                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='User name for connecting to database')
+                                .input-tip
+                                    input.form-control(id='user' type='text' ng-model='selectedPreset.user')
+                        .settings-row
+                            label.col-xs-4.col-sm-2.col-md-2 Password:
+                            .col-xs-8.col-sm-10.col-md-10
+                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Password for connecting to database<br>Note, password would not be saved in preferences for security reasons')
+                                .input-tip
+                                    input.form-control(id='password' type='password' ng-model='selectedPreset.password' on-enter='importDomainNext()')
+                        .settings-row
+                            .checkbox
+                                label
+                                    input(id='tablesOnly' type='checkbox' ng-model='selectedPreset.tablesOnly')
+                                    | Tables only
+                                i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='If selected, then only tables metadata will be parsed<br>Otherwise table and view metadata will be parsed')
+                .import-domain-model-wizard-page(ng-show='importDomain.action == "schemas"')
+                    table.table.metadata(st-table='importDomain.displayedSchemas' st-safe-src='importDomain.schemas')
+                        thead
+                            tr
+                                th.header(colspan='2')
+                                    .col-sm-4.pull-right(style='margin-bottom: 5px')
+                                        input.form-control(type='text' st-search='name' placeholder='Filter schemas...' ng-model='importDomain.displayedSchemasFilter' ng-change='selectSchema()')
+                            tr
+                                th(width='30px')
+                                    +chk('importDomain.allSchemasSelected',  'selectAllSchemas()', 'Select all schemas')
+                                th
+                                    label Schema
+                            tbody
+                                tr
+                                    td(colspan='2')
+                                        .scrollable-y(style='height: 213px')
+                                            table.table-modal-striped(id='importSchemasData')
+                                                tbody
+                                                    tr(ng-repeat='schema in importDomain.displayedSchemas')
+                                                        td(width='30px')
+                                                            input(type='checkbox' ng-model='schema.use' ng-change='selectSchema()')
+                                                        td
+                                                            label {{schema.name}}
+                .import-domain-model-wizard-page(ng-show='importDomain.action == "tables"')
+                    table.table.metadata(st-table='importDomain.displayedTables' st-safe-src='importDomain.tables')
+                        thead
+                            tr
+                                th.header(colspan='6')
+                                    .col-sm-4.pull-right(style='margin-bottom: 8px')
+                                        input.form-control(type='text' st-search='label' placeholder='Filter tables...' ng-model='importDomain.displayedTablesFilter' ng-change='selectTable()')
+                            tr
+                                th(width='30px')
+                                    +chk('importDomain.allTablesSelected',  'selectAllTables()', 'Select all tables')
+                                th(width='130px')
+                                    label Schema
+                                th(width='160px')
+                                    label Table name
+                                th(colspan=2 width='288px')
+                                    label Cache
+                                th
                         tbody
                             tr
-                                td(colspan='2')
-                                    .scrollable-y(style='height: 213px')
-                                        table.table-modal-striped(id='importSchemasData')
+                                td(colspan='6')
+                                    .scrollable-y(style='height: 143px')
+                                        table.table-modal-striped(id='importTableData')
                                             tbody
-                                                tr(ng-repeat='schema in importDomain.displayedSchemas')
-                                                    td(width='30px')
-                                                        input(type='checkbox' ng-model='schema.use' ng-change='selectSchema()')
+                                                tr(ng-repeat='table in importDomain.displayedTables track by $index')
+                                                    td(width='30px' style='min-width: 30px; max-width: 30px')
+                                                        input(type='checkbox' ng-model='table.use' ng-change='selectTable()')
+                                                    +td-ellipses-lbl('130px', '{{table.schema}}')
+                                                    +td-ellipses-lbl('160px', '{{table.tbl}}')
+                                                    td(colspan='2' width='288px' style='min-width: 160px; max-width: 160px')
+                                                        div.td-ellipsis
+                                                            a(ng-if='!table.edit' ng-click='startEditDbTableCache(table)') {{tableActionView(table)}}
+                                                            div(style='display: flex' ng-if='table.edit')
+                                                                button.select-toggle.form-control(style='width: 35%; margin-right: 5px' bs-select ng-model='table.action' data-container='.modal-domain-import' bs-options='item.value as item.shortLabel for item in importActions')
+                                                                button.select-toggle.form-control(style='width: 65%; margin-right: 0' bs-select ng-model='table.cacheOrTemplate' data-container='.modal-domain-import' bs-options='item.value as item.label for item in table.cachesOrTemplates')
                                                     td
-                                                        label {{schema.name}}
-            .import-domain-model-wizard-page(ng-show='importDomain.action == "tables"')
-                table.table.metadata(st-table='importDomain.displayedTables' st-safe-src='importDomain.tables')
-                    thead
-                        tr
-                            th.header(colspan='6')
-                                .col-sm-4.pull-right(style='margin-bottom: 8px')
-                                    input.form-control(type='text' st-search='label' placeholder='Filter tables...' ng-model='importDomain.displayedTablesFilter' ng-change='selectTable()')
-                        tr
-                            th(width='30px')
-                                +chk('importDomain.allTablesSelected',  'selectAllTables()', 'Select all tables')
-                            th(width='130px')
-                                label Schema
-                            th(width='160px')
-                                label Table name
-                            th(colspan=2 width='288px')
-                                label Cache
-                            th
-                    tbody
-                        tr
-                            td(colspan='6')
-                                .scrollable-y(style='height: 143px')
-                                    table.table-modal-striped(id='importTableData')
-                                        tbody
-                                            tr(ng-repeat='table in importDomain.displayedTables track by $index')
-                                                td(width='30px' style='min-width: 30px; max-width: 30px')
-                                                    input(type='checkbox' ng-model='table.use' ng-change='selectTable()')
-                                                +td-ellipses-lbl('130px', '{{table.schema}}')
-                                                +td-ellipses-lbl('160px', '{{table.tbl}}')
-                                                td(colspan='2' width='288px' style='min-width: 160px; max-width: 160px')
-                                                    div.td-ellipsis
-                                                        a(ng-if='!table.edit' ng-click='startEditDbTableCache(table)') {{tableActionView(table)}}
-                                                        div(style='display: flex' ng-if='table.edit')
-                                                            button.select-toggle.form-control(style='width: 35%; margin-right: 5px' bs-select ng-model='table.action' data-container='.modal-domain-import' bs-options='item.value as item.shortLabel for item in importActions')
-                                                            button.select-toggle.form-control(style='width: 65%; margin-right: 0' bs-select ng-model='table.cacheOrTemplate' data-container='.modal-domain-import' bs-options='item.value as item.label for item in table.cachesOrTemplates')
-                                                td
-                .settings-row
-                    label Defaults to be applied for filtered tables
-                    i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Select and apply options for caches generation')
-                .settings-row
-                    .col-sm-11
-                        .col-sm-6(style='padding-right: 5px')
-                            button.select-toggle.form-control(bs-select ng-model='importCommon.action' data-container='.modal-domain-import' bs-options='item.value as item.label for item in importActions')
-                        .col-sm-6(style='padding-left: 5px; padding-right: 5px')
-                            button.select-toggle.form-control(bs-select ng-model='importCommon.cacheOrTemplate' data-container='.modal-domain-import' bs-options='item.value as item.label for item in importCommon.cachesOrTemplates')
-                    .col-sm-1(style='padding-left: 5px')
-                        button.btn.btn-primary(ng-click='applyDefaults()') Apply
-            .import-domain-model-wizard-page(ng-show='importDomain.action == "options"' style='margin-bottom: 176px')
-                form.form-horizontal(name='optionsForm' novalidate)
-                    .settings-row
-                        .col-xs-3.col-sm-2.col-md-2.required
-                            label.required Package:
-                        .col-xs-9.col-sm-10.col-md-10
-                            i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Package that will be used for POJOs generation')
-                            .input-tip
-                                input.form-control(id='domainPackageName' type='text' ng-model='ui.packageName' placeholder='Package for POJOs generation')
-                    .settings-row
-                        .checkbox
-                            label
-                                input(id='domainBuiltinKeys' type='checkbox' ng-model='ui.builtinKeys')
-                                | Use Java built-in types for keys
-                                i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Use Java built-in types like "Integer", "Long", "String" instead of POJO generation in case when table primary key contains only one field')
-                    .settings-row
-                        .checkbox
-                            label
-                                input(id='domainUsePrimitives' type='checkbox' ng-model='ui.usePrimitives')
-                                | Use primitive types for NOT NULL table columns
-                                i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Use primitive types like "int", "long", "double" for POJOs fields generation in case of NOT NULL columns')
                     .settings-row
-                        .checkbox
-                            label
-                                input(id='domainGenerateAliases' type='checkbox' ng-model='ui.generateAliases')
-                                | Generate aliases for query fields
-                                i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Generate aliases for query fields with names from database fields')
+                        label Defaults to be applied for filtered tables
+                        i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Select and apply options for caches generation')
                     .settings-row
-                        .col-xs-3.col-sm-2.col-md-2.required
-                            label Clusters:
-                        .col-xs-9.col-sm-10.col-md-10
-                            i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Choose clusters that will be associated with generated caches')
-                            .input-tip
-                                button.select-toggle.form-control(id='generatedCachesClusters' bs-select ng-model='ui.generatedCachesClusters' ng-class='{placeholder: !(ui.generatedCachesClusters && ui.generatedCachesClusters.length > 0)}' data-container='.modal-domain-import' data-multiple='1' placeholder='Choose clusters for generated caches' bs-options='item.value as item.label for item in clusters')
+                        .col-sm-11
+                            .col-sm-6(style='padding-right: 5px')
+                                button.select-toggle.form-control(bs-select ng-model='importCommon.action' data-container='.modal-domain-import' bs-options='item.value as item.label for item in importActions')
+                            .col-sm-6(style='padding-left: 5px; padding-right: 5px')
+                                button.select-toggle.form-control(bs-select ng-model='importCommon.cacheOrTemplate' data-container='.modal-domain-import' bs-options='item.value as item.label for item in importCommon.cachesOrTemplates')
+                        .col-sm-1(style='padding-left: 5px')
+                            button.btn.btn-primary(ng-click='applyDefaults()') Apply
+                .import-domain-model-wizard-page(ng-show='importDomain.action == "options"')
+                    form.form-horizontal(name='optionsForm' novalidate)
+                        .settings-row
+                            .col-xs-3.col-sm-2.col-md-2.required
+                                label.required Package:
+                            .col-xs-9.col-sm-10.col-md-10
+                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Package that will be used for POJOs generation')
+                                .input-tip
+                                    ignite-form-field-input-text(
+                                        data-id='domainPackageName'
+                                        data-name='domainPackageName'
+                                        data-ng-model='ui.packageName'
+                                        data-ignite-label-name='Package'
+                                        data-ng-required='true'
+                                        data-placeholder='Enter package name'
+                                        data-java-keywords='true'
+                                        data-java-package-name='package-only'
+                                        ng-model-options='{allowInvalid: true}'
+                                    )
+                                        +error-feedback('optionsForm.$error.javaPackageName', 'javaPackageName', 'Package name is invalid')
+                                        +error-feedback('optionsForm.$error.javaKeywords', 'javaKeywords', 'Package name could not contains reserved java keyword')
+                        .settings-row
+                            .checkbox
+                                label
+                                    input(id='domainBuiltinKeys' type='checkbox' ng-model='ui.builtinKeys')
+                                    | Use Java built-in types for keys
+                                    i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Use Java built-in types like "Integer", "Long", "String" instead of POJO generation in case when table primary key contains only one field')
+                        .settings-row
+                            .checkbox
+                                label
+                                    input(id='domainUsePrimitives' type='checkbox' ng-model='ui.usePrimitives')
+                                    | Use primitive types for NOT NULL table columns
+                                    i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Use primitive types like "int", "long", "double" for POJOs fields generation in case of NOT NULL columns')
+                        .settings-row
+                            .checkbox
+                                label
+                                    input(id='domainGenerateAliases' type='checkbox' ng-model='ui.generateAliases')
+                                    | Generate aliases for query fields
+                                    i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Generate aliases for query fields with names from database fields')
+                        .settings-row
+                            .col-xs-3.col-sm-2.col-md-2.required
+                                label Clusters:
+                            .col-xs-9.col-sm-10.col-md-10
+                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Choose clusters that will be associated with generated caches')
+                                .input-tip
+                                    button.select-toggle.form-control(id='generatedCachesClusters' bs-select ng-model='ui.generatedCachesClusters' ng-class='{placeholder: !(ui.generatedCachesClusters && ui.generatedCachesClusters.length > 0)}' data-container='.modal-domain-import' data-multiple='1' placeholder='Choose clusters for generated caches' bs-options='item.value as item.label for item in clusters')
             .modal-footer
                 label(ng-hide='importDomain.action == "drivers" || (importDomain.action == "connect" && importDomain.demo)').labelField {{importDomain.info}}
                 a.btn.btn-primary(ng-hide='importDomain.action == "drivers" || importDomain.action == "connect"' ng-click='importDomainPrev()' bs-tooltip='' data-title='{{prevTooltipText()}}' data-placement='bottom') Prev

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/views/settings/profile.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/views/settings/profile.jade b/modules/web-console/src/main/js/views/settings/profile.jade
index 355d232..53991b3 100644
--- a/modules/web-console/src/main/js/views/settings/profile.jade
+++ b/modules/web-console/src/main/js/views/settings/profile.jade
@@ -48,29 +48,29 @@ mixin lbl(txt)
                     .details-row
                         .advanced-options
                             i.fa(
-                            ng-click='expandedToken = !expandedToken'
+                            ng-click='toggleToken()'
                             ng-class='expandedToken ? "fa-chevron-circle-down" : "fa-chevron-circle-right"')
-                            a(ng-click='expandedToken = !expandedToken') {{expandedToken ? 'Cancel security token changing...' : 'Show security token...'}}
+                            a(ng-click='toggleToken()') {{expandedToken ? 'Cancel security token changing...' : 'Show security token...'}}
                         div(ng-if='expandedToken')
                             +lbl('Security token:')
-                            label(ng-init='user.token = $root.user.token') {{user.token || 'No security token. Regenerate please.'}}
+                            label {{user.token || 'No security token. Regenerate please.'}}
                             i.tipLabel.fa.fa-refresh(ng-click='generateToken()' bs-tooltip='' data-title='Generate random security token')
                             i.tipLabel.fa.fa-clipboard(ng-click-copy='{{user.token}}' bs-tooltip='' data-title='Copy security token to clipboard')
                             i.tipLabel.fa.fa-question-circle(ng-if=lines bs-tooltip='' data-title='The security token is used for authorization of web agent')
                     .details-row
                         .advanced-options
                             i.fa(
-                            ng-click='expandedPassword = !expandedPassword'
+                            ng-click='togglePassword()'
                             ng-class='expandedPassword ? "fa-chevron-circle-down" : "fa-chevron-circle-right"')
-                            a(ng-click='expandedPassword = !expandedPassword') {{expandedPassword ? 'Cancel password changing...' : 'Change password...'}}
+                            a(ng-click='togglePassword()') {{expandedPassword ? 'Cancel password changing...' : 'Change password...'}}
                         div(ng-if='expandedPassword')
                             .details-row
                                 +lbl('New password:')
                                 .col-xs-5.col-sm-4
-                                    input.form-control(ng-init='user.password=null' type='password' ng-model='user.password' placeholder='New password')
+                                    input.form-control(type='password' ng-model='user.password' placeholder='New password')
                             .details-row
                                 +lbl('Confirm:')
                                 .col-xs-5.col-sm-4
-                                    input.form-control(ng-init='user.confirm=null' type='password' ng-model='user.confirm' match='user.password' placeholder='Confirm new password')
+                                    input.form-control(type='password' ng-model='user.confirm' match='user.password' placeholder='Confirm new password')
                 .col-xs-12.col-sm-12.details-row
                     a.btn.btn-primary(ng-disabled='!profileCouldBeSaved()' ng-click='profileCouldBeSaved() && saveUser()' bs-tooltip='' data-title='{{saveBtnTipText()}}' data-placement='bottom' data-trigger='hover') Save

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/views/signin.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/views/signin.jade b/modules/web-console/src/main/js/views/signin.jade
index 7c25a5a..73a07e7 100644
--- a/modules/web-console/src/main/js/views/signin.jade
+++ b/modules/web-console/src/main/js/views/signin.jade
@@ -48,11 +48,15 @@ header#header.header
                             .settings-row(ng-show='action == "signup"')
                                 +lblRequired('Last Name:')
                                 .col-xs-9.col-md-8
-                                    input#last_name.form-control(enter-focus-next='email' type='text' ng-model='ui.lastName' placeholder='Input last name' ng-required='action=="signup"')
-                            .settings-row(ng-show='action != "signup"')
+                                    input#last_name.form-control(enter-focus-next='signup_email' type='text' ng-model='ui.lastName' placeholder='Input last name' ng-required='action=="signup"')
+                            .settings-row(ng-show='action == "password/forgot"')
                                 +lblRequired('Email:')
                                 .col-xs-9.col-md-8
-                                    input#signin_email.form-control(enter-focus-next='company' type='email' ng-model='ui.email' placeholder='Input email' required)
+                                    input#forgot_email.form-control(on-enter='form.$valid && forgotPassword(ui)' type='email' ng-model='ui.email' placeholder='Input email' required)
+                            .settings-row(ng-show='action == "signin"')
+                                +lblRequired('Email:')
+                                .col-xs-9.col-md-8
+                                    input#signin_email.form-control(enter-focus-next='user_password' type='email' ng-model='ui.email' placeholder='Input email' required)
                             .settings-row(ng-show='action == "signup"')
                                 +lblRequired('Email:')
                                 .col-xs-9.col-md-8
@@ -80,17 +84,17 @@ header#header.header
                                         | I agree to the #[a(ui-sref='{{::terms.termsState}}' target='_blank') terms and conditions]
                         .col-xs-12.col-md-11
                             .login-footer(ng-show='action == "signup"')
-                                a.labelField(ng-click='action = "password/forgot"' on-click-focus='email') Forgot password?
-                                a.labelLogin(ng-click='action = "signin"' on-click-focus='email') Sign In
+                                a.labelField(ng-click='action = "password/forgot"' on-click-focus='signin_email') Forgot password?
+                                a.labelLogin(ng-click='action = "signin"' on-click-focus='signin_email') Sign In
                                 button#signup.btn.btn-primary(ng-click='auth(action, ui)' ng-disabled='form.$invalid') Sign Up
                         .col-xs-12.col-md-11
                             .login-footer(ng-show='action == "password/forgot"')
-                                a.labelField(ng-click='action = "signin"' on-click-focus='email') Sign In
-                                button#forgot.btn.btn-primary(ng-click='auth(action, ui)' ng-disabled='form.$invalid') Send it to me
+                                a.labelField(ng-click='action = "signin"' on-click-focus='signin_email') Sign In
+                                button#forgot.btn.btn-primary(ng-click='forgotPassword(ui)' ng-disabled='form.$invalid') Send it to me
                         .col-xs-12.col-md-11
                             .login-footer(ng-show='action == "signin"')
-                                a.labelField(ng-click='action = "password/forgot"' on-click-focus='email') Forgot password?
-                                a.labelLogin(ng-click='action = "signup"' on-click-focus='user_name') Sign Up
+                                a.labelField(ng-click='action = "password/forgot"' on-click-focus='signin_email') Forgot password?
+                                a.labelLogin(ng-click='action = "signup"' on-click-focus='first_name') Sign Up
                                 button#login.btn.btn-primary(ng-click='auth(action, ui)' ng-disabled='form.$invalid') Sign In
 
                     .col-xs-12.col-md-11.home-panel
@@ -144,10 +148,10 @@ header#header.header
                                     h3 Query chart
                                     p View data in tabular form and as charts
                         // Controls
-                        a.left.carousel-control(href='#carousel', role='button', data-slide='prev')
+                        a.left.carousel-control(href='#carousel', ng-click='$event.preventDefault()', role='button', data-slide='prev')
                             span.fa.fa-chevron-left(aria-hidden='true')
                             span.sr-only Previous
-                        a.right.carousel-control(href='#carousel', role='button', data-slide='next')
+                        a.right.carousel-control(href='#carousel', ng-click='$event.preventDefault()', role='button', data-slide='next')
                             span.fa.fa-chevron-right(aria-hidden='true')
                             span.sr-only Next
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/views/sql/cache-metadata.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/views/sql/cache-metadata.jade b/modules/web-console/src/main/js/views/sql/cache-metadata.jade
index 40b7a6b..450c178 100644
--- a/modules/web-console/src/main/js/views/sql/cache-metadata.jade
+++ b/modules/web-console/src/main/js/views/sql/cache-metadata.jade
@@ -24,7 +24,7 @@
             span(ng-switch='' on='node.type')
                 span(ng-switch-when='type' ng-dblclick='dblclickMetadata(paragraph, node)')
                     i.fa.fa-table
-                    label.clickable(ng-bind-html='node.displayMame')
+                    label.clickable(ng-bind='node.displayName')
                 span(ng-switch-when='plain')
                     label {{node.name}}
                 span(ng-switch-when='field' ng-dblclick='dblclickMetadata(paragraph, node)')

http://git-wip-us.apache.org/repos/asf/ignite/blob/541e17d0/modules/web-console/src/main/js/views/sql/sql.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/src/main/js/views/sql/sql.jade b/modules/web-console/src/main/js/views/sql/sql.jade
index 5eade69..be6d85e 100644
--- a/modules/web-console/src/main/js/views/sql/sql.jade
+++ b/modules/web-console/src/main/js/views/sql/sql.jade
@@ -42,24 +42,105 @@ mixin chart-settings(mdl)
         .col-xs-4
             +result-toolbar
 
+mixin notebook-rename
+    .docs-header.notebook-header
+        h1.col-sm-6(ng-hide='notebook.edit')
+            label(style='max-width: calc(100% - 60px)') {{notebook.name}}
+            .btn-group(ng-if='!demo')
+                +btn-toolbar('fa-pencil', 'notebook.edit = true;notebook.editName = notebook.name', 'Rename notebook')
+                +btn-toolbar('fa-trash', 'removeNotebook()', 'Remove notebook')
+        h1.col-sm-6(ng-show='notebook.edit')
+            i.btn.fa.fa-floppy-o(ng-show='notebook.editName' ng-click='renameNotebook(notebook.editName)' bs-tooltip data-title='Save notebook name' data-trigger='hover')
+            .input-tip
+                input.form-control(ng-model='notebook.editName' required on-enter='renameNotebook(notebook.editName)' on-escape='notebook.edit = false;')
+        h1.pull-right
+            a.dropdown-toggle(data-toggle='dropdown' bs-dropdown='scrollParagraphs' data-placement='bottom-right') Scroll to query
+                span.caret
+            .btn-group(style='margin-top: 2px')
+                +btn-toolbar('fa-plus', 'addParagraph()', 'Add new query')
+
+mixin notebook-error
+    h2 Failed to load notebook
+    label.col-sm-12 Notebook not accessible any more. Go back to configuration or open to another notebook.
+    button.h3.btn.btn-primary(ui-sref='base.configuration.clusters') Back to configuration
+
+mixin paragraph-rename
+    .col-sm-6(ng-hide='paragraph.edit')
+        i.tipLabel.fa(ng-class='paragraphExpanded(paragraph) ? "fa-chevron-circle-down" : "fa-chevron-circle-right"')
+        label {{paragraph.name}}
+
+        .btn-group(ng-hide='notebook.paragraphs.length > 1')
+            +btn-toolbar('fa-pencil', 'paragraph.edit = true; paragraph.editName = paragraph.name; $event.stopPropagation();', 'Rename query', 'paragraph-name-{{paragraph.id}}')
+
+        .btn-group(ng-show='notebook.paragraphs.length > 1' ng-click='$event.stopPropagation();')
+            +btn-toolbar('fa-pencil', 'paragraph.edit = true; paragraph.editName = paragraph.name;', 'Rename query', 'paragraph-name-{{paragraph.id}}')
+            +btn-toolbar('fa-remove', 'removeParagraph(paragraph)', 'Remove query')
+
+    .col-sm-6(ng-show='paragraph.edit')
+        i.tipLabel.fa(style='float: left;' ng-class='paragraphExpanded(paragraph) ? "fa-chevron-circle-down" : "fa-chevron-circle-right"')
+        i.tipLabel.fa.fa-floppy-o(style='float: right;' ng-show='paragraph.editName' ng-click='renameParagraph(paragraph, paragraph.editName); $event.stopPropagation();' bs-tooltip data-title='Save query name' data-trigger='hover')
+        .input-tip
+            input.form-control(id='paragraph-name-{{paragraph.id}}' ng-model='paragraph.editName' required ng-click='$event.stopPropagation();' on-enter='renameParagraph(paragraph, paragraph.editName)' on-escape='paragraph.edit = false')
+
+mixin query-controls
+    .sql-controls
+        a.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, true)' ng-click='actionAvailable(paragraph, true) && execute(paragraph)' data-placement='bottom' bs-tooltip data-title='{{actionTooltip(paragraph, "execute", true)}}') Execute
+        a.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, true)' ng-click='actionAvailable(paragraph, true) && explain(paragraph)' data-placement='bottom' bs-tooltip data-title='{{actionTooltip(paragraph, "explain", true)}}') Explain
+        a.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, false)' ng-click='actionAvailable(paragraph, false) && scan(paragraph)' data-placement='bottom' bs-tooltip data-title='{{actionTooltip(paragraph, "execute scan", false)}}') Scan
+        .pull-right
+            labelHide System columns:
+            a.btn.btn-default.fa.fa-bars.tipLabel(ng-class='{"btn-info": paragraph.systemColumns}' ng-click='toggleSystemColumns(paragraph)' ng-disabled='paragraph.disabledSystemColumns' bs-tooltip data-title='Show "_KEY", "_VAL" columns')
+            label.tipLabel Refresh rate:
+            button.btn.btn-default.fa.fa-clock-o.tipLabel(title='Click to show refresh rate dialog' ng-class='{"btn-info": paragraph.rate && paragraph.rate.installed}' bs-popover data-template-url='/sql/paragraph-rate.html' data-placement='left' data-auto-close='1' data-trigger='click') {{rateAsString(paragraph)}}
+            label.tipLabel Page size:
+            button.select-toggle.fieldButton.btn.btn-default(ng-model='paragraph.pageSize' bs-options='item for item in pageSizes' bs-select bs-tooltip data-placement='bottom-right' data-title='Max number of rows to show in query result as one page')
+
+mixin table-result
+    .sql-table-total.row
+        .col-xs-4
+            label(style='margin-right: 10px;') Page: #[b {{paragraph.page}}]
+            label Results so far: #[b {{paragraph.rows.length + paragraph.total}}]
+        .col-xs-4
+            +result-toolbar
+        .col-xs-4
+            .btn-group.pull-right(ng-disabled='paragraph.loading')
+                button.btn.btn-primary.fieldButton(ng-click='exportCsv(paragraph)' bs-tooltip data-title='{{actionTooltip(paragraph, "export", false)}}') Export
+                button.btn.btn-primary(id='export-item-dropdown' data-toggle='dropdown' data-container='body' bs-dropdown='exportDropdown' data-placement='bottom-right')
+                    span.caret
+    .grid(ui-grid='paragraph.gridOptions' ui-grid-resize-columns ui-grid-exporter)
+
+mixin chart-result
+    div(ng-show='paragraph.queryExecuted()')
+        +chart-settings
+        div(ng-show='paragraph.chartColumns.length > 0 && !paragraph.chartColumnsConfigured()')
+            .sql-empty-result Cannot display chart. Please configure axis using #[b Chart settings]
+        div(ng-show='paragraph.chartColumns.length == 0')
+            .sql-empty-result Cannot display chart. Result set must contain Java build-in type columns. Please change query and execute it again.
+        div(ng-show='paragraph.chartColumnsConfigured()')
+            div(ng-show='paragraph.timeLineSupported() || !paragraph.chartTimeLineEnabled()')
+                div(ng-repeat='chart in paragraph.charts')
+                    nvd3(options='chart.options' data='chart.data' api='chart.api')
+            .sql-empty-result(ng-show='!paragraph.timeLineSupported() && paragraph.chartTimeLineEnabled()') Pie chart does not support 'TIME_LINE' column for X-axis. Please use another column for X-axis or switch to another chart.
+    .sql-empty-result(ng-hide='paragraph.queryExecuted()')
+        .row
+            .col-xs-4.col-xs-offset-4
+                +result-toolbar
+        label.margin-top-dflt Charts do not support #[b Explain] and #[b Scan] query
+
+mixin footer-controls
+    hr(style='margin-top: 0; margin-bottom: 5px')
+    a(style='float: left; margin-left: 10px; margin-bottom: 5px' ng-click='showResultQuery(paragraph)') Show query
+
+    -var nextVisibleCondition = 'paragraph.queryId && (paragraph.table() || paragraph.chart() && (paragraph.timeLineSupported() || !paragraph.chartTimeLineEnabled()))'
+
+    .sql-next(ng-show=nextVisibleCondition)
+        i.fa.fa-chevron-circle-right(ng-class='{disabled: paragraph.loading}' ng-click='!paragraph.loading && nextPage(paragraph)')
+        a(ng-class='{disabled: paragraph.loading}' ng-click='!paragraph.loading && nextPage(paragraph)') Next
+
 .row(ng-controller='sqlController')
     .docs-content
         .row(ng-if='notebook' bs-affix style='margin-bottom: 20px;')
-            .docs-header.notebook-header
-                h1.col-sm-6(ng-hide='notebook.edit')
-                    label(style='max-width: calc(100% - 60px)') {{notebook.name}}
-                    .btn-group(ng-if='!demo')
-                        +btn-toolbar('fa-pencil', 'notebook.edit = true;notebook.editName = notebook.name', 'Rename notebook')
-                        +btn-toolbar('fa-trash', 'removeNotebook()', 'Remove notebook')
-                h1.col-sm-6(ng-show='notebook.edit')
-                    i.btn.fa.fa-floppy-o(ng-show='notebook.editName' ng-click='renameNotebook(notebook.editName)' bs-tooltip data-title='Save notebook name' data-trigger='hover')
-                    .input-tip
-                        input.form-control(ng-model='notebook.editName' required on-enter='renameNotebook(notebook.editName)' on-escape='notebook.edit = false;')
-                h1.pull-right
-                    a.dropdown-toggle(data-toggle='dropdown' bs-dropdown='scrollParagraphs' data-placement='bottom-right') Scroll to query
-                        span.caret
-                    .btn-group(style='margin-top: 2px')
-                        +btn-toolbar('fa-plus', 'addParagraph()', 'Add new query')
+            +notebook-rename
 
         ignite-information(data-title='With SQL notebook you can' style='margin-top: 0; margin-bottom: 30px')
             ul
@@ -69,31 +150,15 @@ mixin chart-settings(mdl)
                 li View data in tabular form and as charts
 
         div(ng-if='notebookLoadFailed' style='text-align: center')
-            h2 Failed to load notebook
-            label.col-sm-12 Notebook not accessible any more. Go back to configuration or open to another notebook.
-            button.h3.btn.btn-primary(ui-sref='base.configuration.clusters') Back to configuration
+            +notebook-error
+
         div(ng-if='notebook' ignite-loading='sqlLoading' ignite-loading-text='{{ loadingText }}' ignite-loading-position='top')
             .docs-body.paragraphs
                 .panel-group(bs-collapse ng-model='notebook.expandedParagraphs' data-allow-multiple='true' data-start-collapsed='false')
                     .panel.panel-default(ng-repeat='paragraph in notebook.paragraphs')
                         .panel-heading(id='{{paragraph.id}}' bs-collapse-toggle)
                             .row
-                                .col-sm-6(ng-hide='paragraph.edit')
-                                    i.tipLabel.fa(ng-class='paragraphExpanded(paragraph) ? "fa-chevron-circle-down" : "fa-chevron-circle-right"')
-                                    label {{paragraph.name}}
-
-                                    .btn-group(ng-hide='notebook.paragraphs.length > 1')
-                                        +btn-toolbar('fa-pencil', 'paragraph.edit = true; paragraph.editName = paragraph.name; $event.stopPropagation();', 'Rename query', 'paragraph-name-{{paragraph.id}}')
-
-                                    .btn-group(ng-show='notebook.paragraphs.length > 1' ng-click='$event.stopPropagation();')
-                                        +btn-toolbar('fa-pencil', 'paragraph.edit = true; paragraph.editName = paragraph.name;', 'Rename query', 'paragraph-name-{{paragraph.id}}')
-                                        +btn-toolbar('fa-remove', 'removeParagraph(paragraph)', 'Remove query')
-
-                                .col-sm-6(ng-show='paragraph.edit')
-                                    i.tipLabel.fa(style='float: left;' ng-class='paragraphExpanded(paragraph) ? "fa-chevron-circle-down" : "fa-chevron-circle-right"')
-                                    i.tipLabel.fa.fa-floppy-o(style='float: right;' ng-show='paragraph.editName' ng-click='renameParagraph(paragraph, paragraph.editName); $event.stopPropagation();' bs-tooltip data-title='Save query name' data-trigger='hover')
-                                    .input-tip
-                                        input.form-control(id='paragraph-name-{{paragraph.id}}' ng-model='paragraph.editName' required ng-click='$event.stopPropagation();' on-enter='renameParagraph(paragraph, paragraph.editName)' on-escape='paragraph.edit = false')
+                                +paragraph-rename
                         .panel-collapse(role='tabpanel' bs-collapse-target)
                             .col-sm-12
                                 .col-xs-8.col-sm-9(style='border-right: 1px solid #eee')
@@ -105,13 +170,13 @@ mixin chart-settings(mdl)
                                         lable.labelField.labelFormField Caches:
                                         i.fa.fa-database.tipField(title='Click to show cache types metadata dialog' bs-popover data-template-url='/sql/cache-metadata.html', data-placement='bottom', data-trigger='click')
                                         .input-tip
-                                            input.form-control(type='text' st-search='name' placeholder='Filter caches...')
+                                            input.form-control(type='text' st-search='label' placeholder='Filter caches...')
                                         table.links
-                                            tbody.scrollable-y(style='max-height: 15em;display:block;' ng-model='paragraph.cacheName' bs-radio-group)
+                                            tbody.scrollable-y(style='max-height: 15em; display: block;')
                                                 tr(ng-repeat='cache in displayedCaches track by cache.name')
                                                     td(style='width: 100%')
-                                                        input.labelField(type='radio' value='{{cache.name}}')
-                                                        label(ng-bind-html='maskCacheName(cache.name)')
+                                                        input.labelField(id='cache{{$index}}' type='radio' value='{{cache.name}}' ng-model='paragraph.cacheName')
+                                                        label(for='cache{{$index}}' ng-bind='cache.label')
                                     .empty-caches(ng-show='displayedCaches.length == 0 && caches.length != 0')
                                         label Wrong caches filter
                                     .empty-caches(ng-show='caches.length == 0')
@@ -119,62 +184,18 @@ mixin chart-settings(mdl)
                             .col-sm-12
                                 hr(style='margin: 0')
                             .col-sm-12
-                                .sql-controls
-                                    a.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, true)' ng-click='actionAvailable(paragraph, true) && execute(paragraph)' data-placement='bottom' bs-tooltip data-title='{{actionTooltip(paragraph, "execute", true)}}') Execute
-                                    a.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, true)' ng-click='actionAvailable(paragraph, true) && explain(paragraph)' data-placement='bottom' bs-tooltip data-title='{{actionTooltip(paragraph, "explain", true)}}') Explain
-                                    a.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, false)' ng-click='actionAvailable(paragraph, false) && scan(paragraph)' data-placement='bottom' bs-tooltip data-title='{{actionTooltip(paragraph, "execute scan", false)}}') Scan
-                                    .pull-right
-                                        labelHide System columns:
-                                        a.btn.btn-default.fa.fa-bars.tipLabel(ng-class='{"btn-info": paragraph.systemColumns}' ng-click='toggleSystemColumns(paragraph)' ng-disabled='paragraph.disabledSystemColumns' bs-tooltip data-title='Show "_KEY", "_VAL" columns')
-                                        label.tipLabel Refresh rate:
-                                        button.btn.btn-default.fa.fa-clock-o.tipLabel(title='Click to show refresh rate dialog' ng-class='{"btn-info": paragraph.rate && paragraph.rate.installed}' bs-popover data-template-url='/sql/paragraph-rate.html' data-placement='left' data-auto-close='1' data-trigger='click') {{rateAsString(paragraph)}}
-                                        label.tipLabel Page size:
-                                        button.select-toggle.fieldButton.btn.btn-default(ng-model='paragraph.pageSize' bs-options='item for item in pageSizes' bs-select bs-tooltip data-title='Max number of rows to show in query result as one page')
+                                +query-controls
                             .col-sm-12.sql-error-result(ng-show='paragraph.errMsg') Error: {{paragraph.errMsg}}
-                            .col-sm-12(ng-show='!paragraph.errMsg && paragraph.result != "none"')
+                            .col-sm-12(ng-show='!paragraph.errMsg && paragraph.queryArgs')
                                 hr(style='margin-top: 0; margin-bottom: 10px')
+
                                 .sql-empty-result(ng-show='!paragraph.nonEmpty()') Result set is empty
+
                                 div(ng-show='paragraph.table() && paragraph.nonEmpty()')
-                                    .sql-table-total.row
-                                        .col-xs-4
-                                            label Page #&nbsp;
-                                            b {{paragraph.page}}&nbsp;&nbsp;&nbsp;
-                                            label Results so far:&nbsp;
-                                            b {{paragraph.rows.length + paragraph.total}}
-                                        .col-xs-4
-                                            +result-toolbar
-                                        .col-xs-4
-                                            .btn-group.pull-right(ng-disabled='paragraph.loading')
-                                                button.btn.btn-primary.fieldButton(ng-click='exportCsv(paragraph)' bs-tooltip data-title='{{actionTooltip(paragraph, "export", false)}}') Export
-                                                button.btn.btn-primary(id='export-item-dropdown' data-toggle='dropdown' data-container='body' bs-dropdown='exportDropdown' data-placement='bottom-right')
-                                                    span.caret
-                                    .grid(ui-grid='paragraph.gridOptions' ui-grid-auto-resize ui-grid-exporter ng-style='{ height: paragraph.gridOptions.height }')
+                                    +table-result
+
                                 div(ng-show='paragraph.chart() && paragraph.nonEmpty()')
-                                    div(ng-show='paragraph.queryExecuted()')
-                                        +chart-settings
-                                        div(ng-show='paragraph.chartColumns.length > 0 && !paragraph.chartColumnsConfigured()')
-                                            .sql-empty-result Cannot display chart. Please configure axis using #[b Chart settings]
-                                        div(ng-show='paragraph.chartColumns.length == 0')
-                                            .sql-empty-result Cannot display chart. Result set must contain Java build-in type columns. Please change query and execute it again.
-                                        div(ng-show='paragraph.chartColumnsConfigured()')
-                                            div(ng-show='paragraph.timeLineSupported() || !paragraph.chartTimeLineEnabled()')
-                                                div(ng-repeat='chart in paragraph.charts')
-                                                    nvd3(options='chart.options' data='chart.data' api='chart.api')
-                                            .sql-empty-result(ng-show='!paragraph.timeLineSupported() && paragraph.chartTimeLineEnabled()') Pie chart does not support 'TIME_LINE' column for X-axis. Please use another column for X-axis or switch to another chart.
-                                    .sql-empty-result(ng-hide='paragraph.queryExecuted()')
-                                        .row
-                                            .col-xs-4.col-xs-offset-4
-                                                +result-toolbar
-                                        label.margin-top-dflt Charts do not support&nbsp
-                                            b Explain
-                                            | &nbsp;and&nbsp;
-                                            b Scan
-                                            | &nbsp;query
-                                div(ng-show='paragraph.queryArgs && !paragraph.refreshExecuting()')
-                                    -var nextVisibleCondition = 'paragraph.queryId && (paragraph.table() || paragraph.chart() && paragraph.queryExecute() && (paragraph.timeLineSupported() || !paragraph.chartTimeLineEnabled()))'
-
-                                    hr(style='margin-top: 0; margin-bottom: 5px')
-                                    a(style='float: left; margin-left: 10px; margin-bottom: 5px' ng-click='showResultQuery(paragraph)') Show query
-                                    .sql-next(ng-show=nextVisibleCondition )
-                                        i.fa.fa-chevron-circle-right(ng-class='{disabled: paragraph.loading}' ng-click='!paragraph.loading && nextPage(paragraph)')
-                                        a(ng-class='{disabled: paragraph.loading}' ng-click='!paragraph.loading && nextPage(paragraph)') Next
+                                    +chart-result
+
+                                div(ng-show='!paragraph.refreshExecuting()')
+                                    +footer-controls


[15/50] [abbrv] ignite git commit: IGNITE-3230 External addresses are not registered in IP finder

Posted by sb...@apache.org.
IGNITE-3230 External addresses are not registered in IP finder


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/5177c33e
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/5177c33e
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/5177c33e

Branch: refs/heads/ignite-1232
Commit: 5177c33ec66d98ae379f2908dc056f58ee3cbb40
Parents: 3ca0bc8
Author: Anton Vinogradov <av...@apache.org>
Authored: Wed Jun 22 12:13:30 2016 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Wed Jun 22 12:56:16 2016 +0300

----------------------------------------------------------------------
 .../ignite/internal/util/IgniteUtils.java       | 45 +++++++--
 .../ignite/spi/discovery/tcp/ServerImpl.java    |  5 +-
 .../spi/discovery/tcp/TcpDiscoveryImpl.java     |  3 +-
 .../cluster/GridAddressResolverSelfTest.java    | 97 ++++++++++++++++++++
 .../testsuites/IgniteKernalSelfTestSuite.java   |  2 +
 5 files changed, 140 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5177c33e/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
index 2a83ad4..fee4f378 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@ -8686,16 +8686,10 @@ public abstract class IgniteUtils {
             InetSocketAddress sockAddr = new InetSocketAddress(addr, port);
 
             if (!sockAddr.isUnresolved()) {
-                try {
-                    Collection<InetSocketAddress> extAddrs0 = addrRslvr.getExternalAddresses(sockAddr);
+                Collection<InetSocketAddress> extAddrs0 = resolveAddress(addrRslvr, sockAddr);
 
-                    if (extAddrs0 != null)
-                        extAddrs.addAll(extAddrs0);
-                }
-                catch (IgniteCheckedException e) {
-                    throw new IgniteSpiException("Failed to get mapped external addresses " +
-                        "[addrRslvr=" + addrRslvr + ", addr=" + addr + ']', e);
-                }
+                if (extAddrs0 != null)
+                    extAddrs.addAll(extAddrs0);
             }
         }
 
@@ -8703,6 +8697,39 @@ public abstract class IgniteUtils {
     }
 
     /**
+     * @param addrRslvr Address resolver.
+     * @param sockAddr Addresses.
+     * @return Resolved addresses.
+     */
+    public static Collection<InetSocketAddress> resolveAddresses(AddressResolver addrRslvr,
+        Collection<InetSocketAddress> sockAddr) {
+        if (addrRslvr == null)
+            return sockAddr;
+
+        Collection<InetSocketAddress> resolved = new HashSet<>();
+
+        for (InetSocketAddress address :sockAddr)
+            resolved.addAll(resolveAddress(addrRslvr, address));
+
+        return resolved;
+    }
+
+    /**
+     * @param addrRslvr Address resolver.
+     * @param sockAddr Addresses.
+     * @return Resolved addresses.
+     */
+    private static Collection<InetSocketAddress> resolveAddress(AddressResolver addrRslvr, InetSocketAddress sockAddr) {
+        try {
+            return addrRslvr.getExternalAddresses(sockAddr);
+        }
+        catch (IgniteCheckedException e) {
+            throw new IgniteSpiException("Failed to get mapped external addresses " +
+                "[addrRslvr=" + addrRslvr + ", addr=" + sockAddr + ']', e);
+        }
+    }
+
+    /**
      * Returns string representation of node addresses.
      *
      * @param node Grid node.

http://git-wip-us.apache.org/repos/asf/ignite/blob/5177c33e/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
index 37a1539..38ed671 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
@@ -132,10 +132,10 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryStatusCheckMessa
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
 
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_BINARY_MARSHALLER_USE_STRING_SERIALIZATION_VER_2;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_DISCOVERY_HISTORY_SIZE;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_SERVICES_COMPATIBILITY_MODE;
-import static org.apache.ignite.IgniteSystemProperties.IGNITE_BINARY_MARSHALLER_USE_STRING_SERIALIZATION_VER_2;
 import static org.apache.ignite.IgniteSystemProperties.getInteger;
 import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
 import static org.apache.ignite.events.EventType.EVT_NODE_JOINED;
@@ -4100,7 +4100,8 @@ class ServerImpl extends TcpDiscoveryImpl {
                 if (msg.verified() || !ring.hasRemoteNodes() || msg.senderNodeId() != null) {
                     if (spi.ipFinder.isShared() && !ring.hasRemoteNodes()) {
                         try {
-                            spi.ipFinder.unregisterAddresses(locNode.socketAddresses());
+                            spi.ipFinder.unregisterAddresses(
+                                U.resolveAddresses(spi.getAddressResolver(), locNode.socketAddresses()));
                         }
                         catch (IgniteSpiException e) {
                             U.error(log, "Failed to unregister local node address from IP finder.", e);

http://git-wip-us.apache.org/repos/asf/ignite/blob/5177c33e/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java
index 41086d1..30b83e5 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java
@@ -265,7 +265,8 @@ abstract class TcpDiscoveryImpl {
 
         while (true) {
             try {
-                spi.ipFinder.initializeLocalAddresses(locNode.socketAddresses());
+                spi.ipFinder.initializeLocalAddresses(
+                    U.resolveAddresses(spi.getAddressResolver(), locNode.socketAddresses()));
 
                 // Success.
                 break;

http://git-wip-us.apache.org/repos/asf/ignite/blob/5177c33e/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/GridAddressResolverSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/GridAddressResolverSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/GridAddressResolverSelfTest.java
new file mode 100644
index 0000000..d8fd767
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/GridAddressResolverSelfTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.cluster;
+
+import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.configuration.AddressResolver;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.lang.GridAbsPredicate;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.testframework.junits.common.GridCommonTest;
+
+/**
+ * Address Resolver test.
+ */
+@GridCommonTest(group = "Kernal Self")
+public class GridAddressResolverSelfTest extends GridCommonAbstractTest {
+    /** */
+    private final InetSocketAddress addr0 = new InetSocketAddress("test0.com", 5000);
+
+    /** */
+    private final InetSocketAddress addr1 = new InetSocketAddress("test1.com", 5000);
+
+    /** Ip finder. */
+    private static final TcpDiscoveryVmIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(final String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+        discoSpi.setIpFinder(IP_FINDER);
+        cfg.setDiscoverySpi(discoSpi);
+
+        cfg.setAddressResolver(new AddressResolver() {
+            @Override public Collection<InetSocketAddress> getExternalAddresses(
+                InetSocketAddress addr) throws IgniteCheckedException {
+                Set<InetSocketAddress> set = new HashSet<>();
+
+                set.add(addr);
+                set.add(gridName.contains("0") ? addr0 : addr1);
+
+                return set;
+            }
+        });
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        stopAllGrids();
+    }
+
+    /** */
+    public void test() throws Exception {
+        startGrid(0);
+
+        assertFalse(IP_FINDER.getRegisteredAddresses().contains(addr1));
+
+        startGrid(1);
+
+        assertTrue(IP_FINDER.getRegisteredAddresses().contains(addr0));
+        assertTrue(IP_FINDER.getRegisteredAddresses().contains(addr1));
+
+        stopGrid(0, true);
+
+        assertTrue(GridTestUtils.waitForCondition(new GridAbsPredicate() {
+            @Override public boolean apply() {
+                return !IP_FINDER.getRegisteredAddresses().contains(addr0);
+            }
+        }, 70000));
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5177c33e/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java
index 620c298..c9cb531 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteKernalSelfTestSuite.java
@@ -46,6 +46,7 @@ import org.apache.ignite.internal.managers.discovery.GridDiscoveryManagerSelfTes
 import org.apache.ignite.internal.managers.discovery.IgniteTopologyPrintFormatSelfTest;
 import org.apache.ignite.internal.managers.events.GridEventStorageManagerSelfTest;
 import org.apache.ignite.internal.managers.swapspace.GridSwapSpaceManagerSelfTest;
+import org.apache.ignite.internal.processors.cluster.GridAddressResolverSelfTest;
 import org.apache.ignite.internal.processors.cluster.GridUpdateNotifierSelfTest;
 import org.apache.ignite.internal.processors.port.GridPortProcessorSelfTest;
 import org.apache.ignite.internal.processors.service.GridServiceClientNodeTest;
@@ -121,6 +122,7 @@ public class IgniteKernalSelfTestSuite extends TestSuite {
         suite.addTestSuite(GridKernalConcurrentAccessStopSelfTest.class);
         suite.addTestSuite(IgniteConcurrentEntryProcessorAccessStopTest.class);
         suite.addTestSuite(GridUpdateNotifierSelfTest.class);
+        suite.addTestSuite(GridAddressResolverSelfTest.class);
         suite.addTestSuite(IgniteUpdateNotifierPerClusterSettingSelfTest.class);
         suite.addTestSuite(GridLocalEventListenerSelfTest.class);
         suite.addTestSuite(IgniteTopologyPrintFormatSelfTest.class);


[34/50] [abbrv] ignite git commit: Ignite Web Console beta2.

Posted by sb...@apache.org.
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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
 };
 
 // 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));
         });
 


[10/50] [abbrv] ignite git commit: IGNITE-3277 Fixed null key serialization.

Posted by sb...@apache.org.
IGNITE-3277 Fixed null key serialization.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/482015e9
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/482015e9
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/482015e9

Branch: refs/heads/ignite-1232
Commit: 482015e9924425c70901fdae36222110af6e6c16
Parents: 0c5db20
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Tue Jun 21 17:49:47 2016 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Tue Jun 21 17:49:47 2016 +0700

----------------------------------------------------------------------
 .../JettyRestProcessorAbstractSelfTest.java     | 33 ++++++++++++++++++++
 .../http/jetty/GridJettyObjectMapper.java       | 23 +++++++++++---
 2 files changed, 52 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/482015e9/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
index ad667ed..81bffcf 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
@@ -339,6 +339,39 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     /**
      * @throws Exception If failed.
      */
+    public void testNullMapKeyAndValue()  throws Exception {
+        Map<String, String> map1 = new HashMap<>();
+        map1.put(null, null);
+        map1.put("key", "value");
+
+        jcache().put("mapKey1", map1);
+
+        String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "key", "mapKey1"));
+
+        info("Get command result: " + ret);
+
+        JsonNode res = jsonResponse(ret);
+
+        assertEquals(F.asMap("", null, "key", "value"), JSON_MAPPER.treeToValue(res, HashMap.class));
+
+        Map<String, String> map2 = new HashMap<>();
+        map2.put(null, "value");
+        map2.put("key", null);
+
+        jcache().put("mapKey2", map2);
+
+        ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "key", "mapKey2"));
+
+        info("Get command result: " + ret);
+
+        res = jsonResponse(ret);
+
+        assertEquals(F.asMap("", "value", "key", null), JSON_MAPPER.treeToValue(res, HashMap.class));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testSimpleObject()  throws Exception {
         SimplePerson p = new SimplePerson(1, "Test", java.sql.Date.valueOf("1977-01-26"), 1000.55, 39, "CIO", 25);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/482015e9/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyObjectMapper.java
----------------------------------------------------------------------
diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyObjectMapper.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyObjectMapper.java
index f09b583..6289bdb 100644
--- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyObjectMapper.java
+++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyObjectMapper.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.rest.protocols.http.jetty;
 
 import com.fasterxml.jackson.core.JsonGenerator;
 import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.JsonSerializer;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -67,8 +68,16 @@ public class GridJettyObjectMapper extends ObjectMapper {
         registerModule(module);
     }
 
+    /** Custom {@code null} key serializer. */
+    private static final JsonSerializer<Object> NULL_KEY_SERIALIZER = new JsonSerializer<Object>() {
+        /** {@inheritDoc} */
+        @Override public void serialize(Object val, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            gen.writeFieldName("");
+        }
+    };
+
     /** Custom {@code null} value serializer. */
-    private static final JsonSerializer<Object> NULL_SERIALIZER = new JsonSerializer<Object>() {
+    private static final JsonSerializer<Object> NULL_VALUE_SERIALIZER = new JsonSerializer<Object>() {
         /** {@inheritDoc} */
         @Override public void serialize(Object val, JsonGenerator gen, SerializerProvider ser) throws IOException {
             gen.writeNull();
@@ -76,7 +85,7 @@ public class GridJettyObjectMapper extends ObjectMapper {
     };
 
     /** Custom {@code null} string serializer. */
-    private static final JsonSerializer<Object> NULL_STRING_SERIALIZER = new JsonSerializer<Object>() {
+    private static final JsonSerializer<Object> NULL_STRING_VALUE_SERIALIZER = new JsonSerializer<Object>() {
         /** {@inheritDoc} */
         @Override public void serialize(Object val, JsonGenerator gen, SerializerProvider ser) throws IOException {
             gen.writeString("");
@@ -111,11 +120,17 @@ public class GridJettyObjectMapper extends ObjectMapper {
         }
 
         /** {@inheritDoc} */
+        @Override public JsonSerializer<Object> findNullKeySerializer(JavaType serializationType,
+            BeanProperty prop) throws JsonMappingException {
+            return NULL_KEY_SERIALIZER;
+        }
+
+        /** {@inheritDoc} */
         @Override public JsonSerializer<Object> findNullValueSerializer(BeanProperty prop) throws JsonMappingException {
             if (prop.getType().getRawClass() == String.class)
-                return NULL_STRING_SERIALIZER;
+                return NULL_STRING_VALUE_SERIALIZER;
 
-            return NULL_SERIALIZER;
+            return NULL_VALUE_SERIALIZER;
         }
     }
 


[31/50] [abbrv] ignite git commit: .NET: Fix analysis warning (remove unused import)

Posted by sb...@apache.org.
.NET: Fix analysis warning (remove unused import)


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1986b775
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1986b775
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1986b775

Branch: refs/heads/ignite-1232
Commit: 1986b775326bab7792bf0d9ba72103a98b100665
Parents: e1c755c
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri Jun 24 19:04:31 2016 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Jun 24 19:04:31 2016 +0300

----------------------------------------------------------------------
 modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1986b775/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs
index 69a2f6a..6bdf1ab 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs
@@ -37,7 +37,6 @@
     using Apache.Ignite.Core.Impl;
     using Apache.Ignite.Core.Impl.Binary;
     using Apache.Ignite.Core.Impl.Common;
-    using Apache.Ignite.Core.Impl.Handle;
     using Apache.Ignite.Core.Lifecycle;
     using Apache.Ignite.Core.Transactions;
     using BinaryReader = Apache.Ignite.Core.Impl.Binary.BinaryReader;