You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/10/09 14:47:56 UTC

[01/50] [abbrv] ignite git commit: IGNITE-6535 Web Console: Set IGNITE_HOME for Web Agent. [Forced Update!]

Repository: ignite
Updated Branches:
  refs/heads/ignite-6305 ea1d4b0ac -> b7bcab44d (forced update)


IGNITE-6535 Web Console: Set IGNITE_HOME for Web Agent.


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

Branch: refs/heads/ignite-6305
Commit: 4cb0fc73f4129895e975c6a2381c5059e3f6e1ce
Parents: 0919d9f
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Sun Oct 1 18:47:08 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Oct 2 13:56:21 2017 +0700

----------------------------------------------------------------------
 .../web-agent/bin/ignite-web-agent.bat           | 19 +++++++++++++++++++
 .../web-agent/bin/ignite-web-agent.sh            |  5 +++++
 2 files changed, 24 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/4cb0fc73/modules/web-console/web-agent/bin/ignite-web-agent.bat
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/bin/ignite-web-agent.bat b/modules/web-console/web-agent/bin/ignite-web-agent.bat
index 1f1b52d..387447f 100644
--- a/modules/web-console/web-agent/bin/ignite-web-agent.bat
+++ b/modules/web-console/web-agent/bin/ignite-web-agent.bat
@@ -20,6 +20,25 @@ Setlocal EnableDelayedExpansion
 
 if "%OS%" == "Windows_NT"  setlocal
 
+:: Check IGNITE_HOME.
+pushd "%~dp0"
+set IGNITE_HOME=%CD%
+
+:checkIgniteHome2
+:: Strip double quotes from IGNITE_HOME
+set IGNITE_HOME=%IGNITE_HOME:"=%
+
+:: remove all trailing slashes from IGNITE_HOME.
+if %IGNITE_HOME:~-1,1% == \ goto removeTrailingSlash
+if %IGNITE_HOME:~-1,1% == / goto removeTrailingSlash
+goto checkIgniteHome3
+
+:removeTrailingSlash
+set IGNITE_HOME=%IGNITE_HOME:~0,-1%
+goto checkIgniteHome2
+
+:checkIgniteHome3
+
 :: Check JAVA_HOME.
 if defined JAVA_HOME  goto checkJdk
     echo %0, ERROR:

http://git-wip-us.apache.org/repos/asf/ignite/blob/4cb0fc73/modules/web-console/web-agent/bin/ignite-web-agent.sh
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/bin/ignite-web-agent.sh b/modules/web-console/web-agent/bin/ignite-web-agent.sh
index c2958fc..530bc7f 100644
--- a/modules/web-console/web-agent/bin/ignite-web-agent.sh
+++ b/modules/web-console/web-agent/bin/ignite-web-agent.sh
@@ -60,6 +60,11 @@ fi
 
 SOURCE="${BASH_SOURCE[0]}"
 
+#
+# Set IGNITE_HOME.
+#
+export IGNITE_HOME="$(dirname "$(cd "$(dirname "$0")"; "pwd")")";
+
 DIR="$( dirname "$SOURCE" )"
 
 while [ -h "$SOURCE" ]


[15/50] [abbrv] ignite git commit: IGNITE-6546 Fixed faveicon.

Posted by ag...@apache.org.
IGNITE-6546 Fixed faveicon.


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

Branch: refs/heads/ignite-6305
Commit: f42f34b8dc293e2077ea99a49136d3e2d439e832
Parents: 3256ee2
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Tue Oct 3 14:33:10 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Tue Oct 3 14:33:10 2017 +0700

----------------------------------------------------------------------
 .../rest/protocols/http/jetty/favicon.ico        | Bin 1406 -> 1150 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/f42f34b8/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/favicon.ico
----------------------------------------------------------------------
diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/favicon.ico b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/favicon.ico
index 6f6ed44..b36f8d7 100644
Binary files a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/favicon.ico and b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/favicon.ico differ


[12/50] [abbrv] ignite git commit: IGNITE-6517 .NET: DataStreamer DefaultPerNodeBufferSize, DefaultParallelOpsMultiplier, Timeout

Posted by ag...@apache.org.
IGNITE-6517 .NET: DataStreamer DefaultPerNodeBufferSize, DefaultParallelOpsMultiplier, Timeout

This closes #2785


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

Branch: refs/heads/ignite-6305
Commit: 5764960e802e91b87956f4515e289eaf0003a2de
Parents: 5ca7909
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Mon Oct 2 16:48:23 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Mon Oct 2 16:48:23 2017 +0300

----------------------------------------------------------------------
 .../datastreamer/PlatformDataStreamer.java      | 14 ++++++
 .../Dataload/DataStreamerTest.cs                | 50 +++++++++++++++++---
 .../Apache.Ignite.Core.csproj                   |  1 +
 .../Datastream/DataStreamerDefaults.cs          | 46 ++++++++++++++++++
 .../Datastream/IDataStreamer.cs                 | 21 +++++++-
 .../Impl/Binary/BinaryReaderExtensions.cs       | 10 +---
 .../Impl/Binary/BinaryUtils.cs                  | 14 ++++++
 .../Impl/Datastream/DataStreamerImpl.cs         | 43 ++++++++++++++++-
 8 files changed, 179 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5764960e/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/datastreamer/PlatformDataStreamer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/datastreamer/PlatformDataStreamer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/datastreamer/PlatformDataStreamer.java
index fba0a4c..8cd14c7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/datastreamer/PlatformDataStreamer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/datastreamer/PlatformDataStreamer.java
@@ -86,6 +86,12 @@ public class PlatformDataStreamer extends PlatformAbstractTarget {
     /** */
     private static final int OP_LISTEN_TOPOLOGY = 11;
 
+    /** */
+    private static final int OP_GET_TIMEOUT = 12;
+
+    /** */
+    private static final int OP_SET_TIMEOUT = 13;
+
     /** Cache name. */
     private final String cacheName;
 
@@ -230,6 +236,14 @@ public class PlatformDataStreamer extends PlatformAbstractTarget {
 
             case OP_PER_NODE_PARALLEL_OPS:
                 return ldr.perNodeParallelOperations();
+
+            case OP_GET_TIMEOUT:
+                return ldr.timeout();
+
+            case OP_SET_TIMEOUT:
+                ldr.timeout(val);
+
+                return TRUE;
         }
 
         return super.processInLongOutLong(type, val);

http://git-wip-us.apache.org/repos/asf/ignite/blob/5764960e/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs
index fe5955f..60a1067 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs
@@ -95,25 +95,40 @@ namespace Apache.Ignite.Core.Tests.Dataload
         {
             using (IDataStreamer<int, int> ldr = _grid.GetDataStreamer<int, int>(CacheName))
             {
+                Assert.AreEqual(CacheName, ldr.CacheName);
+                Assert.AreEqual(0, ldr.AutoFlushFrequency);
+
+                Assert.IsFalse(ldr.AllowOverwrite);
                 ldr.AllowOverwrite = true;
                 Assert.IsTrue(ldr.AllowOverwrite);
                 ldr.AllowOverwrite = false;
                 Assert.IsFalse(ldr.AllowOverwrite);
 
+                Assert.IsFalse(ldr.SkipStore);
                 ldr.SkipStore = true;
                 Assert.IsTrue(ldr.SkipStore);
                 ldr.SkipStore = false;
                 Assert.IsFalse(ldr.SkipStore);
 
+                Assert.AreEqual(DataStreamerDefaults.DefaultPerNodeBufferSize, ldr.PerNodeBufferSize);
                 ldr.PerNodeBufferSize = 1;
                 Assert.AreEqual(1, ldr.PerNodeBufferSize);
                 ldr.PerNodeBufferSize = 2;
                 Assert.AreEqual(2, ldr.PerNodeBufferSize);
 
-                ldr.PerNodeParallelOperations = 1;
-                Assert.AreEqual(1, ldr.PerNodeParallelOperations);
+                Assert.AreEqual(0, ldr.PerNodeParallelOperations);
+                var ops = DataStreamerDefaults.DefaultParallelOperationsMultiplier *
+                          IgniteConfiguration.DefaultThreadPoolSize;
+                ldr.PerNodeParallelOperations = ops;
+                Assert.AreEqual(ops, ldr.PerNodeParallelOperations);
                 ldr.PerNodeParallelOperations = 2;
                 Assert.AreEqual(2, ldr.PerNodeParallelOperations);
+
+                Assert.AreEqual(DataStreamerDefaults.DefaultTimeout, ldr.Timeout);
+                ldr.Timeout = TimeSpan.MaxValue;
+                Assert.AreEqual(TimeSpan.MaxValue, ldr.Timeout);
+                ldr.Timeout = TimeSpan.FromSeconds(1.5);
+                Assert.AreEqual(1.5, ldr.Timeout.TotalSeconds);
             }
         }
 
@@ -123,28 +138,37 @@ namespace Apache.Ignite.Core.Tests.Dataload
         [Test]        
         public void TestAddRemove()
         {
-            using (IDataStreamer<int, int> ldr = _grid.GetDataStreamer<int, int>(CacheName))
+            IDataStreamer<int, int> ldr;
+
+            using (ldr = _grid.GetDataStreamer<int, int>(CacheName))
             {
+                Assert.IsFalse(ldr.Task.IsCompleted);
+
                 ldr.AllowOverwrite = true;
 
                 // Additions.
-                ldr.AddData(1, 1);
+                var task = ldr.AddData(1, 1);
                 ldr.Flush();                
                 Assert.AreEqual(1, _cache.Get(1));
+                Assert.IsTrue(task.IsCompleted);
+                Assert.IsFalse(ldr.Task.IsCompleted);
 
-                ldr.AddData(new KeyValuePair<int, int>(2, 2));
+                task = ldr.AddData(new KeyValuePair<int, int>(2, 2));
                 ldr.Flush();
                 Assert.AreEqual(2, _cache.Get(2));
+                Assert.IsTrue(task.IsCompleted);
 
-                ldr.AddData(new List<KeyValuePair<int, int>> { new KeyValuePair<int, int>(3, 3), new KeyValuePair<int, int>(4, 4) });
+                task = ldr.AddData(new [] { new KeyValuePair<int, int>(3, 3), new KeyValuePair<int, int>(4, 4) });
                 ldr.Flush();
                 Assert.AreEqual(3, _cache.Get(3));
                 Assert.AreEqual(4, _cache.Get(4));
+                Assert.IsTrue(task.IsCompleted);
 
                 // Removal.
-                ldr.RemoveData(1);
+                task = ldr.RemoveData(1);
                 ldr.Flush();
                 Assert.IsFalse(_cache.ContainsKey(1));
+                Assert.IsTrue(task.IsCompleted);
 
                 // Mixed.
                 ldr.AddData(5, 5);                
@@ -165,6 +189,8 @@ namespace Apache.Ignite.Core.Tests.Dataload
                 for (int i = 5; i < 13; i++)
                     Assert.AreEqual(i, _cache.Get(i));
             }
+
+            Assert.IsTrue(ldr.Task.IsCompleted);
         }
 
         /// <summary>
@@ -517,6 +543,16 @@ namespace Apache.Ignite.Core.Tests.Dataload
 
                 for (var i = 0; i < 100; i++)
                     Assert.AreEqual(i + 1, cache.Get(i).Val);
+
+                // Repeating WithKeepBinary call: valid args.
+                Assert.AreSame(ldr, ldr.WithKeepBinary<int, IBinaryObject>());
+
+                // Invalid type args.
+                var ex = Assert.Throws<InvalidOperationException>(() => ldr.WithKeepBinary<string, IBinaryObject>());
+
+                Assert.AreEqual(
+                    "Can't change type of binary streamer. WithKeepBinary has been called on an instance of " +
+                    "binary streamer with incompatible generic arguments.", ex.Message);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/5764960e/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 67c540c..58abd26 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -104,6 +104,7 @@
     <Compile Include="Common\ExceptionFactory.cs" />
     <Compile Include="Configuration\Package-Info.cs" />
     <Compile Include="Configuration\ClientConnectorConfiguration.cs" />
+    <Compile Include="Datastream\DataStreamerDefaults.cs" />
     <Compile Include="Impl\Binary\BinaryTypeId.cs" />
     <Compile Include="Impl\Client\Cache\CacheFlags.cs" />
     <Compile Include="Impl\Client\Cache\Query\ClientQueryCursor.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/5764960e/modules/platforms/dotnet/Apache.Ignite.Core/Datastream/DataStreamerDefaults.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Datastream/DataStreamerDefaults.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Datastream/DataStreamerDefaults.cs
new file mode 100644
index 0000000..315ae7f
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Datastream/DataStreamerDefaults.cs
@@ -0,0 +1,46 @@
+/*
+ * 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.Datastream
+{
+    using System;
+
+    /// <summary>
+    /// Data streamer configuration defaults.
+    /// </summary>
+    public static class DataStreamerDefaults
+    {
+        /// <summary>
+        /// The default per node buffer size, see <see cref="IDataStreamer{TK,TV}.PerNodeBufferSize"/>.
+        /// </summary>
+        public const int DefaultPerNodeBufferSize = 512;
+
+        /// <summary>
+        /// Default multiplier for parallel operations per node:
+        /// <see cref="IDataStreamer{TK,TV}.PerNodeParallelOperations"/> = 
+        /// <see cref="IgniteConfiguration.DataStreamerThreadPoolSize"/> * 
+        /// <see cref="DefaultParallelOperationsMultiplier"/>.
+        /// </summary>
+        public const int DefaultParallelOperationsMultiplier = 8;
+
+        /// <summary>
+        /// The default timeout (see <see cref="IDataStreamer{TK,TV}.Timeout"/>).
+        /// Negative value means no timeout.
+        /// </summary>
+        public static readonly TimeSpan DefaultTimeout = TimeSpan.FromMilliseconds(-1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5764960e/modules/platforms/dotnet/Apache.Ignite.Core/Datastream/IDataStreamer.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Datastream/IDataStreamer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Datastream/IDataStreamer.cs
index 222f6c3..277130c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Datastream/IDataStreamer.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Datastream/IDataStreamer.cs
@@ -19,6 +19,7 @@ namespace Apache.Ignite.Core.Datastream
 {
     using System;
     using System.Collections.Generic;
+    using System.ComponentModel;
     using System.Threading.Tasks;
     using Apache.Ignite.Core.Cache.Store;
 
@@ -110,8 +111,9 @@ namespace Apache.Ignite.Core.Datastream
         /// <para />
         /// Setter must be called before any add/remove operation.
         /// <para />
-        /// Default is <c>1024</c>.
+        /// Default is <see cref="DataStreamerDefaults.DefaultPerNodeBufferSize"/>.
         /// </summary>
+        [DefaultValue(DataStreamerDefaults.DefaultPerNodeBufferSize)]
         int PerNodeBufferSize { get; set; }
 
         /// <summary>
@@ -119,7 +121,9 @@ namespace Apache.Ignite.Core.Datastream
         /// <para />
         /// Setter must be called before any add/remove operation.
         /// <para />
-        /// Default is <c>16</c>.
+        /// Default is 0, which means Ignite calculates this automatically as 
+        /// <see cref="IgniteConfiguration.DataStreamerThreadPoolSize"/> * 
+        /// <see cref="DataStreamerDefaults.DefaultParallelOperationsMultiplier"/>.
         /// </summary>
         int PerNodeParallelOperations { get; set; }
 
@@ -208,5 +212,18 @@ namespace Apache.Ignite.Core.Datastream
         /// <typeparam name="TV1">Value type in binary mode.</typeparam>
         /// <returns>Streamer instance with binary mode enabled.</returns>
         IDataStreamer<TK1, TV1> WithKeepBinary<TK1, TV1>();
+
+        /// <summary>
+        /// Gets or sets the timeout. Negative values mean no timeout.
+        /// Default is <see cref="DataStreamerDefaults.DefaultTimeout"/>.
+        /// <para />
+        /// Timeout is used in the following cases:
+        /// <li>Any data addition method can be blocked when all per node parallel operations are exhausted.
+        /// The timeout defines the max time you will be blocked waiting for a permit to add a chunk of data
+        /// into the streamer;</li> 
+        /// <li>Total timeout time for <see cref="Flush"/> operation;</li>
+        /// <li>Total timeout time for <see cref="Close"/> operation.</li>
+        /// </summary>
+        TimeSpan Timeout { get; set; }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5764960e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReaderExtensions.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReaderExtensions.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReaderExtensions.cs
index 7556c41..da87d21 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReaderExtensions.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReaderExtensions.cs
@@ -58,15 +58,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <returns>TimeSpan.</returns>
         public static TimeSpan ReadLongAsTimespan(this IBinaryRawReader reader)
         {
-            long ms = reader.ReadLong();
-
-            if (ms >= TimeSpan.MaxValue.TotalMilliseconds)
-                return TimeSpan.MaxValue;
-
-            if (ms <= TimeSpan.MinValue.TotalMilliseconds)
-                return TimeSpan.MinValue;
-
-            return TimeSpan.FromMilliseconds(ms);
+            return BinaryUtils.LongToTimeSpan(reader.ReadLong());
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/5764960e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
index 46e6752..139783d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
@@ -1664,6 +1664,20 @@ namespace Apache.Ignite.Core.Impl.Binary
         }
 
         /// <summary>
+        /// Converts long to timespan.
+        /// </summary>
+        public static TimeSpan LongToTimeSpan(long ms)
+        {
+            if (ms >= TimeSpan.MaxValue.TotalMilliseconds)
+                return TimeSpan.MaxValue;
+
+            if (ms <= TimeSpan.MinValue.TotalMilliseconds)
+                return TimeSpan.MinValue;
+
+            return TimeSpan.FromMilliseconds(ms);
+        }
+
+        /// <summary>
         /// Creates and instance from the type name in reader.
         /// </summary>
         private static T CreateInstance<T>(BinaryReader reader)

http://git-wip-us.apache.org/repos/asf/ignite/blob/5764960e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerImpl.cs
index 96b24ab..555c6e6 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerImpl.cs
@@ -93,6 +93,12 @@ namespace Apache.Ignite.Core.Impl.Datastream
         /** */
         private const int OpListenTopology = 11;
 
+        /** */
+        private const int OpGetTimeout = 12;
+
+        /** */
+        private const int OpSetTimeout = 13;
+
         /** Cache name. */
         private readonly string _cacheName;
 
@@ -356,8 +362,6 @@ namespace Apache.Ignite.Core.Impl.Datastream
         {
             get
             {
-                ThrowIfDisposed();
-
                 return _closeFut.Task;
             }
         }
@@ -549,6 +553,41 @@ namespace Apache.Ignite.Core.Impl.Datastream
         }
 
         /** <inheritDoc /> */
+        public TimeSpan Timeout
+        {
+            get
+            {
+                _rwLock.EnterReadLock();
+
+                try
+                {
+                    ThrowIfDisposed();
+
+                    return BinaryUtils.LongToTimeSpan(DoOutInOp(OpGetTimeout));
+                }
+                finally
+                {
+                    _rwLock.ExitReadLock();
+                }
+            }
+            set
+            {
+                _rwLock.EnterWriteLock();
+
+                try
+                {
+                    ThrowIfDisposed();
+
+                    DoOutInOp(OpSetTimeout, (long) value.TotalMilliseconds);
+                }
+                finally
+                {
+                    _rwLock.ExitWriteLock();
+                }
+            }
+        }
+
+        /** <inheritDoc /> */
         [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
         protected override void Dispose(bool disposing)
         {


[45/50] [abbrv] ignite git commit: IGNITE-6054: Fixed tests.

Posted by ag...@apache.org.
IGNITE-6054: Fixed tests.


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

Branch: refs/heads/ignite-6305
Commit: 90624c64f76ae46cb98d30b0f7f0697ec6701fbb
Parents: 87e7b32
Author: devozerov <vo...@gridgain.com>
Authored: Mon Oct 9 11:57:06 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Oct 9 11:57:06 2017 +0300

----------------------------------------------------------------------
 .../cache/index/H2DynamicColumnsAbstractBasicSelfTest.java        | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/90624c64/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
index 34be34d..b9f8c61 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
@@ -341,8 +341,7 @@ public abstract class H2DynamicColumnsAbstractBasicSelfTest extends DynamicColum
      */
     private void doTestAlterTableOnFlatValue(String tblName) {
         assertThrows("ALTER TABLE " + tblName + " ADD COLUMN y varchar",
-            "ADD COLUMN is not supported for tables created with wrap_value=false param. " +
-                "(To enable ADD COLUMN, create table with wrap_value=true param).");
+            "Cannot add column(s) because table was created with WRAP_VALUE=false option.");
     }
 
     /**


[10/50] [abbrv] ignite git commit: IGNITE-6231 .NET: Do not start a new thread explicitly in Flusher.RunThread

Posted by ag...@apache.org.
IGNITE-6231 .NET: Do not start a new thread explicitly in Flusher.RunThread


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

Branch: refs/heads/ignite-6305
Commit: 7aaacd8f92645558430b5343a1cb8bf7e908529a
Parents: f57b677
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Mon Oct 2 16:09:04 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Mon Oct 2 16:09:04 2017 +0300

----------------------------------------------------------------------
 .../dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerImpl.cs  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/7aaacd8f/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerImpl.cs
index fb2df01..96b24ab 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Datastream/DataStreamerImpl.cs
@@ -858,7 +858,7 @@ namespace Apache.Ignite.Core.Impl.Datastream
             /// </summary>
             public void RunThread()
             {
-                new Thread(Run).Start();
+                Task.Factory.StartNew(Run);
             }
         }
 


[18/50] [abbrv] ignite git commit: IGNITE-6382 .NET: Set up NDepend project

Posted by ag...@apache.org.
IGNITE-6382 .NET: Set up NDepend project

This closes #2786


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

Branch: refs/heads/ignite-6305
Commit: b21f750f74d0b6598693184d5925addfe828b7ca
Parents: f42f34b
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Tue Oct 3 13:27:51 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Tue Oct 3 13:27:51 2017 +0300

----------------------------------------------------------------------
 modules/platforms/.gitignore                    |     3 +-
 .../Impl/Binary/BinaryProcessorClient.cs        |     4 +-
 .../Client/Cache/Query/ClientQueryCursor.cs     |     1 -
 .../Apache.Ignite.Core/Impl/Events/Events.cs    |     2 +-
 .../Impl/Unmanaged/UnmanagedCallbacks.cs        |     2 +-
 modules/platforms/dotnet/Apache.Ignite.ndproj   | 11139 +++++++++++++++++
 parent/pom.xml                                  |     1 +
 7 files changed, 11146 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b21f750f/modules/platforms/.gitignore
----------------------------------------------------------------------
diff --git a/modules/platforms/.gitignore b/modules/platforms/.gitignore
index 6c05af0..4b415cb 100644
--- a/modules/platforms/.gitignore
+++ b/modules/platforms/.gitignore
@@ -28,4 +28,5 @@ ipch/
 [Rr]elease*/
 packages
 *.classname
-*.nupkg
\ No newline at end of file
+*.nupkg
+NDependOut
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/b21f750f/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessorClient.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessorClient.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessorClient.cs
index 26a8e9b..816e24a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessorClient.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessorClient.cs
@@ -59,7 +59,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /** <inheritdoc /> */
         public List<IBinaryType> GetBinaryTypes()
         {
-            throw new NotImplementedException();
+            throw new NotSupportedException();
         }
 
         /** <inheritdoc /> */
@@ -96,7 +96,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /** <inheritdoc /> */
         public BinaryType RegisterEnum(string typeName, IEnumerable<KeyValuePair<string, int>> values)
         {
-            throw new NotImplementedException();
+            throw new NotSupportedException();
         }
 
         /** <inheritdoc /> */

http://git-wip-us.apache.org/repos/asf/ignite/blob/b21f750f/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs
index 75aa5df..ff891db 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs
@@ -18,7 +18,6 @@
 namespace Apache.Ignite.Core.Impl.Client.Cache.Query
 {
     using System.Collections.Generic;
-    using System.Diagnostics;
     using System.Diagnostics.CodeAnalysis;
     using System.Linq;
     using Apache.Ignite.Core.Cache;

http://git-wip-us.apache.org/repos/asf/ignite/blob/b21f750f/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Events/Events.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Events/Events.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Events/Events.cs
index 55f5be8..a81523a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Events/Events.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Events/Events.cs
@@ -284,7 +284,7 @@ namespace Apache.Ignite.Core.Impl.Events
         /** <inheritDoc /> */
         public void RecordLocal(IEvent evt)
         {
-            throw new NotImplementedException("IGNITE-1410");
+            throw new NotSupportedException("IGNITE-1410");
         }
 
         /** <inheritDoc /> */

http://git-wip-us.apache.org/repos/asf/ignite/blob/b21f750f/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 37a24b1..2cc3659 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
@@ -1060,7 +1060,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
             return 0;
         }
 
-        private long MemoryReallocate(long memPtr, long cap, long unused, void* arg)
+        private static long MemoryReallocate(long memPtr, long cap, long unused, void* arg)
         {
             IgniteManager.Memory.Get(memPtr).Reallocate((int)cap);
 


[39/50] [abbrv] ignite git commit: IGNITE-6570 Web Console: Move parsing of JSON to pool of workers.

Posted by ag...@apache.org.
IGNITE-6570 Web Console: Move parsing of JSON to pool of workers.


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

Branch: refs/heads/ignite-6305
Commit: 74f04001a985211c499ee4bbd73de686288684a8
Parents: a38fdec
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Fri Oct 6 17:00:39 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Fri Oct 6 17:00:39 2017 +0700

----------------------------------------------------------------------
 modules/web-console/backend/app/agentSocket.js  |  21 +---
 .../web-console/backend/app/browsersHandler.js  |   9 +-
 .../app/modules/agent/AgentManager.service.js   |  18 ++-
 .../app/modules/agent/decompress.worker.js      |  33 +++++
 .../frontend/app/utils/SimpleWorkerPool.js      | 119 +++++++++++++++++++
 modules/web-console/frontend/package.json       |   1 +
 6 files changed, 176 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/74f04001/modules/web-console/backend/app/agentSocket.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/agentSocket.js b/modules/web-console/backend/app/agentSocket.js
index 489d145..75dcd53 100644
--- a/modules/web-console/backend/app/agentSocket.js
+++ b/modules/web-console/backend/app/agentSocket.js
@@ -24,7 +24,7 @@
  */
 module.exports = {
     implements: 'agent-socket',
-    inject: ['require(lodash)', 'require(zlib)']
+    inject: ['require(lodash)']
 };
 
 /**
@@ -79,10 +79,9 @@ class Command {
 
 /**
  * @param _
- * @param zlib
  * @returns {AgentSocket}
  */
-module.exports.factory = function(_, zlib) {
+module.exports.factory = function(_) {
     /**
      * Connected agent descriptor.
      */
@@ -136,21 +135,7 @@ module.exports.factory = function(_, zlib) {
                     if (resErr)
                         return reject(resErr);
 
-                    if (res.zipped) {
-                        // TODO IGNITE-6127 Temporary solution until GZip support for socket.io-client-java.
-                        // See: https://github.com/socketio/socket.io-client-java/issues/312
-                        // We can GZip manually for now.
-                        zlib.gunzip(new Buffer(res.data, 'base64'), (unzipErr, unzipped) => {
-                            if (unzipErr)
-                                return reject(unzipErr);
-
-                            res.data = unzipped.toString();
-
-                            resolve(res);
-                        });
-                    }
-                    else
-                        resolve(res);
+                    resolve(res);
                 })
             );
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/74f04001/modules/web-console/backend/app/browsersHandler.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/browsersHandler.js b/modules/web-console/backend/app/browsersHandler.js
index 4fb5088..f4ff23c 100644
--- a/modules/web-console/backend/app/browsersHandler.js
+++ b/modules/web-console/backend/app/browsersHandler.js
@@ -181,8 +181,12 @@ module.exports.factory = (_, socketio, configure, errors, mongo) => {
             return agent
                 .then((agentSock) => agentSock.emitEvent('node:rest', {uri: 'ignite', demo, params}))
                 .then((res) => {
-                    if (res.status === 0)
+                    if (res.status === 0) {
+                        if (res.zipped)
+                            return res;
+
                         return JSON.parse(res.data);
+                    }
 
                     throw new Error(res.error);
                 });
@@ -250,6 +254,9 @@ module.exports.factory = (_, socketio, configure, errors, mongo) => {
 
                 this.executeOnNode(agent, demo, params)
                     .then((data) => {
+                        if (data.zipped)
+                            return cb(null, data);
+
                         if (data.finished)
                             return cb(null, data.result);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/74f04001/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/agent/AgentManager.service.js b/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
index 288ec94..752b4f0 100644
--- a/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
+++ b/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
@@ -17,6 +17,8 @@
 
 import { BehaviorSubject } from 'rxjs/BehaviorSubject';
 
+import Worker from 'worker!./decompress.worker';
+import SimpleWorkerPool from '../../utils/SimpleWorkerPool';
 import maskNull from 'app/core/utils/maskNull';
 
 const State = {
@@ -82,11 +84,9 @@ export default class IgniteAgentManager {
 
         this.promises = new Set();
 
-        /**
-         * Connection to backend.
-         * @type {Socket}
-         */
-        this.socket = null;
+        this.pool = new SimpleWorkerPool('decompressor', Worker, 4);
+
+        this.socket = null; // Connection to backend.
 
         let cluster;
 
@@ -364,7 +364,13 @@ export default class IgniteAgentManager {
      * @private
      */
     _rest(event, ...args) {
-        return this._emit(event, _.get(this.connectionSbj.getValue(), 'cluster.id'), ...args);
+        return this._emit(event, _.get(this.connectionSbj.getValue(), 'cluster.id'), ...args)
+            .then((data) => {
+                if (data.zipped)
+                    return this.pool.postMessage(data.data);
+
+                return data;
+            });
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/74f04001/modules/web-console/frontend/app/modules/agent/decompress.worker.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/agent/decompress.worker.js b/modules/web-console/frontend/app/modules/agent/decompress.worker.js
new file mode 100644
index 0000000..d8e176d
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/agent/decompress.worker.js
@@ -0,0 +1,33 @@
+/*
+ * 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 _ from 'lodash';
+import pako from 'pako';
+
+/** This worker decode & decompress BASE64/Zipped data and parse to JSON. */
+// eslint-disable-next-line no-undef
+onmessage = function(e) {
+    const data = e.data;
+
+    const binaryString = atob(data); // Decode from BASE64
+
+    const unzipped = pako.inflate(binaryString, {to: 'string'});
+
+    const res = JSON.parse(unzipped);
+
+    postMessage(_.get(res, 'result', res));
+};

http://git-wip-us.apache.org/repos/asf/ignite/blob/74f04001/modules/web-console/frontend/app/utils/SimpleWorkerPool.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/utils/SimpleWorkerPool.js b/modules/web-console/frontend/app/utils/SimpleWorkerPool.js
new file mode 100644
index 0000000..d8ed28b
--- /dev/null
+++ b/modules/web-console/frontend/app/utils/SimpleWorkerPool.js
@@ -0,0 +1,119 @@
+/*
+ * 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 {Observable} from 'rxjs/Observable';
+import {Subject} from 'rxjs/Subject';
+import 'rxjs/add/observable/race';
+import 'rxjs/add/operator/filter';
+import 'rxjs/add/operator/pluck';
+import 'rxjs/add/operator/take';
+import 'rxjs/add/operator/toPromise';
+
+/**
+ * Simple implementation of workers pool.
+ */
+export default class SimpleWorkerPool {
+    constructor(name, WorkerClass, poolSize = (navigator.hardwareConcurrency || 4), dbg = false) {
+        this._name = name;
+        this._WorkerClass = WorkerClass;
+        this._tasks = [];
+        this._msgId = 0;
+        this.messages$ = new Subject();
+        this.errors$ = new Subject();
+        this.__dbg = dbg;
+
+        this._workers = _.range(poolSize).map(() => {
+            const worker = new this._WorkerClass();
+
+            worker.onmessage = (m) => {
+                this.messages$.next({tid: worker.tid, m});
+
+                worker.tid = null;
+
+                this._run();
+            };
+
+            worker.onerror = (e) => {
+                this.errors$.next({tid: worker.tid, e});
+
+                worker.tid = null;
+
+                this._run();
+            };
+
+            return worker;
+        });
+    }
+
+    _makeTaskID() {
+        return this._msgId++;
+    }
+
+    _getNextWorker() {
+        return this._workers.find((w) => !w.tid);
+    }
+
+    _getNextTask() {
+        return this._tasks.shift();
+    }
+
+    _run() {
+        const worker = this._getNextWorker();
+
+        if (!worker || !this._tasks.length)
+            return;
+
+        const task = this._getNextTask();
+
+        worker.tid = task.tid;
+
+        if (this.__dbg)
+            console.time(`Post message[pool=${this._name}]`);
+
+        worker.postMessage(task.data);
+
+        if (this.__dbg)
+            console.timeEnd('Post message');
+    }
+
+    terminate() {
+        this._workers.forEach((w) => w.terminate());
+
+        this.messages$.complete();
+        this.errors$.complete();
+
+        this._workers = null;
+    }
+
+    postMessage(data) {
+        const tid = this._makeTaskID();
+
+        this._tasks.push({tid, data});
+
+        if (this.__dbg)
+            console.log(`Pool: [name=${this._name}, queue=${this._tasks.length}]`);
+
+        this._run();
+
+        return Observable.race(
+            this.messages$.filter((e) => e.tid === tid).take(1).pluck('m', 'data'),
+            this.errors$.filter((e) => e.tid === tid).take(1).map((e) => {
+                throw e.e;
+            }))
+            .take(1).toPromise();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/74f04001/modules/web-console/frontend/package.json
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/package.json b/modules/web-console/frontend/package.json
index d828e17..2083640 100644
--- a/modules/web-console/frontend/package.json
+++ b/modules/web-console/frontend/package.json
@@ -80,6 +80,7 @@
     "lodash": "4.17.4",
     "node-sass": "4.5.3",
     "nvd3": "1.8.4",
+    "pako": "1.0.6",
     "progress-bar-webpack-plugin": "1.10.0",
     "pug-html-loader": "1.1.0",
     "pug-loader": "2.3.0",


[36/50] [abbrv] ignite git commit: IGNITE-6287 Web Console: Improved DDL support.

Posted by ag...@apache.org.
IGNITE-6287 Web Console: Improved DDL support.


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

Branch: refs/heads/ignite-6305
Commit: 2410f0792fec33725f1b7f74b5b576b353b8fe55
Parents: 49b8358
Author: Vasiliy Sisko <vs...@gridgain.com>
Authored: Fri Oct 6 14:25:42 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Fri Oct 6 14:25:42 2017 +0700

----------------------------------------------------------------------
 .../handlers/cache/GridCacheCommandHandler.java | 12 +++++--
 .../internal/visor/query/VisorQueryTask.java    | 36 ++++++++++++++++++--
 .../app/modules/agent/AgentManager.service.js   |  7 ++--
 .../frontend/app/modules/sql/sql.controller.js  | 36 ++++++++++++++------
 .../web-console/frontend/views/sql/sql.tpl.pug  | 14 ++++----
 5 files changed, 79 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/2410f079/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java
index 53342c9..d627b20 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java
@@ -56,6 +56,7 @@ import org.apache.ignite.internal.processors.cache.CacheInvokeEntry;
 import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
+import org.apache.ignite.internal.processors.cache.IgniteCacheProxy;
 import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
 import org.apache.ignite.internal.processors.cache.query.GridCacheSqlMetadata;
 import org.apache.ignite.internal.processors.rest.GridRestCommand;
@@ -1078,7 +1079,11 @@ public class GridCacheCommandHandler extends GridRestCommandHandlerAdapter {
         /** {@inheritDoc} */
         @Override public Collection<GridCacheSqlMetadata> execute() {
             String cacheName = null;
-            IgniteInternalCache<?, ?> cache;
+
+            if (!ignite.active())
+                return Collections.emptyList();
+
+            IgniteInternalCache<?, ?> cache = null;
 
             if (!F.isEmpty(arguments())) {
                 cacheName = argument(0);
@@ -1088,7 +1093,10 @@ public class GridCacheCommandHandler extends GridRestCommandHandlerAdapter {
                 assert cache != null;
             }
             else {
-                cache = F.first(ignite.context().cache().publicCaches()).internalProxy();
+                IgniteCacheProxy<?, ?> pubCache = F.first(ignite.context().cache().publicCaches());
+
+                if (pubCache != null)
+                    cache = pubCache.internalProxy();
 
                 if (cache == null)
                     return Collections.emptyList();

http://git-wip-us.apache.org/repos/asf/ignite/blob/2410f079/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryTask.java
index c85ceea..a3668c8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryTask.java
@@ -22,10 +22,15 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.UUID;
+import javax.cache.CacheException;
 import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.query.FieldsQueryCursor;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
+import org.apache.ignite.internal.processors.query.IgniteSQLException;
 import org.apache.ignite.internal.processors.task.GridInternal;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.internal.visor.VisorEither;
@@ -70,7 +75,6 @@ public class VisorQueryTask extends VisorOneNodeTask<VisorQueryTaskArg, VisorEit
         /** {@inheritDoc} */
         @Override protected VisorEither<VisorQueryResult> run(final VisorQueryTaskArg arg) {
             try {
-                IgniteCache<Object, Object> c = ignite.cache(arg.getCacheName());
                 UUID nid = ignite.localNode().id();
 
                 SqlFieldsQuery qry = new SqlFieldsQuery(arg.getQueryText());
@@ -83,7 +87,35 @@ public class VisorQueryTask extends VisorOneNodeTask<VisorQueryTaskArg, VisorEit
 
                 long start = U.currentTimeMillis();
 
-                VisorQueryCursor<List<?>> cur = new VisorQueryCursor<>(c.withKeepBinary().query(qry));
+                FieldsQueryCursor<List<?>> qryCursor;
+
+                String cacheName = arg.getCacheName();
+
+                if (F.isEmpty(cacheName))
+                    qryCursor = ignite.context().query().querySqlFieldsNoCache(qry, true);
+                else {
+                    IgniteCache<Object, Object> c = ignite.cache(cacheName);
+
+                    if (c == null)
+                        throw new SQLException("Fail to execute query. Cache not found: " + cacheName);
+
+                    try {
+                        qryCursor = c.withKeepBinary().query(qry);
+                    }
+                    catch (CacheException e) {
+                        // Work around for DDL without explicit schema name.
+                        if (X.hasCause(e, IgniteSQLException.class)
+                            && e.getMessage().contains("can only be executed on PUBLIC schema")) {
+                            qry.setSchema("PUBLIC");
+
+                            qryCursor = c.withKeepBinary().query(qry);
+                        }
+                        else
+                            throw e;
+                    }
+                }
+
+                VisorQueryCursor<List<?>> cur = new VisorQueryCursor<>(qryCursor);
 
                 Collection<GridQueryFieldMetadata> meta = cur.fieldsMeta();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/2410f079/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/agent/AgentManager.service.js b/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
index 20d2976..288ec94 100644
--- a/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
+++ b/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
@@ -377,11 +377,10 @@ export default class IgniteAgentManager {
     }
 
     /**
-     * @param {String} [cacheName] Cache name.
      * @returns {Promise}
      */
-    metadata(cacheName) {
-        return this._rest('node:rest', {cmd: 'metadata', cacheName: maskNull(cacheName)})
+    metadata() {
+        return this._rest('node:rest', {cmd: 'metadata'})
             .then((caches) => {
                 let types = [];
 
@@ -590,7 +589,7 @@ export default class IgniteAgentManager {
                 nid + '=' + queryId);
         }
 
-        return this.visorTask('queryClose', nid, queryId);
+        return this.visorTask('queryClose', nid, nid, queryId);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/2410f079/modules/web-console/frontend/app/modules/sql/sql.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/sql/sql.controller.js b/modules/web-console/frontend/app/modules/sql/sql.controller.js
index 5f06c1e..8011b0f 100644
--- a/modules/web-console/frontend/app/modules/sql/sql.controller.js
+++ b/modules/web-console/frontend/app/modules/sql/sql.controller.js
@@ -863,9 +863,6 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
                         return cachesAcc;
                     }, []), 'label');
 
-                    if (_.isEmpty($scope.caches))
-                        return;
-
                     // Reset to first cache in case of stopped selected.
                     const cacheNames = _.map($scope.caches, (cache) => cache.value);
 
@@ -1313,6 +1310,9 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
          * @return {String} Nid
          */
         const _chooseNode = (name, local) => {
+            if (_.isEmpty(name))
+                return Promise.resolve(null);
+
             const nodes = cacheNodes(name);
 
             if (local) {
@@ -1386,7 +1386,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
             const enforceJoinOrder = !!paragraph.enforceJoinOrder;
             const lazy = !!paragraph.lazy;
 
-            $scope.actionAvailable(paragraph, true) && _chooseNode(paragraph.cacheName, local)
+            $scope.queryAvailable(paragraph) && _chooseNode(paragraph.cacheName, local)
                 .then((nid) => {
                     Notebook.save($scope.notebook)
                         .catch(Messages.showError);
@@ -1444,7 +1444,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
         };
 
         $scope.explain = (paragraph) => {
-            if (!$scope.actionAvailable(paragraph, true))
+            if (!$scope.queryAvailable(paragraph))
                 return;
 
             Notebook.save($scope.notebook)
@@ -1483,7 +1483,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
             const filter = paragraph.filter;
             const pageSize = paragraph.pageSize;
 
-            $scope.actionAvailable(paragraph, false) && _chooseNode(cacheName, local)
+            $scope.scanAvailable(paragraph) && _chooseNode(cacheName, local)
                 .then((nid) => {
                     Notebook.save($scope.notebook)
                         .catch(Messages.showError);
@@ -1689,18 +1689,32 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
             _chartApplySettings(paragraph, true);
         };
 
-        $scope.actionAvailable = function(paragraph, needQuery) {
-            return $scope.caches.length > 0 && (!needQuery || paragraph.query) && !paragraph.loading;
+        $scope.queryAvailable = function(paragraph) {
+            return paragraph.query && !paragraph.loading;
+        };
+
+        $scope.queryTooltip = function(paragraph, action) {
+            if ($scope.queryAvailable(paragraph))
+                return;
+
+            if (paragraph.loading)
+                return 'Waiting for server response';
+
+            return 'Input text to ' + action;
+        };
+
+        $scope.scanAvailable = function(paragraph) {
+            return $scope.caches.length && !paragraph.loading;
         };
 
-        $scope.actionTooltip = function(paragraph, action, needQuery) {
-            if ($scope.actionAvailable(paragraph, needQuery))
+        $scope.scanTooltip = function(paragraph) {
+            if ($scope.scanAvailable(paragraph))
                 return;
 
             if (paragraph.loading)
                 return 'Waiting for server response';
 
-            return 'To ' + action + ' query select cache' + (needQuery ? ' and input query' : '');
+            return 'Select cache to export scan results';
         };
 
         $scope.clickableMetadata = function(node) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/2410f079/modules/web-console/frontend/views/sql/sql.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/sql/sql.tpl.pug b/modules/web-console/frontend/views/sql/sql.tpl.pug
index 1ef2a4c..724c53c 100644
--- a/modules/web-console/frontend/views/sql/sql.tpl.pug
+++ b/modules/web-console/frontend/views/sql/sql.tpl.pug
@@ -123,10 +123,10 @@ mixin query-settings
                     span Lazy result set
 
 mixin query-actions
-    button.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, true)' ng-click='execute(paragraph)') Execute
-    button.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, true)' ng-click='execute(paragraph, true)') Execute on selected node
+    button.btn.btn-primary(ng-disabled='!queryAvailable(paragraph)' ng-click='execute(paragraph)') Execute
+    button.btn.btn-primary(ng-disabled='!queryAvailable(paragraph)' ng-click='execute(paragraph, true)') Execute on selected node
 
-    a.btn.btn-default(ng-disabled='!actionAvailable(paragraph, true)' ng-click='explain(paragraph)' data-placement='bottom' bs-tooltip='' data-title='{{actionTooltip(paragraph, "explain", true)}}') Explain
+    a.btn.btn-default(ng-disabled='!queryAvailable(paragraph)' ng-click='explain(paragraph)' data-placement='bottom' bs-tooltip='' data-title='{{queryTooltip(paragraph, "explain query")}}') Explain
 
 mixin table-result-heading-query
     .total.row
@@ -142,7 +142,7 @@ mixin table-result-heading-query
         .col-xs-4
             .pull-right
                 -var options = [{ text: "Export", click: 'exportCsv(paragraph)' }, { text: 'Export all', click: 'exportCsvAll(paragraph)' }]
-                +btn-group('paragraph.loading', options, '{{ actionTooltip(paragraph, "export", false) }}')
+                +btn-group('paragraph.loading', options, '{{ queryTooltip(paragraph, "export query results") }}')
 
 mixin table-result-heading-scan
     .total.row
@@ -158,7 +158,7 @@ mixin table-result-heading-scan
         .col-xs-4
             .pull-right
                 -var options = [{ text: "Export", click: 'exportCsv(paragraph)' }, { text: 'Export all', click: 'exportCsvAll(paragraph)' }]
-                +btn-group('paragraph.loading', options, '{{ actionTooltip(paragraph, "export", false) }}')
+                +btn-group('paragraph.loading', options, '{{ scanTooltip(paragraph) }}')
 
 mixin table-result-body
     .grid(ui-grid='paragraph.gridOptions' ui-grid-resize-columns ui-grid-exporter)
@@ -196,9 +196,9 @@ mixin paragraph-scan
                 button.btn.btn-default.select-toggle.tipLabel(ng-model='paragraph.pageSize' bs-select bs-options='item for item in pageSizes')
 
         .col-sm-12.sql-controls
-            button.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, false)' ng-click='scan(paragraph)')
+            button.btn.btn-primary(ng-disabled='!scanAvailable(paragraph)' ng-click='scan(paragraph)')
                 | Scan
-            button.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, false)' ng-click='scan(paragraph, true)')
+            button.btn.btn-primary(ng-disabled='!scanAvailable(paragraph)' ng-click='scan(paragraph, true)')
                 | Scan on selected node
 
         .col-sm-12.sql-result(ng-if='paragraph.queryExecuted()' ng-switch='paragraph.resultType()')


[31/50] [abbrv] ignite git commit: IGNITE-6358: JDBC thick: support multiple statements. This closes #2777.

Posted by ag...@apache.org.
IGNITE-6358: JDBC thick: support multiple statements. This closes #2777.


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

Branch: refs/heads/ignite-6305
Commit: df3c407f8c40d4dcd603ee35215199cd1d60c38a
Parents: c116bfc
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Thu Oct 5 16:32:33 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Thu Oct 5 16:32:33 2017 +0300

----------------------------------------------------------------------
 .../internal/jdbc2/JdbcStatementSelfTest.java   | 130 ++++++++-
 .../org/apache/ignite/IgniteJdbcDriver.java     |   9 +-
 .../ignite/internal/jdbc2/JdbcConnection.java   |  13 +
 .../internal/jdbc2/JdbcDatabaseMetadata.java    |  54 ++--
 .../jdbc2/JdbcQueryMultipleStatementsTask.java  | 167 ++++++++++++
 .../ignite/internal/jdbc2/JdbcQueryTask.java    | 154 +++--------
 .../internal/jdbc2/JdbcQueryTaskResult.java     | 120 +++++++++
 .../ignite/internal/jdbc2/JdbcQueryTaskV3.java  |  94 +++++++
 .../ignite/internal/jdbc2/JdbcResultSet.java    | 175 +++++++++---
 .../ignite/internal/jdbc2/JdbcStatement.java    | 270 ++++++++++---------
 .../internal/jdbc2/JdbcStatementResultInfo.java |  73 +++++
 .../jdbc2/JdbcStreamedPreparedStatement.java    |  19 +-
 12 files changed, 966 insertions(+), 312 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/df3c407f/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcStatementSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcStatementSelfTest.java
index 138eef5..d3f77e0 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcStatementSelfTest.java
@@ -45,7 +45,8 @@ public class JdbcStatementSelfTest extends GridCommonAbstractTest {
     private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
 
     /** JDBC URL. */
-    private static final String BASE_URL = CFG_URL_PREFIX + "cache=default@modules/clients/src/test/config/jdbc-config.xml";
+    private static final String BASE_URL = CFG_URL_PREFIX
+        + "cache=default:multipleStatementsAllowed=true@modules/clients/src/test/config/jdbc-config.xml";
 
     /** SQL query. */
     private static final String SQL = "select * from Person where age > 30";
@@ -250,6 +251,133 @@ public class JdbcStatementSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * @throws Exception If failed.
+     */
+    public void testExecuteQueryMultipleOnlyResultSets() throws Exception {
+        assert conn.getMetaData().supportsMultipleResultSets();
+
+        int stmtCnt = 10;
+
+        StringBuilder sql = new StringBuilder();
+
+        for (int i = 0; i < stmtCnt; ++i)
+            sql.append("select ").append(i).append("; ");
+
+        assert stmt.execute(sql.toString());
+
+        for (int i = 0; i < stmtCnt; ++i) {
+            assert stmt.getMoreResults();
+
+            ResultSet rs = stmt.getResultSet();
+
+            assert rs.next();
+            assert rs.getInt(1) == i;
+            assert !rs.next();
+        }
+
+        assert !stmt.getMoreResults();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testExecuteQueryMultipleOnlyDml() throws Exception {
+        assert conn.getMetaData().supportsMultipleResultSets();
+
+        conn.setSchema(null);
+
+        int stmtCnt = 10;
+
+        StringBuilder sql = new StringBuilder(
+            "drop table if exists test; create table test(ID int primary key, NAME varchar(20)); ");
+
+        for (int i = 0; i < stmtCnt; ++i)
+            sql.append("insert into test (ID, NAME) values (" + i + ", 'name_" + i +"'); ");
+
+        assert !stmt.execute(sql.toString());
+
+        // DROP TABLE statement
+        assert stmt.getResultSet() == null;
+        assert stmt.getUpdateCount() == 0;
+
+        // CREATE TABLE statement
+        assert stmt.getResultSet() == null;
+        assert stmt.getUpdateCount() == 0;
+
+        for (int i = 0; i < stmtCnt; ++i) {
+            assert stmt.getMoreResults();
+
+            assert stmt.getResultSet() == null;
+            assert stmt.getUpdateCount() == 1;
+        }
+
+        assert !stmt.getMoreResults();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testExecuteQueryMultipleMixed() throws Exception {
+        assert conn.getMetaData().supportsMultipleResultSets();
+
+        conn.setSchema(null);
+
+        int stmtCnt = 10;
+
+        StringBuilder sql = new StringBuilder(
+            "drop table if exists test; create table test(ID int primary key, NAME varchar(20)); ");
+
+        for (int i = 0; i < stmtCnt; ++i) {
+            if (i % 2 == 0)
+                sql.append(" insert into test (ID, NAME) values (" + i + ", 'name_" + i + "'); ");
+            else
+                sql.append(" select * from test where id < " + i + "; ");
+        }
+
+        assert !stmt.execute(sql.toString());
+
+        // DROP TABLE statement
+        assert stmt.getResultSet() == null;
+        assert stmt.getUpdateCount() == 0;
+
+        // CREATE TABLE statement
+        assert stmt.getResultSet() == null;
+        assert stmt.getUpdateCount() == 0;
+
+        boolean notEmptyResult = false;
+
+        for (int i = 0; i < stmtCnt; ++i) {
+            assert stmt.getMoreResults();
+
+            if (i % 2 == 0) {
+                assert stmt.getResultSet() == null;
+                assert stmt.getUpdateCount() == 1;
+            }
+            else {
+                assert stmt.getUpdateCount() == -1;
+
+                ResultSet rs = stmt.getResultSet();
+
+                assert rs.getMetaData().getColumnCount() == 2;
+
+                int rowsCnt = 0;
+
+                while(rs.next())
+                    rowsCnt++;
+
+                assert rowsCnt <= (i + 1) / 2;
+
+                if (rowsCnt == (i + 1) / 2)
+                    notEmptyResult = true;
+            }
+        }
+
+        assert notEmptyResult;
+
+        assert !stmt.getMoreResults();
+    }
+
+    /**
      * Person.
      */
     @SuppressWarnings("UnusedDeclaration")

http://git-wip-us.apache.org/repos/asf/ignite/blob/df3c407f/modules/core/src/main/java/org/apache/ignite/IgniteJdbcDriver.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteJdbcDriver.java b/modules/core/src/main/java/org/apache/ignite/IgniteJdbcDriver.java
index f519589..b03e387 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteJdbcDriver.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteJdbcDriver.java
@@ -331,6 +331,9 @@ public class IgniteJdbcDriver implements Driver {
     /** Whether DML streaming will overwrite existing cache entries. */
     private static final String PARAM_STREAMING_ALLOW_OVERWRITE = "streamingAllowOverwrite";
 
+    /** Allow queries with multiple statements. */
+    private static final String PARAM_MULTIPLE_STMTS = "multipleStatementsAllowed";
+
     /** Hostname property name. */
     public static final String PROP_HOST = PROP_PREFIX + "host";
 
@@ -376,6 +379,9 @@ public class IgniteJdbcDriver implements Driver {
     /** Whether DML streaming will overwrite existing cache entries. */
     public static final String PROP_STREAMING_ALLOW_OVERWRITE = PROP_PREFIX + PARAM_STREAMING_ALLOW_OVERWRITE;
 
+    /** Allow query with multiple statements. */
+    public static final String PROP_MULTIPLE_STMTS = PROP_PREFIX + PARAM_MULTIPLE_STMTS;
+
     /** Cache name property name. */
     public static final String PROP_CFG = PROP_PREFIX + "cfg";
 
@@ -447,7 +453,8 @@ public class IgniteJdbcDriver implements Driver {
             new JdbcDriverPropertyInfo("Distributed Joins", info.getProperty(PROP_DISTRIBUTED_JOINS), ""),
             new JdbcDriverPropertyInfo("Enforce Join Order", info.getProperty(JdbcThinUtils.PROP_ENFORCE_JOIN_ORDER), ""),
             new JdbcDriverPropertyInfo("Lazy query execution", info.getProperty(JdbcThinUtils.PROP_LAZY), ""),
-            new JdbcDriverPropertyInfo("Transactions Allowed", info.getProperty(PROP_TX_ALLOWED), "")
+            new JdbcDriverPropertyInfo("Transactions Allowed", info.getProperty(PROP_TX_ALLOWED), ""),
+            new JdbcDriverPropertyInfo("Queries with multiple statements allowed", info.getProperty(PROP_MULTIPLE_STMTS), "")
         );
 
         if (info.getProperty(PROP_CFG) != null)

http://git-wip-us.apache.org/repos/asf/ignite/blob/df3c407f/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
index fde16ff..ccc09ec 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
@@ -80,6 +80,7 @@ import static org.apache.ignite.IgniteJdbcDriver.PROP_DISTRIBUTED_JOINS;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_ENFORCE_JOIN_ORDER;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_LAZY;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_LOCAL;
+import static org.apache.ignite.IgniteJdbcDriver.PROP_MULTIPLE_STMTS;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_NODE_ID;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_TX_ALLOWED;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_STREAMING;
@@ -164,6 +165,9 @@ public class JdbcConnection implements Connection {
     /** Allow overwrites for duplicate keys on streamed {@code INSERT}s. */
     private final boolean streamAllowOverwrite;
 
+    /** Allow queries with multiple statements. */
+    private final boolean multipleStmts;
+
     /** Statements. */
     final Set<JdbcStatement> statements = new HashSet<>();
 
@@ -204,6 +208,8 @@ public class JdbcConnection implements Connection {
         // by IgniteDataStreamer.DFLT_PARALLEL_OPS_MULTIPLIER will be used
         streamNodeParOps = Integer.parseInt(props.getProperty(PROP_STREAMING_PER_NODE_PAR_OPS, "0"));
 
+        multipleStmts = Boolean.parseBoolean(props.getProperty(PROP_MULTIPLE_STMTS));
+
         String nodeIdProp = props.getProperty(PROP_NODE_ID);
 
         if (nodeIdProp != null)
@@ -841,6 +847,13 @@ public class JdbcConnection implements Connection {
     }
 
     /**
+     * @return {@code true} if multiple statements allowed, {@code false} otherwise.
+     */
+    boolean isMultipleStatementsAllowed() {
+        return multipleStmts;
+    }
+
+    /**
      * @return Local query flag.
      */
     boolean isLocalQuery() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/df3c407f/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcDatabaseMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcDatabaseMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcDatabaseMetadata.java
index 03fde79..2fe24bb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcDatabaseMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcDatabaseMetadata.java
@@ -319,7 +319,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
     /** {@inheritDoc} */
     @Override public boolean supportsMultipleResultSets() {
-        return false;
+        return conn.isMultipleStatementsAllowed();
     }
 
     /** {@inheritDoc} */
@@ -675,7 +675,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getProcedures(String catalog, String schemaPtrn,
         String procedureNamePtrn) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Arrays.asList("PROCEDURE_CAT", "PROCEDURE_SCHEM", "PROCEDURE_NAME",
@@ -689,7 +689,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getProcedureColumns(String catalog, String schemaPtrn, String procedureNamePtrn,
         String colNamePtrn) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Arrays.asList("PROCEDURE_CAT", "PROCEDURE_SCHEM", "PROCEDURE_NAME",
@@ -725,7 +725,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             }
         }
 
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "TABLE_TYPE", "REMARKS", "TYPE_CAT",
@@ -766,7 +766,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
     /** {@inheritDoc} */
     @Override public ResultSet getCatalogs() throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.singletonList("TABLE_CAT"),
@@ -778,7 +778,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
     /** {@inheritDoc} */
     @Override public ResultSet getTableTypes() throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.singletonList("TABLE_TYPE"),
@@ -812,7 +812,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             }
         }
 
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "DATA_TYPE",
@@ -870,7 +870,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getColumnPrivileges(String catalog, String schema, String tbl,
         String colNamePtrn) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -883,7 +883,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getTablePrivileges(String catalog, String schemaPtrn,
         String tblNamePtrn) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -896,7 +896,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getBestRowIdentifier(String catalog, String schema, String tbl, int scope,
         boolean nullable) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -908,7 +908,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
     /** {@inheritDoc} */
     @Override public ResultSet getVersionColumns(String catalog, String schema, String tbl) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -936,7 +936,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             }
         }
 
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "KEY_SEQ", "PK_NAME"),
@@ -948,7 +948,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
     /** {@inheritDoc} */
     @Override public ResultSet getImportedKeys(String catalog, String schema, String tbl) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -960,7 +960,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
     /** {@inheritDoc} */
     @Override public ResultSet getExportedKeys(String catalog, String schema, String tbl) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -973,7 +973,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTbl,
         String foreignCatalog, String foreignSchema, String foreignTbl) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -985,7 +985,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
     /** {@inheritDoc} */
     @Override public ResultSet getTypeInfo() throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -1000,7 +1000,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
         boolean approximate) throws SQLException {
         updateMetaData();
 
-        Collection<List<?>> rows = new ArrayList<>(indexes.size());
+        List<List<?>> rows = new ArrayList<>(indexes.size());
 
         if (validCatalogPattern(catalog)) {
             for (List<Object> idx : indexes) {
@@ -1029,7 +1029,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             }
         }
 
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "NON_UNIQUE", "INDEX_QUALIFIER",
@@ -1106,7 +1106,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getUDTs(String catalog, String schemaPtrn, String typeNamePtrn,
         int[] types) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -1144,7 +1144,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getSuperTypes(String catalog, String schemaPtrn,
         String typeNamePtrn) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -1157,7 +1157,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getSuperTables(String catalog, String schemaPtrn,
         String tblNamePtrn) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -1170,7 +1170,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getAttributes(String catalog, String schemaPtrn, String typeNamePtrn,
         String attributeNamePtrn) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -1233,7 +1233,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             }
         }
 
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Arrays.asList("TABLE_SCHEM", "TABLE_CATALOG"),
@@ -1259,7 +1259,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
     /** {@inheritDoc} */
     @Override public ResultSet getClientInfoProperties() throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),
@@ -1272,7 +1272,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getFunctions(String catalog, String schemaPtrn,
         String functionNamePtrn) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Arrays.asList("FUNCTION_CAT", "FUNCTION_SCHEM", "FUNCTION_NAME",
@@ -1286,7 +1286,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getFunctionColumns(String catalog, String schemaPtrn, String functionNamePtrn,
         String colNamePtrn) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Arrays.asList("FUNCTION_CAT", "FUNCTION_SCHEM", "FUNCTION_NAME",
@@ -1305,7 +1305,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     /** {@inheritDoc} */
     @Override public ResultSet getPseudoColumns(String catalog, String schemaPtrn, String tblNamePtrn,
         String colNamePtrn) throws SQLException {
-        return new JdbcResultSet(null,
+        return new JdbcResultSet(true, null,
             conn.createStatement0(),
             Collections.<String>emptyList(),
             Collections.<String>emptyList(),

http://git-wip-us.apache.org/repos/asf/ignite/blob/df3c407f/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryMultipleStatementsTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryMultipleStatementsTask.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryMultipleStatementsTask.java
new file mode 100644
index 0000000..bf7c24e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryMultipleStatementsTask.java
@@ -0,0 +1,167 @@
+/*
+ * 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.jdbc2;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteJdbcDriver;
+import org.apache.ignite.cache.query.FieldsQueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.IgniteKernal;
+import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.lang.IgniteCallable;
+import org.apache.ignite.resources.IgniteInstanceResource;
+
+/**
+ * Task for SQL queries execution through {@link IgniteJdbcDriver}.
+ * The query can contains several SQL statements.
+ */
+class JdbcQueryMultipleStatementsTask implements IgniteCallable<List<JdbcStatementResultInfo>> {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /** Ignite. */
+    @IgniteInstanceResource
+    private Ignite ignite;
+
+    /** Schema name. */
+    private final String schemaName;
+
+    /** Sql. */
+    private final String sql;
+
+    /** Operation type flag - query or not. */
+    private Boolean isQry;
+
+    /** Args. */
+    private final Object[] args;
+
+    /** Fetch size. */
+    private final int fetchSize;
+
+    /** Local execution flag. */
+    private final boolean loc;
+
+    /** Local query flag. */
+    private final boolean locQry;
+
+    /** Collocated query flag. */
+    private final boolean collocatedQry;
+
+    /** Distributed joins flag. */
+    private final boolean distributedJoins;
+
+    /** Enforce join order flag. */
+    private final boolean enforceJoinOrder;
+
+    /** Lazy query execution flag. */
+    private final boolean lazy;
+
+    /**
+     * @param ignite Ignite.
+     * @param schemaName Schema name.
+     * @param sql Sql query.
+     * @param isQry Operation type flag - query or not - to enforce query type check.
+     * @param loc Local execution flag.
+     * @param args Args.
+     * @param fetchSize Fetch size.
+     * @param locQry Local query flag.
+     * @param collocatedQry Collocated query flag.
+     * @param distributedJoins Distributed joins flag.
+     * @param enforceJoinOrder Enforce joins order falg.
+     * @param lazy Lazy query execution flag.
+     */
+    public JdbcQueryMultipleStatementsTask(Ignite ignite, String schemaName, String sql, Boolean isQry, boolean loc,
+        Object[] args, int fetchSize, boolean locQry, boolean collocatedQry, boolean distributedJoins,
+        boolean enforceJoinOrder, boolean lazy) {
+        this.ignite = ignite;
+        this.args = args;
+        this.schemaName = schemaName;
+        this.sql = sql;
+        this.isQry = isQry;
+        this.fetchSize = fetchSize;
+        this.loc = loc;
+        this.locQry = locQry;
+        this.collocatedQry = collocatedQry;
+        this.distributedJoins = distributedJoins;
+        this.enforceJoinOrder = enforceJoinOrder;
+        this.lazy = lazy;
+    }
+
+    /** {@inheritDoc} */
+    @Override public List<JdbcStatementResultInfo> call() throws Exception {
+        SqlFieldsQuery qry = (isQry != null ? new JdbcSqlFieldsQuery(sql, isQry) : new SqlFieldsQuery(sql))
+            .setArgs(args);
+
+        qry.setPageSize(fetchSize);
+        qry.setLocal(locQry);
+        qry.setCollocated(collocatedQry);
+        qry.setDistributedJoins(distributedJoins);
+        qry.setEnforceJoinOrder(enforceJoinOrder);
+        qry.setLazy(lazy);
+        qry.setSchema(schemaName);
+
+        GridKernalContext ctx = ((IgniteKernal)ignite).context();
+
+        List<FieldsQueryCursor<List<?>>> curs = ctx.query().querySqlFieldsNoCache(qry, true, false);
+
+        List<JdbcStatementResultInfo> resultsInfo = new ArrayList<>(curs.size());
+
+        for (FieldsQueryCursor<List<?>> cur0 : curs) {
+            QueryCursorImpl<List<?>> cur = (QueryCursorImpl<List<?>>)cur0;
+
+            long updCnt = -1;
+
+            UUID qryId = null;
+
+            if (!cur.isQuery()) {
+                List<List<?>> items = cur.getAll();
+
+                assert items != null && items.size() == 1 && items.get(0).size() == 1
+                    && items.get(0).get(0) instanceof Long :
+                    "Invalid result set for not-SELECT query. [qry=" + sql +
+                        ", res=" + S.toString(List.class, items) + ']';
+
+                updCnt = (Long)items.get(0).get(0);
+
+                cur.close();
+            }
+            else {
+                qryId = UUID.randomUUID();
+
+                JdbcQueryTask.Cursor jdbcCur = new JdbcQueryTask.Cursor(cur, cur.iterator());
+
+                JdbcQueryTask.addCursor(qryId, jdbcCur);
+
+                if (!loc)
+                    JdbcQueryTask.scheduleRemoval(qryId);
+            }
+
+            JdbcStatementResultInfo resInfo = new JdbcStatementResultInfo(cur.isQuery(), qryId, updCnt);
+
+            resultsInfo.add(resInfo);
+        }
+
+        return resultsInfo;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df3c407f/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTask.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTask.java
index 4854129..ecbfb71 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTask.java
@@ -17,7 +17,6 @@
 
 package org.apache.ignite.internal.jdbc2;
 
-import java.io.Serializable;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -50,7 +49,7 @@ import org.apache.ignite.resources.IgniteInstanceResource;
  * This parameter can be configured via {@link IgniteSystemProperties#IGNITE_JDBC_DRIVER_CURSOR_REMOVE_DELAY}
  * system property.
  */
-class JdbcQueryTask implements IgniteCallable<JdbcQueryTask.QueryResult> {
+class JdbcQueryTask implements IgniteCallable<JdbcQueryTaskResult> {
     /** Serial version uid. */
     private static final long serialVersionUID = 0L;
 
@@ -132,7 +131,7 @@ class JdbcQueryTask implements IgniteCallable<JdbcQueryTask.QueryResult> {
     }
 
     /** {@inheritDoc} */
-    @Override public JdbcQueryTask.QueryResult call() throws Exception {
+    @Override public JdbcQueryTaskResult call() throws Exception {
         Cursor cursor = CURSORS.get(uuid);
 
         List<String> tbls = null;
@@ -173,7 +172,11 @@ class JdbcQueryTask implements IgniteCallable<JdbcQueryTask.QueryResult> {
             if (isQry == null)
                 isQry = qryCursor.isQuery();
 
-            Collection<GridQueryFieldMetadata> meta = qryCursor.fieldsMeta();
+            CURSORS.put(uuid, cursor = new Cursor(qryCursor, qryCursor.iterator()));
+        }
+
+        if (first || updateMetadata()) {
+            Collection<GridQueryFieldMetadata> meta = cursor.queryCursor().fieldsMeta();
 
             tbls = new ArrayList<>(meta.size());
             cols = new ArrayList<>(meta.size());
@@ -184,8 +187,6 @@ class JdbcQueryTask implements IgniteCallable<JdbcQueryTask.QueryResult> {
                 cols.add(desc.fieldName().toUpperCase());
                 types.add(desc.fieldTypeName());
             }
-
-            CURSORS.put(uuid, cursor = new Cursor(qryCursor, qryCursor.iterator()));
         }
 
         List<List<?>> rows = new ArrayList<>();
@@ -208,14 +209,14 @@ class JdbcQueryTask implements IgniteCallable<JdbcQueryTask.QueryResult> {
             remove(uuid, cursor);
         else if (first) {
             if (!loc)
-                scheduleRemoval(uuid, RMV_DELAY);
+                scheduleRemoval(uuid);
         }
         else if (!loc && !CURSORS.replace(uuid, cursor, new Cursor(cursor.cursor, cursor.iter)))
             assert !CURSORS.containsKey(uuid) : "Concurrent cursor modification.";
 
         assert isQry != null : "Query flag must be set prior to returning result";
 
-        return new QueryResult(uuid, finished, isQry, rows, cols, tbls, types);
+        return new JdbcQueryTaskResult(uuid, finished, isQry, rows, cols, tbls, types);
     }
 
     /**
@@ -233,14 +234,28 @@ class JdbcQueryTask implements IgniteCallable<JdbcQueryTask.QueryResult> {
     }
 
     /**
+     * @return Flag to update metadata on demand.
+     */
+    protected boolean updateMetadata() {
+        return false;
+    }
+
+    /**
      * Schedules removal of stored cursor in case of remote query execution.
      *
      * @param uuid Cursor UUID.
-     * @param delay Delay in milliseconds.
      */
-    private void scheduleRemoval(final UUID uuid, long delay) {
-        assert !loc;
+    static void scheduleRemoval(final UUID uuid) {
+        scheduleRemoval(uuid, RMV_DELAY);
+    }
 
+    /**
+     * Schedules removal of stored cursor in case of remote query execution.
+     *
+     * @param uuid Cursor UUID.
+     * @param delay Delay in milliseconds.
+     */
+    private static void scheduleRemoval(final UUID uuid, long delay) {
         SCHEDULER.schedule(new CAX() {
             @Override public void applyx() {
                 while (true) {
@@ -279,6 +294,14 @@ class JdbcQueryTask implements IgniteCallable<JdbcQueryTask.QueryResult> {
     }
 
     /**
+     * @param uuid Cursor UUID.
+     * @param c Cursor.
+     */
+    static void addCursor(UUID uuid, Cursor c) {
+        CURSORS.putIfAbsent(uuid, c);
+    }
+
+    /**
      * Closes and removes cursor.
      *
      * @param uuid Cursor UUID.
@@ -291,107 +314,9 @@ class JdbcQueryTask implements IgniteCallable<JdbcQueryTask.QueryResult> {
     }
 
     /**
-     * Result of query execution.
-     */
-    static class QueryResult implements Serializable {
-        /** Serial version uid. */
-        private static final long serialVersionUID = 0L;
-
-        /** Uuid. */
-        private final UUID uuid;
-
-        /** Finished. */
-        private final boolean finished;
-
-        /** Result type - query or update. */
-        private final boolean isQry;
-
-        /** Rows. */
-        private final List<List<?>> rows;
-
-        /** Tables. */
-        private final List<String> tbls;
-
-        /** Columns. */
-        private final List<String> cols;
-
-        /** Types. */
-        private final List<String> types;
-
-        /**
-         * @param uuid UUID..
-         * @param finished Finished.
-         * @param isQry
-         * @param rows Rows.
-         * @param cols Columns.
-         * @param tbls Tables.
-         * @param types Types.
-         */
-        public QueryResult(UUID uuid, boolean finished, boolean isQry, List<List<?>> rows, List<String> cols,
-            List<String> tbls, List<String> types) {
-            this.isQry = isQry;
-            this.cols = cols;
-            this.uuid = uuid;
-            this.finished = finished;
-            this.rows = rows;
-            this.tbls = tbls;
-            this.types = types;
-        }
-
-        /**
-         * @return Query result rows.
-         */
-        public List<List<?>> getRows() {
-            return rows;
-        }
-
-        /**
-         * @return Tables metadata.
-         */
-        public List<String> getTbls() {
-            return tbls;
-        }
-
-        /**
-         * @return Columns metadata.
-         */
-        public List<String> getCols() {
-            return cols;
-        }
-
-        /**
-         * @return Types metadata.
-         */
-        public List<String> getTypes() {
-            return types;
-        }
-
-        /**
-         * @return Query UUID.
-         */
-        public UUID getUuid() {
-            return uuid;
-        }
-
-        /**
-         * @return {@code True} if it is finished query.
-         */
-        public boolean isFinished() {
-            return finished;
-        }
-
-        /**
-         * @return {@code true} if it is result of a query operation, not update; {@code false} otherwise.
-         */
-        public boolean isQuery() {
-            return isQry;
-        }
-    }
-
-    /**
      * Cursor.
      */
-    private static final class Cursor implements Iterable<List<?>> {
+    static final class Cursor implements Iterable<List<?>> {
         /** Cursor. */
         final QueryCursor<List<?>> cursor;
 
@@ -405,7 +330,7 @@ class JdbcQueryTask implements IgniteCallable<JdbcQueryTask.QueryResult> {
          * @param cursor Cursor.
          * @param iter Iterator.
          */
-        private Cursor(QueryCursor<List<?>> cursor, Iterator<List<?>> iter) {
+        Cursor(QueryCursor<List<?>> cursor, Iterator<List<?>> iter) {
             this.cursor = cursor;
             this.iter = iter;
             this.lastAccessTime = U.currentTimeMillis();
@@ -422,5 +347,12 @@ class JdbcQueryTask implements IgniteCallable<JdbcQueryTask.QueryResult> {
         public boolean hasNext() {
             return iter.hasNext();
         }
+
+        /**
+         * @return Cursor.
+         */
+        public QueryCursorImpl<List<?>> queryCursor() {
+            return (QueryCursorImpl<List<?>>)cursor;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/df3c407f/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskResult.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskResult.java
new file mode 100644
index 0000000..607bb38
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskResult.java
@@ -0,0 +1,120 @@
+/*
+ * 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.jdbc2;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Result of query execution.
+ */
+class JdbcQueryTaskResult implements Serializable {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /** Uuid. */
+    private final UUID uuid;
+
+    /** Finished. */
+    private final boolean finished;
+
+    /** Result type - query or update. */
+    private final boolean isQry;
+
+    /** Rows. */
+    private final List<List<?>> rows;
+
+    /** Tables. */
+    private final List<String> tbls;
+
+    /** Columns. */
+    private final List<String> cols;
+
+    /** Types. */
+    private final List<String> types;
+
+    /**
+     * @param uuid UUID..
+     * @param finished Finished.
+     * @param isQry Is query flag.
+     * @param rows Rows.
+     * @param cols Columns.
+     * @param tbls Tables.
+     * @param types Types.
+     */
+    public JdbcQueryTaskResult(UUID uuid, boolean finished, boolean isQry, List<List<?>> rows, List<String> cols,
+        List<String> tbls, List<String> types) {
+        this.isQry = isQry;
+        this.cols = cols;
+        this.uuid = uuid;
+        this.finished = finished;
+        this.rows = rows;
+        this.tbls = tbls;
+        this.types = types;
+    }
+
+    /**
+     * @return Query result rows.
+     */
+    public List<List<?>> getRows() {
+        return rows;
+    }
+
+    /**
+     * @return Tables metadata.
+     */
+    public List<String> getTbls() {
+        return tbls;
+    }
+
+    /**
+     * @return Columns metadata.
+     */
+    public List<String> getCols() {
+        return cols;
+    }
+
+    /**
+     * @return Types metadata.
+     */
+    public List<String> getTypes() {
+        return types;
+    }
+
+    /**
+     * @return Query UUID.
+     */
+    public UUID getUuid() {
+        return uuid;
+    }
+
+    /**
+     * @return {@code True} if it is finished query.
+     */
+    public boolean isFinished() {
+        return finished;
+    }
+
+    /**
+     * @return {@code true} if it is result of a query operation, not update; {@code false} otherwise.
+     */
+    public boolean isQuery() {
+        return isQry;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df3c407f/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskV3.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskV3.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskV3.java
new file mode 100644
index 0000000..cb2d452
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskV3.java
@@ -0,0 +1,94 @@
+/*
+ * 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.jdbc2;
+
+import java.util.UUID;
+import org.apache.ignite.Ignite;
+
+/**
+ * Task for fetch results of multi-statement query.
+ */
+class JdbcQueryTaskV3 extends JdbcQueryTaskV2 {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /** Update metadata on demand flag. */
+    private final boolean updateMeta;
+
+    /**
+     * @param ignite Ignite.
+     * @param cacheName Cache name.
+     * @param schemaName Schema name.
+     * @param sql Sql query.
+     * @param isQry Operation type flag - query or not - to enforce query type check.
+     * @param loc Local execution flag.
+     * @param args Args.
+     * @param fetchSize Fetch size.
+     * @param uuid UUID.
+     * @param locQry Local query flag.
+     * @param collocatedQry Collocated query flag.
+     * @param distributedJoins Distributed joins flag.
+     * @param enforceJoinOrder Enforce joins order flag.
+     * @param lazy Lazy query execution flag.
+     * @param updateMeta Update metadata on demand.
+     */
+    public JdbcQueryTaskV3(Ignite ignite, String cacheName, String schemaName, String sql, Boolean isQry, boolean loc,
+        Object[] args, int fetchSize, UUID uuid, boolean locQry, boolean collocatedQry, boolean distributedJoins,
+        boolean enforceJoinOrder, boolean lazy, boolean updateMeta) {
+        super(ignite, cacheName, schemaName, sql, isQry, loc, args, fetchSize, uuid, locQry,
+            collocatedQry, distributedJoins, enforceJoinOrder, lazy);
+
+        this.updateMeta = updateMeta;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected boolean updateMetadata() {
+        return updateMeta;
+    }
+
+    /**
+     * @param ignite Ignite.
+     * @param cacheName Cache name.
+     * @param schemaName Schema name.
+     * @param sql Sql query.
+     * @param isQry Operation type flag - query or not - to enforce query type check.
+     * @param loc Local execution flag.
+     * @param args Args.
+     * @param fetchSize Fetch size.
+     * @param uuid UUID.
+     * @param locQry Local query flag.
+     * @param collocatedQry Collocated query flag.
+     * @param distributedJoins Distributed joins flag.
+     * @param enforceJoinOrder Enforce joins order flag.
+     * @param lazy Lazy query execution flag.
+     * @param updateMeta Update metadata on demand.
+     * @return Appropriate task JdbcQueryTask or JdbcQueryTaskV2.
+     */
+    public static JdbcQueryTask createTask(Ignite ignite, String cacheName, String schemaName, String sql,
+        Boolean isQry, boolean loc, Object[] args, int fetchSize, UUID uuid, boolean locQry,
+        boolean collocatedQry, boolean distributedJoins,
+        boolean enforceJoinOrder, boolean lazy, boolean updateMeta) {
+
+        if (updateMeta)
+            return new JdbcQueryTaskV3(ignite, cacheName, schemaName, sql, isQry, loc, args, fetchSize,
+                uuid, locQry, collocatedQry, distributedJoins, enforceJoinOrder, lazy, true);
+        else
+            return JdbcQueryTaskV2.createTask(ignite, cacheName, schemaName, sql, isQry, loc, args, fetchSize,
+                uuid, locQry, collocatedQry, distributedJoins, enforceJoinOrder, lazy);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/df3c407f/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
index 04b4041..69d4252 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
@@ -39,13 +39,14 @@ import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Calendar;
-import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.internal.processors.odbc.SqlStateCode;
+import org.apache.ignite.internal.util.typedef.F;
 import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.internal.jdbc2.JdbcUtils.convertToSqlException;
@@ -54,6 +55,12 @@ import static org.apache.ignite.internal.jdbc2.JdbcUtils.convertToSqlException;
  * JDBC result set implementation.
  */
 public class JdbcResultSet implements ResultSet {
+    /** Is query. */
+    private final boolean isQry;
+
+    /** Update count. */
+    private final long updCnt;
+
     /** Uuid. */
     private final UUID uuid;
 
@@ -61,13 +68,13 @@ public class JdbcResultSet implements ResultSet {
     private final JdbcStatement stmt;
 
     /** Table names. */
-    private final List<String> tbls;
+    private List<String> tbls;
 
     /** Column names. */
-    private final List<String> cols;
+    private List<String> cols;
 
     /** Class names. */
-    private final List<String> types;
+    private List<String> types;
 
     /** Rows cursor iterator. */
     private Iterator<List<?>> it;
@@ -93,6 +100,7 @@ public class JdbcResultSet implements ResultSet {
     /**
      * Creates new result set.
      *
+     * @param isQry Is query flag.
      * @param uuid Query UUID.
      * @param stmt Statement.
      * @param tbls Table names.
@@ -100,26 +108,56 @@ public class JdbcResultSet implements ResultSet {
      * @param types Types.
      * @param fields Fields.
      * @param finished Result set finished flag (the last result set).
+     * @throws SQLException On error.
      */
-    JdbcResultSet(@Nullable UUID uuid, JdbcStatement stmt, List<String> tbls, List<String> cols,
-        List<String> types, Collection<List<?>> fields, boolean finished) {
-        assert stmt != null;
-        assert tbls != null;
-        assert cols != null;
-        assert types != null;
-        assert fields != null;
-
-        this.uuid = uuid;
+    JdbcResultSet(boolean isQry, @Nullable UUID uuid, JdbcStatement stmt, List<String> tbls, List<String> cols,
+        List<String> types, List<List<?>> fields, boolean finished) throws SQLException {
+        this.isQry = isQry;
         this.stmt = stmt;
-        this.tbls = tbls;
-        this.cols = cols;
-        this.types = types;
-        this.finished = finished;
 
-        this.it = fields.iterator();
+        if (isQry) {
+            this.uuid = uuid;
+            updCnt = -1;
+            this.tbls = tbls;
+            this.cols = cols;
+            this.types = types;
+            this.finished = finished;
+
+            if (fields != null)
+                it = fields.iterator();
+            else
+                it = Collections.emptyIterator();
+        }
+        else {
+            updCnt = updateCounterFromQueryResult(fields);
+
+            this.uuid = null;
+            this.tbls = null;
+            this.cols = null;
+            this.types = null;
+            this.finished = true;
+            it = null;
+        }
     }
 
-    /** {@inheritDoc} */
+    /**
+     * @param stmt Statement.
+     * @param updCnt Update count.
+     */
+    JdbcResultSet(JdbcStatement stmt, long updCnt) {
+        isQry = false;
+        this.updCnt = updCnt;
+        this.stmt = stmt;
+
+        uuid = null;
+        tbls = null;
+        cols = null;
+        types = null;
+        finished = true;
+        it = null;
+    }
+
+        /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
     @Override public boolean next() throws SQLException {
         ensureNotClosed();
@@ -140,37 +178,52 @@ public class JdbcResultSet implements ResultSet {
             return true;
         }
         else if (!finished) {
-            JdbcConnection conn = (JdbcConnection)stmt.getConnection();
+            fetchPage();
 
-            Ignite ignite = conn.ignite();
+            return next();
+        }
 
-            UUID nodeId = conn.nodeId();
+        it = null;
 
-            boolean loc = nodeId == null;
+        return false;
+    }
 
-            // Connections from new clients send queries with new tasks, so we have to continue in the same manner
-            JdbcQueryTask qryTask = JdbcQueryTaskV2.createTask(loc ? ignite : null, conn.cacheName(), conn.schemaName(),
-                null,true, loc, null, fetchSize, uuid, conn.isLocalQuery(), conn.isCollocatedQuery(),
-                    conn.isDistributedJoins(), conn.isEnforceJoinOrder(), conn.isLazy());
+    /**
+     *
+     */
+    private void fetchPage() throws SQLException {
+        JdbcConnection conn = (JdbcConnection)stmt.getConnection();
 
-            try {
-                JdbcQueryTask.QueryResult res =
-                    loc ? qryTask.call() : ignite.compute(ignite.cluster().forNodeId(nodeId)).call(qryTask);
+        Ignite ignite = conn.ignite();
 
-                finished = res.isFinished();
+        UUID nodeId = conn.nodeId();
 
-                it = res.getRows().iterator();
+        boolean loc = nodeId == null;
 
-                return next();
-            }
-            catch (Exception e) {
-                throw convertToSqlException(e, "Failed to query Ignite.");
-            }
-        }
+        boolean updateMetadata = tbls == null;
 
-        it = null;
+        // Connections from new clients send queries with new tasks, so we have to continue in the same manner
+        JdbcQueryTask qryTask = JdbcQueryTaskV3.createTask(loc ? ignite : null, conn.cacheName(), conn.schemaName(),
+            null,true, loc, null, fetchSize, uuid, conn.isLocalQuery(), conn.isCollocatedQuery(),
+            conn.isDistributedJoins(), conn.isEnforceJoinOrder(), conn.isLazy(), updateMetadata);
 
-        return false;
+        try {
+            JdbcQueryTaskResult res =
+                loc ? qryTask.call() : ignite.compute(ignite.cluster().forNodeId(nodeId)).call(qryTask);
+
+            finished = res.isFinished();
+
+            it = res.getRows().iterator();
+
+            if (updateMetadata) {
+                tbls = res.getTbls();
+                cols = res.getCols();
+                types = res.getTypes();
+            }
+        }
+        catch (Exception e) {
+            throw convertToSqlException(e, "Failed to query Ignite.");
+        }
     }
 
     /** {@inheritDoc} */
@@ -421,6 +474,9 @@ public class JdbcResultSet implements ResultSet {
     @Override public ResultSetMetaData getMetaData() throws SQLException {
         ensureNotClosed();
 
+        if (tbls == null)
+            fetchPage();
+
         return new JdbcResultSetMetadata(tbls, cols, types);
     }
 
@@ -1523,4 +1579,43 @@ public class JdbcResultSet implements ResultSet {
         if (curr == null)
             throw new SQLException("Result set is not positioned on a row.");
     }
+
+    /**
+     * @return Is Query flag.
+     */
+    public boolean isQuery() {
+        return isQry;
+    }
+
+    /**
+     * @return Update count.
+     */
+    public long updateCount() {
+        return updCnt;
+    }
+
+    /**
+     * @param rows query result.
+     * @return update counter, if found.
+     * @throws SQLException if getting an update counter from result proved to be impossible.
+     */
+    private static long updateCounterFromQueryResult(List<List<?>> rows) throws SQLException {
+        if (F.isEmpty(rows))
+            return -1;
+
+        if (rows.size() != 1)
+            throw new SQLException("Expected fetch size of 1 for update operation.");
+
+        List<?> row = rows.get(0);
+
+        if (row.size() != 1)
+            throw new SQLException("Expected row size of 1 for update operation.");
+
+        Object objRes = row.get(0);
+
+        if (!(objRes instanceof Long))
+            throw new SQLException("Unexpected update result type.");
+
+        return (Long)objRes;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/df3c407f/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement.java
index a94b8fd..acac123 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement.java
@@ -24,6 +24,7 @@ import java.sql.SQLFeatureNotSupportedException;
 import java.sql.SQLWarning;
 import java.sql.Statement;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -57,9 +58,6 @@ public class JdbcStatement implements Statement {
     /** Rows limit. */
     private int maxRows;
 
-    /** Current result set. */
-    protected ResultSet rs;
-
     /** Query arguments. */
     protected ArrayList<Object> args;
 
@@ -72,12 +70,15 @@ public class JdbcStatement implements Statement {
     /** Fields indexes. */
     Map<String, Integer> fieldsIdxs = new HashMap<>();
 
-    /** Current updated items count. */
-    long updateCnt = -1;
-
     /** Batch of statements. */
     private List<String> batch;
 
+    /** Results. */
+    protected List<JdbcResultSet> results;
+
+    /** Current result set index. */
+    protected int curRes = 0;
+
     /**
      * Creates new statement.
      *
@@ -92,11 +93,20 @@ public class JdbcStatement implements Statement {
     /** {@inheritDoc} */
     @SuppressWarnings("deprecation")
     @Override public ResultSet executeQuery(String sql) throws SQLException {
-        ensureNotClosed();
+        execute0(sql, true);
 
-        rs = null;
+        return getResultSet();
+    }
 
-        updateCnt = -1;
+    /**
+     * @param sql SQL query.
+     * @param isQuery Expected type of statements are contained in the query.
+     * @throws SQLException On error.
+     */
+    private void executeMultipleStatement(String sql, Boolean isQuery) throws SQLException {
+        ensureNotClosed();
+
+        closeResults();
 
         if (F.isEmpty(sql))
             throw new SQLException("SQL query is empty");
@@ -105,53 +115,37 @@ public class JdbcStatement implements Statement {
 
         UUID nodeId = conn.nodeId();
 
-        UUID uuid = UUID.randomUUID();
-
         boolean loc = nodeId == null;
 
-        JdbcQueryTask qryTask = JdbcQueryTaskV2.createTask(loc ? ignite : null, conn.cacheName(), conn.schemaName(),
-            sql, true, loc, getArgs(), fetchSize, uuid, conn.isLocalQuery(), conn.isCollocatedQuery(),
+        JdbcQueryMultipleStatementsTask qryTask = new JdbcQueryMultipleStatementsTask(loc ? ignite : null, conn.schemaName(),
+            sql, isQuery, loc, getArgs(), fetchSize, conn.isLocalQuery(), conn.isCollocatedQuery(),
             conn.isDistributedJoins(), conn.isEnforceJoinOrder(), conn.isLazy());
 
         try {
-            JdbcQueryTask.QueryResult res =
+            List<JdbcStatementResultInfo> rsInfos =
                 loc ? qryTask.call() : ignite.compute(ignite.cluster().forNodeId(nodeId)).call(qryTask);
 
-            JdbcResultSet rs = new JdbcResultSet(uuid, this, res.getTbls(), res.getCols(), res.getTypes(),
-                res.getRows(), res.isFinished());
+            results = new ArrayList<>(rsInfos.size());
 
-            rs.setFetchSize(fetchSize);
-
-            resSets.add(rs);
-
-            return rs;
+            for (JdbcStatementResultInfo rsInfo : rsInfos) {
+                if (rsInfo.isQuery())
+                    results.add(new JdbcResultSet(true, rsInfo.queryId(), this, null, null, null, null, false));
+                else
+                    results.add(new JdbcResultSet(this, rsInfo.updateCount()));
+            }
         }
         catch (Exception e) {
             throw convertToSqlException(e, "Failed to query Ignite.");
         }
     }
 
-    /** {@inheritDoc} */
-    @Override public int executeUpdate(String sql) throws SQLException {
-        ensureNotClosed();
-
-        rs = null;
-
-        updateCnt = -1;
-
-        return Long.valueOf(doUpdate(sql, getArgs())).intValue();
-    }
-
     /**
-     * Run update query.
      * @param sql SQL query.
-     * @param args Update arguments.
-     * @return Number of affected items.
-     * @throws SQLException If failed.
+     * @param isQuery Expected type of statements are contained in the query.
+     * @throws SQLException On error.
      */
-    long doUpdate(String sql, Object[] args) throws SQLException {
-        if (F.isEmpty(sql))
-            throw new SQLException("SQL query is empty");
+    private void executeSingle(String sql, Boolean isQuery) throws SQLException {
+        ensureNotClosed();
 
         Ignite ignite = conn.ignite();
 
@@ -162,46 +156,50 @@ public class JdbcStatement implements Statement {
         boolean loc = nodeId == null;
 
         if (!conn.isDmlSupported())
-            throw new SQLException("Failed to query Ignite: DML operations are supported in versions 1.8.0 and newer");
+            if(isQuery != null && !isQuery)
+                throw new SQLException("Failed to query Ignite: DML operations are supported in versions 1.8.0 and newer");
+            else
+                isQuery = true;
 
         JdbcQueryTask qryTask = JdbcQueryTaskV2.createTask(loc ? ignite : null, conn.cacheName(), conn.schemaName(),
-            sql, false, loc, args, fetchSize, uuid, conn.isLocalQuery(), conn.isCollocatedQuery(),
+            sql, isQuery, loc, getArgs(), fetchSize, uuid, conn.isLocalQuery(), conn.isCollocatedQuery(),
             conn.isDistributedJoins(), conn.isEnforceJoinOrder(), conn.isLazy());
 
         try {
-            JdbcQueryTask.QueryResult qryRes =
+            JdbcQueryTaskResult qryRes =
                 loc ? qryTask.call() : ignite.compute(ignite.cluster().forNodeId(nodeId)).call(qryTask);
 
-            return updateCnt = updateCounterFromQueryResult(qryRes.getRows());
+            JdbcResultSet rs = new JdbcResultSet(qryRes.isQuery(), uuid, this, qryRes.getTbls(), qryRes.getCols(),
+                qryRes.getTypes(), qryRes.getRows(), qryRes.isFinished());
+
+            rs.setFetchSize(fetchSize);
+
+            results = Collections.singletonList(rs);
+            curRes = 0;
         }
         catch (Exception e) {
             throw convertToSqlException(e, "Failed to query Ignite.");
         }
+
     }
 
     /**
-     * @param rows query result.
-     * @return update counter, if found.
-     * @throws SQLException if getting an update counter from result proved to be impossible.
+     * @param sql SQL query.
+     * @param isQuery Expected type of statements are contained in the query.
+     * @throws SQLException On error.
      */
-    private static long updateCounterFromQueryResult(List<List<?>> rows) throws SQLException {
-         if (F.isEmpty(rows))
-            return -1;
-
-        if (rows.size() != 1)
-            throw new SQLException("Expected fetch size of 1 for update operation");
-
-        List<?> row = rows.get(0);
-
-        if (row.size() != 1)
-            throw new SQLException("Expected row size of 1 for update operation");
-
-        Object objRes = row.get(0);
+    protected void execute0(String sql, Boolean isQuery) throws SQLException {
+        if (conn.isMultipleStatementsAllowed())
+            executeMultipleStatement(sql, isQuery);
+        else
+            executeSingle(sql, isQuery);
+    }
 
-        if (!(objRes instanceof Long))
-            throw new SQLException("Unexpected update result type");
+    /** {@inheritDoc} */
+    @Override public int executeUpdate(String sql) throws SQLException {
+        execute0(sql, false);
 
-        return (Long)objRes;
+        return getUpdateCount();
     }
 
     /** {@inheritDoc} */
@@ -302,86 +300,48 @@ public class JdbcStatement implements Statement {
 
     /** {@inheritDoc} */
     @Override public boolean execute(String sql) throws SQLException {
-        if (!conn.isDmlSupported()) {
-            // We attempt to run a query without any checks as long as server does not support DML anyway,
-            // so it simply will throw an exception when given a DML statement instead of a query.
-            rs = executeQuery(sql);
-
-            return true;
-        }
-
-        ensureNotClosed();
-
-        rs = null;
-
-        updateCnt = -1;
-
-        if (F.isEmpty(sql))
-            throw new SQLException("SQL query is empty");
-
-        Ignite ignite = conn.ignite();
+        execute0(sql, null);
 
-        UUID nodeId = conn.nodeId();
-
-        UUID uuid = UUID.randomUUID();
-
-        boolean loc = nodeId == null;
-
-        JdbcQueryTask qryTask = JdbcQueryTaskV2.createTask(loc ? ignite : null, conn.cacheName(), conn.schemaName(),
-            sql, null, loc, getArgs(), fetchSize, uuid, conn.isLocalQuery(), conn.isCollocatedQuery(),
-            conn.isDistributedJoins(), conn.isEnforceJoinOrder(), conn.isLazy());
-
-        try {
-            JdbcQueryTask.QueryResult res =
-                loc ? qryTask.call() : ignite.compute(ignite.cluster().forNodeId(nodeId)).call(qryTask);
-
-            if (res.isQuery()) {
-                JdbcResultSet rs = new JdbcResultSet(uuid, this, res.getTbls(), res.getCols(),
-                    res.getTypes(), res.getRows(), res.isFinished());
-
-                rs.setFetchSize(fetchSize);
-
-                resSets.add(rs);
-
-                this.rs = rs;
-            }
-            else
-                updateCnt = updateCounterFromQueryResult(res.getRows());
-
-            return res.isQuery();
-        }
-        catch (Exception e) {
-            throw convertToSqlException(e, "Failed to query Ignite.");
-        }
+        return results.get(0).isQuery();
     }
 
     /** {@inheritDoc} */
     @Override public ResultSet getResultSet() throws SQLException {
-        ensureNotClosed();
+        JdbcResultSet rs = nextResultSet();
 
-        ResultSet rs0 = rs;
+        if (rs == null)
+            return null;
 
-        rs = null;
+        if (!rs.isQuery()) {
+            curRes--;
 
-        return rs0;
+            return null;
+        }
+
+        return rs;
     }
 
     /** {@inheritDoc} */
     @Override public int getUpdateCount() throws SQLException {
-        ensureNotClosed();
+        JdbcResultSet rs = nextResultSet();
 
-        long res = updateCnt;
+        if (rs == null)
+            return -1;
 
-        updateCnt = -1;
+        if (rs.isQuery()) {
+            curRes--;
+
+            return -1;
+        }
 
-        return Long.valueOf(res).intValue();
+        return (int)rs.updateCount();
     }
 
     /** {@inheritDoc} */
     @Override public boolean getMoreResults() throws SQLException {
         ensureNotClosed();
 
-        return false;
+        return getMoreResults(CLOSE_CURRENT_RESULT);
     }
 
     /** {@inheritDoc} */
@@ -472,9 +432,8 @@ public class JdbcStatement implements Statement {
      */
     protected int[] doBatchUpdate(String command, List<String> batch, List<List<Object>> batchArgs)
         throws SQLException {
-        rs = null;
 
-        updateCnt = -1;
+        closeResults();
 
         if ((F.isEmpty(command) || F.isEmpty(batchArgs)) && F.isEmpty(batch))
             throw new SQLException("Batch is empty.");
@@ -495,7 +454,11 @@ public class JdbcStatement implements Statement {
         try {
             int[] res = loc ? task.call() : ignite.compute(ignite.cluster().forNodeId(nodeId)).call(task);
 
-            updateCnt = F.isEmpty(res)? -1 : res[res.length - 1];
+            long updateCnt = F.isEmpty(res)? -1 : res[res.length - 1];
+
+            results = Collections.singletonList(new JdbcResultSet(this, updateCnt));
+
+            curRes = 0;
 
             return res;
         }
@@ -515,10 +478,32 @@ public class JdbcStatement implements Statement {
     @Override public boolean getMoreResults(int curr) throws SQLException {
         ensureNotClosed();
 
-        if (curr == KEEP_CURRENT_RESULT || curr == CLOSE_ALL_RESULTS)
-            throw new SQLFeatureNotSupportedException("Multiple open results are not supported.");
+        if (results != null) {
+            assert curRes <= results.size() : "Invalid results state: [resultsCount=" + results.size() +
+                ", curRes=" + curRes + ']';
 
-        return false;
+            switch (curr) {
+                case CLOSE_CURRENT_RESULT:
+                    if (curRes > 0)
+                        results.get(curRes - 1).close();
+
+                    break;
+
+                case CLOSE_ALL_RESULTS:
+                    for (int i = 0; i < curRes; ++i)
+                        results.get(i).close();
+
+                    break;
+
+                case KEEP_CURRENT_RESULT:
+                    break;
+
+                default:
+                    throw new SQLException("Invalid 'current' parameter.");
+            }
+        }
+
+        return (results != null && curRes < results.size());
     }
 
     /** {@inheritDoc} */
@@ -657,4 +642,35 @@ public class JdbcStatement implements Statement {
         if (closed)
             throw new SQLException("Connection is closed.", SqlStateCode.CONNECTION_CLOSED);
     }
+
+    /**
+     * Get last result set if any.
+     *
+     * @return Result set or null.
+     * @throws SQLException If failed.
+     */
+    private JdbcResultSet nextResultSet() throws SQLException {
+        ensureNotClosed();
+
+        if (results == null || curRes >= results.size())
+            return null;
+        else
+            return results.get(curRes++);
+    }
+
+    /**
+     * Close results.
+     *
+     * @throws SQLException On error.
+     */
+    private void closeResults() throws SQLException {
+        if (results != null) {
+            for (JdbcResultSet rs : results)
+                rs.close();
+
+            results = null;
+            curRes = 0;
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/df3c407f/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatementResultInfo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatementResultInfo.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatementResultInfo.java
new file mode 100644
index 0000000..8aa02f1
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatementResultInfo.java
@@ -0,0 +1,73 @@
+/*
+ * 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.jdbc2;
+
+import java.util.UUID;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC statement result information. Keeps statement type (SELECT or UPDATE) and
+ * queryId or update count (depends on statement type).
+ */
+public class JdbcStatementResultInfo {
+    /** Query flag. */
+    private boolean isQuery;
+
+    /** Update count. */
+    private long updCnt;
+
+    /** Query ID. */
+    private UUID qryId;
+
+    /**
+     * @param isQuery Query flag.
+     * @param qryId Query ID.
+     * @param updCnt Update count.
+     */
+    public JdbcStatementResultInfo(boolean isQuery, UUID qryId, long updCnt) {
+        this.isQuery = isQuery;
+        this.updCnt = updCnt;
+        this.qryId = qryId;
+    }
+
+    /**
+     * @return Query flag.
+     */
+    public boolean isQuery() {
+        return isQuery;
+    }
+
+    /**
+     * @return Query ID.
+     */
+    public UUID queryId() {
+        return qryId;
+    }
+
+    /**
+     * @return Update count.
+     */
+    public long updateCount() {
+        return updCnt;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcStatementResultInfo.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df3c407f/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStreamedPreparedStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStreamedPreparedStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStreamedPreparedStatement.java
index 9f76700..408f089 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStreamedPreparedStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStreamedPreparedStatement.java
@@ -19,8 +19,8 @@ package org.apache.ignite.internal.jdbc2;
 
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
+import java.util.Collections;
 import org.apache.ignite.IgniteDataStreamer;
-import org.apache.ignite.internal.IgniteEx;
 
 /**
  * Prepared statement associated with a data streamer.
@@ -33,8 +33,9 @@ class JdbcStreamedPreparedStatement extends JdbcPreparedStatement {
      * Creates new prepared statement.
      *
      * @param conn Connection.
-     * @param sql  SQL query.
+     * @param sql SQL query.
      * @param streamer Data streamer to use with this statement. Will be closed on statement close.
+     * @param nativeStmt Native statement.
      */
     JdbcStreamedPreparedStatement(JdbcConnection conn, String sql, IgniteDataStreamer<?, ?> streamer,
         PreparedStatement nativeStmt) {
@@ -53,8 +54,16 @@ class JdbcStreamedPreparedStatement extends JdbcPreparedStatement {
     }
 
     /** {@inheritDoc} */
-    @Override long doUpdate(String sql, Object[] args) throws SQLException {
-        return conn.ignite().context().query().streamUpdateQuery(conn.cacheName(), conn.schemaName(),
-            streamer, sql, args);
+    @Override protected void execute0(String sql, Boolean isQuery) throws SQLException {
+        assert isQuery != null && !isQuery;
+
+        long updCnt = conn.ignite().context().query().streamUpdateQuery(conn.cacheName(), conn.schemaName(),
+            streamer, sql, getArgs());
+
+        JdbcResultSet rs = new JdbcResultSet(this, updCnt);
+
+        results = Collections.singletonList(rs);
+
+        curRes = 0;
     }
 }


[34/50] [abbrv] ignite git commit: IGNITE-6539 WAL parser fails if empty log files exist in directory - Fixes #2794.

Posted by ag...@apache.org.
IGNITE-6539 WAL parser fails if empty log files exist in directory - Fixes #2794.

Signed-off-by: Alexey Goncharuk <al...@gmail.com>


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

Branch: refs/heads/ignite-6305
Commit: 474479c3f624c3a3c67b6ae549a566caac1f6b1c
Parents: 3b1cad2
Author: dpavlov <dp...@gridgain.com>
Authored: Thu Oct 5 18:06:27 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Oct 5 18:06:27 2017 +0300

----------------------------------------------------------------------
 .../reader/StandaloneWalRecordsIterator.java    | 24 ++++--
 .../db/wal/reader/IgniteWalReaderTest.java      | 89 ++++++++++++++++++++
 2 files changed, 104 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/474479c3/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
index 24b2148..42bb410 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
@@ -45,10 +45,10 @@ import org.apache.ignite.internal.processors.cache.persistence.wal.ByteBufferExp
 import org.apache.ignite.internal.processors.cache.persistence.wal.FileInput;
 import org.apache.ignite.internal.processors.cache.persistence.wal.FileWALPointer;
 import org.apache.ignite.internal.processors.cache.persistence.wal.FileWriteAheadLogManager;
-import org.apache.ignite.internal.processors.cache.persistence.wal.SegmentEofException;
 import org.apache.ignite.internal.processors.cache.persistence.wal.serializer.RecordV1Serializer;
 import org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor;
 import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.U;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -185,12 +185,11 @@ class StandaloneWalRecordsIterator extends AbstractWalRecordsIterator {
      * Header record and its position is checked. WAL position is used to determine real index.
      * File index from file name is ignored.
      *
-     * @param allFiles files to scan
-     * @return list of file descriptors with checked header records, file index is set
-     * @throws IgniteCheckedException if IO error occurs
+     * @param allFiles files to scan.
+     * @return list of file descriptors with checked header records, having correct file index is set
      */
     private List<FileWriteAheadLogManager.FileDescriptor> scanIndexesFromFileHeaders(
-        @Nullable final File[] allFiles) throws IgniteCheckedException {
+        @Nullable final File[] allFiles) {
         if (allFiles == null || allFiles.length == 0)
             return Collections.emptyList();
 
@@ -198,7 +197,7 @@ class StandaloneWalRecordsIterator extends AbstractWalRecordsIterator {
 
         for (File file : allFiles) {
             if (file.length() < HEADER_RECORD_SIZE)
-                continue;
+                continue;  //filter out this segment as it is too short
 
             FileWALPointer ptr;
 
@@ -211,17 +210,24 @@ class StandaloneWalRecordsIterator extends AbstractWalRecordsIterator {
                 // Header record must be agnostic to the serializer version.
                 final int type = in.readUnsignedByte();
 
-                if (type == WALRecord.RecordType.STOP_ITERATION_RECORD_TYPE)
-                    throw new SegmentEofException("Reached logical end of the segment", null);
+                if (type == WALRecord.RecordType.STOP_ITERATION_RECORD_TYPE) {
+                    if (log.isInfoEnabled())
+                        log.info("Reached logical end of the segment for file " + file);
+
+                    continue; //filter out this segment
+                }
                 ptr = RecordV1Serializer.readPosition(in);
             }
             catch (IOException e) {
-                throw new IgniteCheckedException("Failed to scan index from file [" + file + "]", e);
+                U.warn(log, "Failed to scan index from file [" + file + "]. Skipping this file during iteration", e);
+
+                continue; //filter out this segment
             }
 
             resultingDescs.add(new FileWriteAheadLogManager.FileDescriptor(file, ptr.index()));
         }
         Collections.sort(resultingDescs);
+
         return resultingDescs;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/474479c3/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
index 6db2784..93df8b2 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
@@ -75,6 +75,7 @@ import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.transactions.Transaction;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.junit.Assert;
 
 import static org.apache.ignite.events.EventType.EVT_WAL_SEGMENT_ARCHIVED;
 import static org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE;
@@ -340,6 +341,22 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Puts provided number of records to fill WAL
+     *
+     * @param ignite ignite instance
+     * @param recordsToWrite count
+     */
+    private void putAllDummyRecords(Ignite ignite, int recordsToWrite) {
+        IgniteCache<Object, Object> cache0 = ignite.cache(CACHE_NAME);
+
+        Map<Object, Object> values = new HashMap<>();
+
+        for (int i = 0; i < recordsToWrite; i++)
+            values.put(i, new IndexedObject(i));
+
+        cache0.putAll(values);
+    }
+    /**
      * Puts provided number of records to fill WAL under transactions
      *
      * @param ignite ignite instance
@@ -715,6 +732,78 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Tests archive completed event is fired
+     *
+     * @throws Exception if failed
+     */
+    public void testFillWalForExactSegmentsCount() throws Exception {
+        customWalMode = WALMode.DEFAULT;
+
+        final CountDownLatch reqSegments = new CountDownLatch(15);
+        final Ignite ignite = startGrid("node0");
+
+        ignite.active(true);
+
+        final IgniteEvents evts = ignite.events();
+
+        if (!evts.isEnabled(EVT_WAL_SEGMENT_ARCHIVED))
+            assertTrue("nothing to test", false);
+
+        evts.localListen(new IgnitePredicate<Event>() {
+            @Override public boolean apply(Event e) {
+                WalSegmentArchivedEvent archComplEvt = (WalSegmentArchivedEvent)e;
+                long idx = archComplEvt.getAbsWalSegmentIdx();
+                log.info("Finished archive for segment [" + idx + ", " +
+                    archComplEvt.getArchiveFile() + "]: [" + e + "]");
+
+                reqSegments.countDown();
+                return true;
+            }
+        }, EVT_WAL_SEGMENT_ARCHIVED);
+
+
+        int totalEntries = 0;
+        while (reqSegments.getCount() > 0) {
+            final int write = 500;
+            putAllDummyRecords(ignite, write);
+            totalEntries += write;
+            Assert.assertTrue("Too much entries generated, but segments was not become available",
+                totalEntries < 10000);
+        }
+        final String subfolderName = genDbSubfolderName(ignite, 0);
+
+        stopGrid("node0");
+
+        final String workDir = U.defaultWorkDirectory();
+        final IgniteWalIteratorFactory factory = createWalIteratorFactory(subfolderName, workDir);
+
+        scanIterateAndCount(factory, workDir, subfolderName, totalEntries, 0, null, null);
+    }
+
+    /**
+     * Tests reading of empty WAL from non filled cluster
+     *
+     * @throws Exception if failed.
+     */
+    public void testReadEmptyWal() throws Exception {
+        customWalMode = WALMode.DEFAULT;
+
+        final Ignite ignite = startGrid("node0");
+
+        ignite.active(true);
+        ignite.active(false);
+
+        final String subfolderName = genDbSubfolderName(ignite, 0);
+
+        stopGrid("node0");
+
+        final String workDir = U.defaultWorkDirectory();
+        final IgniteWalIteratorFactory factory = createWalIteratorFactory(subfolderName, workDir);
+
+        scanIterateAndCount(factory, workDir, subfolderName, 0, 0, null, null);
+    }
+
+    /**
      * Creates and fills cache with data.
      *
      * @param ig Ignite instance.


[37/50] [abbrv] ignite git commit: IGNITE-5224 .NET: PadLeft and PadRight support in LINQ

Posted by ag...@apache.org.
IGNITE-5224 .NET: PadLeft and PadRight support in LINQ

This closes #2808


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

Branch: refs/heads/ignite-6305
Commit: e5c25b444ae605f0b76289f5c8466c850a26e344
Parents: 2410f07
Author: Alexey Popov <ta...@gmail.com>
Authored: Fri Oct 6 12:18:38 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Oct 6 12:18:38 2017 +0300

----------------------------------------------------------------------
 .../Cache/Query/Linq/CacheLinqTest.Strings.cs                   | 5 +++++
 .../platforms/dotnet/Apache.Ignite.Linq/Impl/MethodVisitor.cs   | 4 ++++
 2 files changed, 9 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e5c25b44/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Strings.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Strings.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Strings.cs
index 7457d0a..1139c4d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Strings.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Strings.cs
@@ -46,6 +46,11 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Linq
         {
             var strings = GetSecondPersonCache().AsCacheQueryable().Select(x => x.Value.Name);
 
+            CheckFunc(x => x.PadLeft(20), strings);
+            CheckFunc(x => x.PadLeft(20, 'l'), strings);
+            CheckFunc(x => x.PadRight(20), strings);
+            CheckFunc(x => x.PadRight(20, 'r'), strings);
+
             CheckFunc(x => x.ToLower(), strings);
             CheckFunc(x => x.ToUpper(), strings);
             CheckFunc(x => x.StartsWith("Person_9"), strings);

http://git-wip-us.apache.org/repos/asf/ignite/blob/e5c25b44/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/MethodVisitor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/MethodVisitor.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/MethodVisitor.cs
index 9446af3..8abf2a6 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/MethodVisitor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/MethodVisitor.cs
@@ -66,6 +66,10 @@ namespace Apache.Ignite.Linq.Impl
             GetParameterizedTrimMethod("TrimStart", "ltrim"),
             GetParameterizedTrimMethod("TrimEnd", "rtrim"),
             GetStringMethod("Replace", "replace", typeof(string), typeof(string)),
+            GetStringMethod("PadLeft", "lpad", typeof (int)),
+            GetStringMethod("PadLeft", "lpad", typeof (int), typeof (char)),
+            GetStringMethod("PadRight", "rpad", typeof (int)),
+            GetStringMethod("PadRight", "rpad", typeof (int), typeof (char)),
 
             GetMethod(typeof (Regex), "Replace", new[] {typeof (string), typeof (string), typeof (string)}, 
                 GetFunc("regexp_replace")),


[23/50] [abbrv] ignite git commit: IGNITE-6554 Atomic cache remove operations are not logged to WAL - Fixes #2800.

Posted by ag...@apache.org.
IGNITE-6554 Atomic cache remove operations are not logged to WAL - Fixes #2800.

Signed-off-by: Alexey Goncharuk <al...@gmail.com>


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

Branch: refs/heads/ignite-6305
Commit: 20033c7324c49212ad9543e13e9a5ac1e4bf5b68
Parents: 62f3c4c
Author: dpavlov <dp...@gridgain.com>
Authored: Wed Oct 4 15:05:48 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Wed Oct 4 15:05:48 2017 +0300

----------------------------------------------------------------------
 .../processors/cache/GridCacheMapEntry.java     |   2 +
 .../db/wal/reader/IgniteWalReaderTest.java      | 159 ++++++++++++++++++-
 2 files changed, 158 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/20033c73/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index 7b60b9c..54b8dc3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@ -4486,6 +4486,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
             if (updateCntr != null)
                 updateCntr0 = updateCntr;
 
+            entry.logUpdate(op, null, newVer, 0, updateCntr0);
+
             if (oldVal != null) {
                 assert !entry.deletedUnlocked();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/20033c73/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
index b9c60b2..6db2784 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
@@ -24,6 +24,7 @@ import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.io.Serializable;
 import java.util.Collection;
+import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -61,6 +62,7 @@ import org.apache.ignite.internal.pagemem.wal.record.TxRecord;
 import org.apache.ignite.internal.pagemem.wal.record.UnwrapDataEntry;
 import org.apache.ignite.internal.pagemem.wal.record.WALRecord;
 import org.apache.ignite.internal.processors.cache.CacheObject;
+import org.apache.ignite.internal.processors.cache.GridCacheOperation;
 import org.apache.ignite.internal.processors.cache.KeyCacheObject;
 import org.apache.ignite.internal.processors.cache.persistence.wal.FileWriteAheadLogManager;
 import org.apache.ignite.internal.processors.cache.persistence.wal.reader.IgniteWalIteratorFactory;
@@ -75,8 +77,9 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.events.EventType.EVT_WAL_SEGMENT_ARCHIVED;
-import static org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor.genNewStyleSubfolderName;
+import static org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE;
 import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.DFLT_STORE_DIR;
+import static org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor.genNewStyleSubfolderName;
 
 /**
  * Test suite for WAL segments reader and event generator.
@@ -109,6 +112,9 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
      */
     private int archiveIncompleteSegmentAfterInactivityMs;
 
+    /** Custom wal mode. */
+    private WALMode customWalMode;
+
     /** {@inheritDoc} */
     @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
         final IgniteConfiguration cfg = super.getConfiguration(gridName);
@@ -143,7 +149,7 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
         pCfg.setWalHistorySize(1);
         pCfg.setWalSegmentSize(1024 * 1024);
         pCfg.setWalSegments(WAL_SEGMENTS);
-        pCfg.setWalMode(WALMode.BACKGROUND);
+        pCfg.setWalMode(customWalMode != null ? customWalMode : WALMode.BACKGROUND);
 
         if (archiveIncompleteSegmentAfterInactivityMs > 0)
             pCfg.setWalAutoArchiveAfterInactivity(archiveIncompleteSegmentAfterInactivityMs);
@@ -709,6 +715,128 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Creates and fills cache with data.
+     *
+     * @param ig Ignite instance.
+     * @param mode Cache Atomicity Mode.
+     */
+    private void createCache2(Ignite ig, CacheAtomicityMode mode) {
+        if (log.isInfoEnabled())
+            log.info("Populating the cache...");
+
+        final CacheConfiguration<Integer, Organization> cfg = new CacheConfiguration<>("Org" + "11");
+        cfg.setAtomicityMode(mode);
+        final IgniteCache<Integer, Organization> cache = ig.getOrCreateCache(cfg).withKeepBinary();
+
+        try (Transaction tx = ig.transactions().txStart()) {
+            for (int i = 0; i < 10; i++) {
+
+                cache.put(i, new Organization(i, "Organization-" + i));
+
+                if (i % 2 == 0)
+                    cache.put(i, new Organization(i, "Organization-updated-" + i));
+
+                if (i % 5 == 0)
+                    cache.remove(i);
+            }
+            tx.commit();
+        }
+
+    }
+
+    /**
+     * Test if DELETE operation can be found for transactional cache after mixed cache operations including remove().
+     *
+     * @throws Exception if failed.
+     */
+    public void testRemoveOperationPresentedForDataEntry() throws Exception {
+        runRemoveOperationTest(CacheAtomicityMode.TRANSACTIONAL);
+    }
+
+    /**
+     * Test if DELETE operation can be found for atomic cache after mixed cache operations including remove().
+     *
+     * @throws Exception if failed.
+     */
+    public void testRemoveOperationPresentedForDataEntryForAtomic() throws Exception {
+        runRemoveOperationTest(CacheAtomicityMode.ATOMIC);
+    }
+
+
+    /**
+     * Test if DELETE operation can be found after mixed cache operations including remove().
+     *
+     * @throws Exception if failed.
+     * @param mode Cache Atomicity Mode.
+     */
+    private void runRemoveOperationTest(CacheAtomicityMode mode) throws Exception {
+        final Ignite ignite = startGrid("node0");
+
+        ignite.active(true);
+        createCache2(ignite, mode);
+        ignite.active(false);
+
+        final String subfolderName = genDbSubfolderName(ignite, 0);
+
+        stopGrid("node0");
+
+        final String workDir = U.defaultWorkDirectory();
+        final IgniteWalIteratorFactory factory = createWalIteratorFactory(subfolderName, workDir);
+
+        final StringBuilder builder = new StringBuilder();
+        final Map<GridCacheOperation, Integer> operationsFound = new EnumMap<>(GridCacheOperation.class);
+
+        scanIterateAndCount(factory, workDir, subfolderName, 0, 0, null, new Consumer<DataRecord>() {
+            @Override public void accept(DataRecord dataRecord) {
+                final List<DataEntry> entries = dataRecord.writeEntries();
+
+                builder.append("{");
+                for (DataEntry entry : entries) {
+                    final GridCacheOperation op = entry.op();
+                    final Integer cnt = operationsFound.get(op);
+
+                    operationsFound.put(op, cnt == null ? 1 : (cnt + 1));
+
+                    if (entry instanceof UnwrapDataEntry) {
+                        final UnwrapDataEntry entry1 = (UnwrapDataEntry)entry;
+
+                        builder.append(entry1.op()).append(" for ").append(entry1.unwrappedKey());
+                        final GridCacheVersion ver = entry.nearXidVersion();
+
+                        builder.append(", ");
+
+                        if (ver != null)
+                            builder.append("tx=").append(ver).append(", ");
+                    }
+                }
+
+                builder.append("}\n");
+            }
+        });
+
+        final Integer deletesFound = operationsFound.get(DELETE);
+
+        if (log.isInfoEnabled())
+            log.info(builder.toString());
+
+        assertTrue("Delete operations should be found in log: " + operationsFound,
+            deletesFound != null && deletesFound > 0);
+    }
+
+    @NotNull private IgniteWalIteratorFactory createWalIteratorFactory(String subfolderName,
+        String workDir) throws IgniteCheckedException {
+        final File binaryMeta = U.resolveWorkDirectory(workDir, "binary_meta", false);
+        final File binaryMetaWithConsId = new File(binaryMeta, subfolderName);
+        final File marshallerMapping = U.resolveWorkDirectory(workDir, "marshaller", false);
+
+        return new IgniteWalIteratorFactory(log,
+            PAGE_SIZE,
+            binaryMetaWithConsId,
+            marshallerMapping);
+    }
+
+
+    /**
      * @param values collection with numbers
      * @return sum of numbers
      */
@@ -776,7 +904,7 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
                             "; Key: " + unwrappedKeyObj +
                             "; Value: " + unwrappedValObj);
 
-                        if (cacheObjHnd != null && unwrappedKeyObj != null || unwrappedValObj != null)
+                        if (cacheObjHnd != null && (unwrappedKeyObj != null || unwrappedValObj != null))
                             cacheObjHnd.accept(unwrappedKeyObj, unwrappedValObj);
 
                         final Integer entriesUnderTx = entriesUnderTxFound.get(globalTxId);
@@ -967,4 +1095,29 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
                 '}';
         }
     }
+
+    /** Test class for storing in ignite */
+    private static class Organization {
+        /** Key. */
+        private final int key;
+        /** Name. */
+        private final String name;
+
+        /**
+         * @param key Key.
+         * @param name Name.
+         */
+        public Organization(int key, String name) {
+            this.key = key;
+            this.name = name;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return "Organization{" +
+                "key=" + key +
+                ", name='" + name + '\'' +
+                '}';
+        }
+    }
 }


[27/50] [abbrv] ignite git commit: IGNITE-6307 If getAll() fails with NPE, onHeap entry is not removed, for local cache

Posted by ag...@apache.org.
IGNITE-6307 If getAll() fails with NPE, onHeap entry is not removed, for local cache


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

Branch: refs/heads/ignite-6305
Commit: e74163a99870bd50b24ea6799b7566dc37682f74
Parents: b2a0295
Author: Nikolay Izhikov <NI...@gmail.com>
Authored: Wed Oct 4 19:31:17 2017 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Wed Oct 4 19:31:17 2017 +0300

----------------------------------------------------------------------
 .../processors/cache/GridCacheAdapter.java      | 16 +++++++
 .../cache/GridCacheAbstractFullApiSelfTest.java | 45 +++++++++++++++++++-
 2 files changed, 59 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e74163a9/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 6d9f0d3..8c5d6f2 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
@@ -1853,6 +1853,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
         if (tx == null || tx.implicit()) {
             Map<KeyCacheObject, EntryGetResult> misses = null;
 
+            Set<GridCacheEntryEx> newLocalEntries = null;
+
             final AffinityTopologyVersion topVer = tx == null ? ctx.affinity().affinityTopologyVersion() :
                 tx.topologyVersion();
 
@@ -1925,6 +1927,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                             }
 
                             if (!skipEntry) {
+                                boolean isNewLocalEntry = this.map.getEntry(ctx, key) == null;
+
                                 entry = entryEx(key);
 
                                 if (entry == null) {
@@ -1934,6 +1938,13 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                                     break;
                                 }
 
+                                if (isNewLocalEntry) {
+                                    if (newLocalEntries == null)
+                                        newLocalEntries = new HashSet<>();
+
+                                    newLocalEntries.add(entry);
+                                }
+
                                 if (storeEnabled) {
                                     res = entry.innerGetAndReserveForLoad(updateMetrics,
                                         evt,
@@ -2128,6 +2139,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                         ctx.evicts().touch(peekEx(key0), topVer);
                 }
 
+                if (newLocalEntries != null) {
+                    for (GridCacheEntryEx entry : newLocalEntries)
+                        removeEntry(entry);
+                }
+
                 return new GridFinishedFuture<>(e);
             }
             catch (IgniteCheckedException e) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/e74163a9/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
index bf27e26..e6c9589 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
@@ -919,13 +919,54 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract
     /**
      * @throws Exception In case of error.
      */
-    public void testGetAllWithNulls() throws Exception {
+    public void testGetAllWithLastNull() throws Exception {
         final IgniteCache<String, Integer> cache = jcache();
 
-        final Set<String> c = new HashSet<>();
+        final Set<String> c = new LinkedHashSet<>();
+
+        c.add("key1");
+        c.add(null);
+
+        GridTestUtils.assertThrows(log, new Callable<Void>() {
+            @Override public Void call() throws Exception {
+                cache.getAll(c);
+
+                return null;
+            }
+        }, NullPointerException.class, null);
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    public void testGetAllWithFirstNull() throws Exception {
+        final IgniteCache<String, Integer> cache = jcache();
+
+        final Set<String> c = new LinkedHashSet<>();
+
+        c.add(null);
+        c.add("key1");
+
+        GridTestUtils.assertThrows(log, new Callable<Void>() {
+            @Override public Void call() throws Exception {
+                cache.getAll(c);
+
+                return null;
+            }
+        }, NullPointerException.class, null);
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    public void testGetAllWithInTheMiddle() throws Exception {
+        final IgniteCache<String, Integer> cache = jcache();
+
+        final Set<String> c = new LinkedHashSet<>();
 
         c.add("key1");
         c.add(null);
+        c.add("key2");
 
         GridTestUtils.assertThrows(log, new Callable<Void>() {
             @Override public Void call() throws Exception {


[38/50] [abbrv] ignite git commit: .NET: Add PlatformConfigurationUtils modification warning

Posted by ag...@apache.org.
.NET: Add PlatformConfigurationUtils modification warning


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

Branch: refs/heads/ignite-6305
Commit: a38fdec7212e0e21dc3ff8e6673fb56e2e00e1d1
Parents: e5c25b4
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri Oct 6 12:54:06 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Oct 6 12:54:06 2017 +0300

----------------------------------------------------------------------
 .../processors/platform/utils/PlatformConfigurationUtils.java     | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a38fdec7/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 66160fb..24f4438 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
@@ -98,6 +98,9 @@ import org.apache.ignite.transactions.TransactionIsolation;
 
 /**
  * Configuration utils.
+ *
+ * WARNING: DO NOT MODIFY THIS FILE without updating corresponding platform code!
+ * Each read/write method has a counterpart in .NET platform (see IgniteConfiguration.cs, CacheConfiguration.cs, etc).
  */
 @SuppressWarnings({"unchecked", "TypeMayBeWeakened"})
 public class PlatformConfigurationUtils {


[24/50] [abbrv] ignite git commit: Removed excluding ML from examples/src

Posted by ag...@apache.org.
Removed excluding ML from examples/src


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

Branch: refs/heads/ignite-6305
Commit: 78f77b1fd158955a3203811ba909e01fe7c474f5
Parents: 20033c7
Author: oleg-ostanin <oo...@gridgain.com>
Authored: Wed Oct 4 17:35:50 2017 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Wed Oct 4 17:35:50 2017 +0300

----------------------------------------------------------------------
 assembly/release-fabric-base.xml | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/78f77b1f/assembly/release-fabric-base.xml
----------------------------------------------------------------------
diff --git a/assembly/release-fabric-base.xml b/assembly/release-fabric-base.xml
index a16d996..8e8bd75 100644
--- a/assembly/release-fabric-base.xml
+++ b/assembly/release-fabric-base.xml
@@ -239,7 +239,6 @@
             <excludes>
                 <exclude>**/package.html</exclude>
                 <exclude>src/test/**</exclude>
-                <exclude>src/main/ml/**</exclude>
             </excludes>
         </fileSet>
 


[14/50] [abbrv] ignite git commit: IGNITE-6350: SQL: forbid configurations with NOT NULL fields and read-through cache store. This closes #2656.

Posted by ag...@apache.org.
IGNITE-6350: SQL: forbid configurations with NOT NULL fields and read-through cache store. This closes #2656.


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

Branch: refs/heads/ignite-6305
Commit: 3256ee27e7cd929246f2e5813fcc35adda58cc3f
Parents: 16d2370
Author: Sergey Kalashnikov <sk...@gridgain.com>
Authored: Tue Oct 3 10:13:06 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Oct 3 10:13:06 2017 +0300

----------------------------------------------------------------------
 .../ignite/jdbc/JdbcErrorsAbstractSelfTest.java |  88 ++++++++-
 .../processors/cache/GridCacheUtils.java        |   6 +-
 .../processors/query/GridQueryProcessor.java    |   6 +-
 .../internal/processors/query/QueryUtils.java   |  17 ++
 .../query/h2/ddl/DdlStatementsProcessor.java    |  15 +-
 .../query/IgniteSqlNotNullConstraintTest.java   | 179 ++++++++++++++++++-
 .../Cache/CacheConfigurationTest.cs             |   2 +-
 7 files changed, 304 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/3256ee27/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java
index 78020cf..952baa5 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.jdbc;
 
+import java.io.Serializable;
 import java.net.URL;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
@@ -29,8 +30,14 @@ import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Collections;
 import java.util.List;
+import javax.cache.Cache;
+import javax.cache.integration.CacheLoaderException;
+import javax.cache.integration.CacheWriterException;
+import org.apache.ignite.cache.CacheInterceptorAdapter;
 import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.store.CacheStoreAdapter;
 import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.lang.IgniteCallable;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
@@ -39,13 +46,27 @@ import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
  * Test SQLSTATE codes propagation with (any) Ignite JDBC driver.
  */
 public abstract class JdbcErrorsAbstractSelfTest extends GridCommonAbstractTest {
+    /** */
+    protected static final String CACHE_STORE_TEMPLATE = "cache_store";
+
+    /** */
+    protected static final String CACHE_INTERCEPTOR_TEMPLATE = "cache_interceptor";
+
     /** {@inheritDoc} */
     @Override protected void beforeTestsStarted() throws Exception {
         super.beforeTestsStarted();
 
-        startGrid(getConfiguration(getTestIgniteInstanceName(0))
+        IgniteEx grid = startGrid(getConfiguration(getTestIgniteInstanceName(0))
             .setCacheConfiguration(new CacheConfiguration("test")
                 .setQueryEntities(Collections.singletonList(new QueryEntity(Integer.class, Integer.class)))));
+
+        // add cache template for cache with enabled read-through cache store
+        grid.addCacheConfiguration(new CacheConfiguration<>(CACHE_STORE_TEMPLATE)
+            .setCacheStoreFactory(singletonFactory(new TestCacheStore())).setReadThrough(true));
+
+        // add cache template for cache with enabled cache interceptor
+        grid.addCacheConfiguration(new CacheConfiguration<>(CACHE_INTERCEPTOR_TEMPLATE)
+            .setInterceptor(new TestCacheInterceptor()));
     }
 
     /** {@inheritDoc} */
@@ -505,6 +526,44 @@ public abstract class JdbcErrorsAbstractSelfTest extends GridCommonAbstractTest
     }
 
     /**
+     * Check error code for the case not null field is configured for table belonging to cache
+     * with enabled read-through cache store.
+     *
+     * @throws SQLException if failed.
+     */
+    public void testNotNullRestrictionReadThroughCacheStore() throws SQLException {
+        checkErrorState(new ConnClosure() {
+            @Override public void run(Connection conn) throws Exception {
+                conn.setSchema("PUBLIC");
+
+                try (Statement stmt = conn.createStatement()) {
+                    stmt.execute("CREATE TABLE cache_store_nulltest(id INT PRIMARY KEY, age INT NOT NULL) " +
+                        "WITH \"template=" + CACHE_STORE_TEMPLATE + "\"");
+                }
+            }
+        }, "0A000");
+    }
+
+    /**
+     * Check error code for the case not null field is configured for table belonging to cache
+     * with configured cache interceptor.
+     *
+     * @throws SQLException if failed.
+     */
+    public void testNotNullRestrictionCacheInterceptor() throws SQLException {
+        checkErrorState(new ConnClosure() {
+            @Override public void run(Connection conn) throws Exception {
+                conn.setSchema("PUBLIC");
+
+                try (Statement stmt = conn.createStatement()) {
+                    stmt.execute("CREATE TABLE cache_interceptor_nulltest(id INT PRIMARY KEY, age INT NOT NULL) " +
+                        "WITH \"template=" + CACHE_INTERCEPTOR_TEMPLATE + "\"");
+                }
+            }
+        }, "0A000");
+    }
+
+    /**
      * @return Connection to execute statements on.
      * @throws SQLException if failed.
      */
@@ -570,4 +629,31 @@ public abstract class JdbcErrorsAbstractSelfTest extends GridCommonAbstractTest
          */
         void run(Connection conn) throws Exception;
     }
+
+    /**
+     * Cache store stub.
+     */
+    protected class TestCacheStore extends CacheStoreAdapter<Object,Object> implements Serializable {
+        /** {@inheritDoc} */
+        @Override public Object load(Object key) throws CacheLoaderException {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void write(Cache.Entry<?, ?> entry) throws CacheWriterException {
+            // No-op
+        }
+
+        /** {@inheritDoc} */
+        @Override public void delete(Object key) throws CacheWriterException {
+            // No-op
+        }
+    }
+
+    /**
+     * Cache interceptor stub.
+     */
+    private static class TestCacheInterceptor extends CacheInterceptorAdapter<Object, Object> implements Serializable {
+        // No-op
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/3256ee27/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
index 2018a64..4f76875 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
@@ -1663,8 +1663,12 @@ public class GridCacheUtils {
         if (!F.isEmpty(entities)) {
             Collection<QueryEntity> normalEntities = new ArrayList<>(entities.size());
 
-            for (QueryEntity entity : entities)
+            for (QueryEntity entity : entities) {
+                if (!F.isEmpty(entity.getNotNullFields()))
+                    QueryUtils.checkNotNullAllowed(cfg);
+
                 normalEntities.add(QueryUtils.normalizeQueryEntity(entity, cfg.isSqlEscapeAll()));
+            }
 
             cfg.clearQueryEntities().setQueryEntities(normalEntities);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/3256ee27/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index 58c3ce9..56e8a42 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -39,7 +39,6 @@ import javax.cache.CacheException;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteDataStreamer;
 import org.apache.ignite.IgniteException;
-import org.apache.ignite.binary.BinaryType;
 import org.apache.ignite.binary.Binarylizable;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheKeyConfiguration;
@@ -1355,7 +1354,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
      * @param schemaName Schema name to create table in.
      * @param entity Entity to create table from.
      * @param templateName Template name.
-     * @param cacheName
+     * @param cacheName Cache name.
      * @param cacheGroup Cache group name.
      * @param affinityKey Affinity key column name.
      * @param atomicityMode Atomicity mode.
@@ -1389,6 +1388,9 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             throw new SchemaOperationException("Template cache already contains query entities which it should not: " +
                 templateName);
 
+        if (!F.isEmpty(entity.getNotNullFields()))
+            QueryUtils.checkNotNullAllowed(ccfg);
+
         if (F.isEmpty(cacheName))
             cacheName = QueryUtils.createTableCacheName(schemaName, entity.getTableName());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/3256ee27/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
index e76a6ca..1b61ce9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
@@ -46,6 +46,7 @@ import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheDefaultAffinityKeyMapper;
 import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
+import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
 import org.apache.ignite.internal.processors.query.property.QueryBinaryProperty;
 import org.apache.ignite.internal.processors.query.property.QueryClassProperty;
 import org.apache.ignite.internal.processors.query.property.QueryFieldAccessor;
@@ -1204,6 +1205,22 @@ public class QueryUtils {
     }
 
     /**
+     * Performs checks to forbid cache configurations that are not compatible with NOT NULL query fields.
+     * See {@link QueryEntity#setNotNullFields(Set)}.
+     *
+     * @param cfg Cache configuration.
+     */
+    public static void checkNotNullAllowed(CacheConfiguration cfg) {
+        if (cfg.isReadThrough())
+            throw new IgniteSQLException("NOT NULL constraint is not supported when CacheConfiguration.readThrough " +
+                "is enabled.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
+
+        if (cfg.getInterceptor() != null)
+            throw new IgniteSQLException("NOT NULL constraint is not supported when CacheConfiguration.interceptor " +
+                "is set.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
+    }
+
+    /**
      * Private constructor.
      */
     private QueryUtils() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/3256ee27/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
index 8a901dc..affd903 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
@@ -229,6 +229,8 @@ public class DdlStatementsProcessor {
                 else {
                     List<QueryField> cols = new ArrayList<>(cmd.columns().length);
 
+                    boolean allFieldsNullable = true;
+
                     for (GridSqlColumn col : cmd.columns()) {
                         if (tbl.doesColumnExist(col.columnName())) {
                             if ((!cmd.ifNotExists() || cmd.columns().length != 1)) {
@@ -242,14 +244,21 @@ public class DdlStatementsProcessor {
                             }
                         }
 
-                        cols.add(new QueryField(col.columnName(),
+                        QueryField field = new QueryField(col.columnName(),
                             DataType.getTypeClassName(col.column().getType()),
-                            col.column().isNullable()));
+                            col.column().isNullable());
+
+                        cols.add(field);
+
+                        allFieldsNullable &= field.isNullable();
                     }
 
                     if (cols != null) {
                         assert tbl.rowDescriptor() != null;
 
+                        if (!allFieldsNullable)
+                            QueryUtils.checkNotNullAllowed(tbl.cache().config());
+
                         fut = ctx.query().dynamicColumnAdd(tbl.cacheName(), cmd.schemaName(),
                             tbl.rowDescriptor().type().tableName(), cols, cmd.ifTableExists(), cmd.ifNotExists());
                     }
@@ -276,7 +285,7 @@ public class DdlStatementsProcessor {
             throw e;
         }
         catch (Exception e) {
-            throw new IgniteSQLException("Unexpected DLL operation failure: " + e.getMessage(), e);
+            throw new IgniteSQLException("Unexpected DDL operation failure: " + e.getMessage(), e);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/3256ee27/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java
index b724f02..b372eb3 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Callable;
+import javax.cache.Cache;
 import javax.cache.CacheException;
 import javax.cache.processor.EntryProcessor;
 import javax.cache.processor.EntryProcessorException;
@@ -32,6 +33,7 @@ import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheInterceptor;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.CacheWriteSynchronizationMode;
 import org.apache.ignite.cache.QueryEntity;
@@ -47,6 +49,7 @@ import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.lang.IgniteBiInClosure;
+import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
 import org.apache.ignite.testframework.GridTestUtils;
@@ -76,9 +79,29 @@ public class IgniteSqlNotNullConstraintTest extends GridCommonAbstractTest {
     /** Name of SQL table. */
     private static String TABLE_PERSON = "\"" + CACHE_PERSON +  "\".\"PERSON\"";
 
+    /** Template of cache with read-through setting. */
+    private static String CACHE_READ_THROUGH = "cacheReadThrough";
+
+    /** Template of cache with interceptor setting. */
+    private static String CACHE_INTERCEPTOR = "cacheInterceptor";
+
     /** Expected error message. */
     private static String ERR_MSG = "Null value is not allowed for field 'NAME'";
 
+    /** Expected error message for read-through restriction. */
+    private static String READ_THROUGH_ERR_MSG = "NOT NULL constraint is not supported when " +
+        "CacheConfiguration.readThrough is enabled.";
+
+    /** Expected error message for cache interceptor restriction. */
+    private static String INTERCEPTOR_ERR_MSG = "NOT NULL constraint is not supported when " +
+        "CacheConfiguration.interceptor is set.";
+
+    /** Name of the node which configuration includes restricted cache config. */
+    private static String READ_THROUGH_CFG_NODE_NAME = "nodeCacheReadThrough";
+
+    /** Name of the node which configuration includes restricted cache config. */
+    private static String INTERCEPTOR_CFG_NODE_NAME = "nodeCacheInterceptor";
+
     /** OK value. */
     private final Person okValue = new Person("Name", 18);
 
@@ -100,6 +123,18 @@ public class IgniteSqlNotNullConstraintTest extends GridCommonAbstractTest {
 
         ccfgs.addAll(cacheConfigurations());
 
+        if (gridName.equals(READ_THROUGH_CFG_NODE_NAME)) {
+            ccfgs.add(buildCacheConfigurationRestricted("BadCfgTestCacheRT", true, false, true));
+
+            c.setClientMode(true);
+        }
+
+        if (gridName.equals(INTERCEPTOR_CFG_NODE_NAME)) {
+            ccfgs.add(buildCacheConfigurationRestricted("BadCfgTestCacheINT", false, true, true));
+
+            c.setClientMode(true);
+        }
+
         c.setCacheConfiguration(ccfgs.toArray(new CacheConfiguration[ccfgs.size()]));
 
         if (gridName.equals(NODE_CLIENT)) {
@@ -161,6 +196,30 @@ public class IgniteSqlNotNullConstraintTest extends GridCommonAbstractTest {
         return cfg;
     }
 
+    /** */
+    private CacheConfiguration buildCacheConfigurationRestricted(String cacheName, boolean readThrough,
+        boolean interceptor, boolean hasQueryEntity) {
+        CacheConfiguration cfg = new CacheConfiguration<Integer, Person>()
+            .setName(cacheName)
+            .setCacheMode(CacheMode.PARTITIONED)
+            .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
+
+        if (readThrough) {
+            cfg.setCacheStoreFactory(singletonFactory(new TestStore()));
+            cfg.setReadThrough(true);
+        }
+
+        if (interceptor)
+            cfg.setInterceptor(new TestInterceptor());
+
+        if (hasQueryEntity) {
+            cfg.setQueryEntities(F.asList(new QueryEntity(Integer.class, Person.class)
+                .setNotNullFields(Collections.singleton("name"))));
+        }
+
+        return cfg;
+    }
+
     /** {@inheritDoc} */
     @Override protected void beforeTestsStarted() throws Exception {
         super.beforeTestsStarted();
@@ -169,6 +228,14 @@ public class IgniteSqlNotNullConstraintTest extends GridCommonAbstractTest {
 
         startGrid(NODE_CLIENT);
 
+        // Add cache template with read-through cache store.
+        grid(NODE_CLIENT).addCacheConfiguration(
+            buildCacheConfigurationRestricted(CACHE_READ_THROUGH, true, false, false));
+
+        // Add cache template with cache interceptor.
+        grid(NODE_CLIENT).addCacheConfiguration(
+            buildCacheConfigurationRestricted(CACHE_INTERCEPTOR, false, true, false));
+
         awaitPartitionMapExchange();
     }
 
@@ -806,6 +873,86 @@ public class IgniteSqlNotNullConstraintTest extends GridCommonAbstractTest {
         assertEquals("Bob", result.get(2).get(1));
     }
 
+    /** Check QueryEntity configuration fails with NOT NULL field and read-through. */
+    public void testReadThroughRestrictionQueryEntity() throws Exception {
+        // Node start-up failure (read-through cache store).
+        GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                return startGrid(READ_THROUGH_CFG_NODE_NAME);
+            }
+        }, IgniteCheckedException.class, READ_THROUGH_ERR_MSG);
+
+        // Dynamic cache start-up failure (read-through cache store)
+        GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                return grid(NODE_CLIENT).createCache(
+                    buildCacheConfigurationRestricted("dynBadCfgCacheRT", true, false, true));
+            }
+        }, IgniteCheckedException.class, READ_THROUGH_ERR_MSG);
+    }
+
+    /** Check QueryEntity configuration fails with NOT NULL field and cache interceptor. */
+    public void testInterceptorRestrictionQueryEntity() throws Exception {
+        // Node start-up failure (interceptor).
+        GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                return startGrid(INTERCEPTOR_CFG_NODE_NAME);
+            }
+        }, IgniteCheckedException.class, INTERCEPTOR_ERR_MSG);
+
+        // Dynamic cache start-up failure (interceptor)
+        GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                return grid(NODE_CLIENT).createCache(
+                    buildCacheConfigurationRestricted("dynBadCfgCacheINT", false, true, true));
+            }
+        }, IgniteCheckedException.class, INTERCEPTOR_ERR_MSG);
+    }
+
+    /** Check create table fails with NOT NULL field and read-through. */
+    public void testReadThroughRestrictionCreateTable() throws Exception {
+        GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                return executeSql("CREATE TABLE test(id INT PRIMARY KEY, name char NOT NULL) " +
+                    "WITH \"template=" + CACHE_READ_THROUGH+ "\"");
+            }
+        }, IgniteSQLException.class, READ_THROUGH_ERR_MSG);
+    }
+
+    /** Check create table fails with NOT NULL field and cache interceptor. */
+    public void testInterceptorRestrictionCreateTable() throws Exception {
+        GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                return executeSql("CREATE TABLE test(id INT PRIMARY KEY, name char NOT NULL) " +
+                    "WITH \"template=" + CACHE_INTERCEPTOR + "\"");
+            }
+        }, IgniteSQLException.class, INTERCEPTOR_ERR_MSG);
+    }
+
+    /** Check alter table fails with NOT NULL field and read-through. */
+    public void testReadThroughRestrictionAlterTable() throws Exception {
+        executeSql("CREATE TABLE test(id INT PRIMARY KEY, age INT) " +
+            "WITH \"template=" + CACHE_READ_THROUGH + "\"");
+
+        GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                return executeSql("ALTER TABLE test ADD COLUMN name char NOT NULL");
+            }
+        }, IgniteSQLException.class, READ_THROUGH_ERR_MSG);
+    }
+
+    /** Check alter table fails with NOT NULL field and cache interceptor. */
+    public void testInterceptorRestrictionAlterTable() throws Exception {
+        executeSql("CREATE TABLE test(id INT PRIMARY KEY, age INT) " +
+            "WITH \"template=" + CACHE_INTERCEPTOR + "\"");
+
+        GridTestUtils.assertThrowsAnyCause(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                return executeSql("ALTER TABLE test ADD COLUMN name char NOT NULL");
+            }
+        }, IgniteSQLException.class, INTERCEPTOR_ERR_MSG);
+    }
+
     /** */
     private void executeWithAllCaches(TestClosure clo) throws Exception {
         for (CacheConfiguration ccfg : cacheConfigurations())
@@ -1034,7 +1181,7 @@ public class IgniteSqlNotNullConstraintTest extends GridCommonAbstractTest {
     }
 
     /**
-     * Test store.
+     * Test cache store stub.
      */
     private static class TestStore extends CacheStoreAdapter<Integer, Person> {
         /** {@inheritDoc} */
@@ -1057,4 +1204,34 @@ public class IgniteSqlNotNullConstraintTest extends GridCommonAbstractTest {
             // No-op
         }
     }
+
+    /**
+     * Test interceptor stub.
+     */
+    private static class TestInterceptor implements CacheInterceptor<Integer, Person> {
+        /** {@inheritDoc} */
+        @Nullable @Override public Person onGet(Integer key, @Nullable Person val) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Nullable @Override public Person onBeforePut(Cache.Entry<Integer, Person> entry, Person newVal) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void onAfterPut(Cache.Entry<Integer, Person> entry) {
+            // No-op
+        }
+
+        /** {@inheritDoc} */
+        @Nullable @Override public IgniteBiTuple<Boolean, Person> onBeforeRemove(Cache.Entry<Integer, Person> entry) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void onAfterRemove(Cache.Entry<Integer, Person> entry) {
+            // No-op
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/3256ee27/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 abf8af0..ddf669d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs
@@ -573,7 +573,7 @@ namespace Apache.Ignite.Core.Tests.Cache
                 WriteBehindEnabled = false,
                 WriteSynchronizationMode = CacheWriteSynchronizationMode.PrimarySync,
                 CacheStoreFactory = new CacheStoreFactoryTest(),
-                ReadThrough = true,
+                ReadThrough = false,
                 WriteThrough = true,
                 WriteBehindCoalescing = false,
                 GroupName = "someGroup",


[26/50] [abbrv] ignite git commit: IGNITE-6550 Added new snapshot WAL record type - Fixes #2795.

Posted by ag...@apache.org.
IGNITE-6550 Added new snapshot WAL record type - Fixes #2795.

Signed-off-by: Alexey Goncharuk <al...@gmail.com>


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

Branch: refs/heads/ignite-6305
Commit: b2a0295894dbdeb638ac8f764549a724578322ac
Parents: e6e1ca9
Author: Dmitriy Govorukhin <dm...@gmail.com>
Authored: Wed Oct 4 18:59:40 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Wed Oct 4 18:59:40 2017 +0300

----------------------------------------------------------------------
 .../ignite/internal/pagemem/wal/WALPointer.java |  4 +-
 .../pagemem/wal/record/SnapshotRecord.java      | 58 ++++++++++++++++++++
 .../internal/pagemem/wal/record/WALRecord.java  |  6 +-
 .../GridCacheDatabaseSharedManager.java         |  3 +
 .../cache/persistence/wal/FileWALPointer.java   |  3 +
 5 files changed, 71 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b2a02958/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/WALPointer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/WALPointer.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/WALPointer.java
index 73321f1..7ca4aee 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/WALPointer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/WALPointer.java
@@ -17,10 +17,12 @@
 
 package org.apache.ignite.internal.pagemem.wal;
 
+import java.io.Serializable;
+
 /**
  *
  */
-public interface WALPointer {
+public interface WALPointer extends Serializable {
     /**
      * Pointer to the next record. Can be used only for original pointers obtained from WAL manager.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/b2a02958/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/SnapshotRecord.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/SnapshotRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/SnapshotRecord.java
new file mode 100644
index 0000000..3c3a77b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/SnapshotRecord.java
@@ -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.
+ */
+
+package org.apache.ignite.internal.pagemem.wal.record;
+
+/**
+ * Wal snapshot record.
+ */
+public class SnapshotRecord extends WALRecord {
+    /** Snapshot id. */
+    private long snapshotId;
+
+    /** Full snapshot or incremental. */
+    private boolean full;
+
+    /**
+     *
+     */
+    public SnapshotRecord(long snapshotId, boolean full) {
+        this.snapshotId = snapshotId;
+        this.full = full;
+    }
+
+    /**
+     *
+     */
+    public long getSnapshotId() {
+        return snapshotId;
+    }
+
+    /**
+     *
+     */
+    public boolean isFull() {
+        return full;
+    }
+
+    /**
+     *
+     */
+    @Override public RecordType type() {
+        return RecordType.SNAPSHOT;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/b2a02958/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
index 89f3c86..08bba1b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
@@ -163,8 +163,10 @@ public abstract class WALRecord {
         BTREE_META_PAGE_INIT_ROOT2,
 
         /** Partition destroy. */
-        PARTITION_DESTROY
-        ;
+        PARTITION_DESTROY,
+
+        /** Snapshot record. */
+        SNAPSHOT;
 
         /** */
         private static final RecordType[] VALS = RecordType.values();

http://git-wip-us.apache.org/repos/asf/ignite/blob/b2a02958/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
index 2d89942..33f065e 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
@@ -2383,6 +2383,9 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
                 return new Checkpoint(cpEntry, cpPages, curr);
             }
             else {
+                if (curr.nextSnapshot)
+                    cctx.wal().fsync(null);
+
                 if (printCheckpointStats) {
                     if (log.isInfoEnabled())
                         LT.info(log, String.format("Skipping checkpoint (no pages were modified) [" +

http://git-wip-us.apache.org/repos/asf/ignite/blob/b2a02958/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWALPointer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWALPointer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWALPointer.java
index 3716de2..4998700 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWALPointer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWALPointer.java
@@ -24,6 +24,9 @@ import org.apache.ignite.internal.util.typedef.internal.S;
  * File WAL pointer.
  */
 public class FileWALPointer implements WALPointer, Comparable<FileWALPointer> {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
     /** Absolute WAL segment file index (incrementing counter) */
     private final long idx;
 


[28/50] [abbrv] ignite git commit: Adjusted WAL docs

Posted by ag...@apache.org.
Adjusted WAL docs


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

Branch: refs/heads/ignite-6305
Commit: 8bd51d8af815f91089405dfdde3b1b81af7b2e59
Parents: e74163a
Author: Denis Magda <dm...@gridgain.com>
Authored: Wed Oct 4 13:51:53 2017 -0700
Committer: Denis Magda <dm...@gridgain.com>
Committed: Wed Oct 4 13:51:53 2017 -0700

----------------------------------------------------------------------
 .../main/java/org/apache/ignite/configuration/WALMode.java  | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8bd51d8a/modules/core/src/main/java/org/apache/ignite/configuration/WALMode.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/WALMode.java b/modules/core/src/main/java/org/apache/ignite/configuration/WALMode.java
index bea0cba..aa5cfdd 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/WALMode.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/WALMode.java
@@ -26,7 +26,7 @@ import org.jetbrains.annotations.Nullable;
 public enum WALMode {
     /**
      * Default mode: full-sync disk writes. These writes survive power loss scenarios. When a control is returned
-     * from the trnasaction commit operation, the changes are guaranteed to be forced on disk according to the
+     * from the transaction commit operation, the changes are guaranteed to be persisted to disk according to the
      * transaction write synchronization mode.
      */
     DEFAULT,
@@ -34,18 +34,19 @@ public enum WALMode {
     /**
      * Log only mode: flushes application buffers. These writes survive process crash. When a control is returned
      * from the transaction commit operation, the changes are guaranteed to be forced to the OS buffer cache.
+     * It's up to the OS to decide when to flush its caches to disk.
      */
     LOG_ONLY,
 
     /**
-     * Background mode. Does not force application buffer flush. Last updates may be lost in case of a process crash.
+     * Background mode. Does not force application's buffer flush. Last updates may be lost in case of a process crash.
      */
     BACKGROUND,
 
     /**
      * WAL is disabled. Data is guaranteed to be persisted on disk only in case of graceful cluster shutdown using
-     * {@link Ignite#active(boolean)} method. If an Ignite node is forefully terminated in NONE mode, it is likely
-     * that data stored on disk is corrupted and work directory will need to be cleared for a successfull node restart.
+     * {@link Ignite#active(boolean)} method. If an Ignite node is terminated in NONE mode abruptly, it is likely
+     * that the data stored on disk is corrupted and work directory will need to be cleared for a node restart.
      */
     NONE;
 


[04/50] [abbrv] ignite git commit: ignite-2.2.0 Update version.

Posted by ag...@apache.org.
ignite-2.2.0 Update version.


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

Branch: refs/heads/ignite-6305
Commit: 59ee8af5ce8076a3c97ef69765075cbe9e5694d0
Parents: 55886b1
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Mon Oct 2 14:07:40 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Oct 2 14:07:40 2017 +0700

----------------------------------------------------------------------
 .../frontend/app/modules/agent/AgentManager.service.js       | 4 +++-
 .../web-console/frontend/app/modules/sql/sql.controller.js   | 8 ++++----
 modules/web-console/frontend/app/services/Version.service.js | 6 +++---
 3 files changed, 10 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee8af5/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/agent/AgentManager.service.js b/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
index e4bde6f..20d2976 100644
--- a/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
+++ b/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
@@ -26,6 +26,8 @@ const State = {
     CONNECTED: 'CONNECTED'
 };
 
+const LAZY_QUERY_SINCE = [['2.1.4-p1', '2.2.0'], '2.2.1'];
+
 class ConnectionState {
     constructor(cluster) {
         this.agents = [];
@@ -499,7 +501,7 @@ export default class IgniteAgentManager {
      */
     querySql(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz, lazy) {
         if (this.available('2.0.0')) {
-            const task = this.available('2.1.4-p1') ?
+            const task = this.available(...LAZY_QUERY_SINCE) ?
                 this.visorTask('querySqlX2', nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz, lazy) :
                 this.visorTask('querySqlX2', nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee8af5/modules/web-console/frontend/app/modules/sql/sql.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/sql/sql.controller.js b/modules/web-console/frontend/app/modules/sql/sql.controller.js
index 420c4b9..5f06c1e 100644
--- a/modules/web-console/frontend/app/modules/sql/sql.controller.js
+++ b/modules/web-console/frontend/app/modules/sql/sql.controller.js
@@ -28,9 +28,9 @@ const ROW_IDX = {value: -2, type: 'java.lang.Integer', label: 'ROW_IDX'};
 
 const NON_COLLOCATED_JOINS_SINCE = '1.7.0';
 
-const ENFORCE_JOIN_VERS = [['1.7.9', '1.8.0'], ['1.8.4', '1.9.0'], ['1.9.1']];
+const ENFORCE_JOIN_SINCE = [['1.7.9', '1.8.0'], ['1.8.4', '1.9.0'], '1.9.1'];
 
-const LAZY_QUERY_VERS = ['2.1.4-p1'];
+const LAZY_QUERY_SINCE = [['2.1.4-p1', '2.2.0'], '2.2.1'];
 
 const _fullColName = (col) => {
     const res = [];
@@ -1367,7 +1367,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
             const cache = _.find($scope.caches, {name: paragraph.cacheName});
 
             if (cache)
-                return !!_.find(cache.nodes, (node) => Version.since(node.version, ...ENFORCE_JOIN_VERS));
+                return !!_.find(cache.nodes, (node) => Version.since(node.version, ...ENFORCE_JOIN_SINCE));
 
             return false;
         };
@@ -1376,7 +1376,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
             const cache = _.find($scope.caches, {name: paragraph.cacheName});
 
             if (cache)
-                return !!_.find(cache.nodes, (node) => Version.since(node.version, ...LAZY_QUERY_VERS));
+                return !!_.find(cache.nodes, (node) => Version.since(node.version, ...LAZY_QUERY_SINCE));
 
             return false;
         };

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee8af5/modules/web-console/frontend/app/services/Version.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/services/Version.service.js b/modules/web-console/frontend/app/services/Version.service.js
index 8ae23d3..beb27fa 100644
--- a/modules/web-console/frontend/app/services/Version.service.js
+++ b/modules/web-console/frontend/app/services/Version.service.js
@@ -73,12 +73,12 @@ const compare = (a, b) => {
 
 export default class IgniteVersion {
     constructor() {
-        this.webConsole = '2.1.0';
+        this.webConsole = '2.2.0';
 
         this.supportedVersions = [
             {
-                label: 'Ignite 2.1',
-                ignite: '2.1.0'
+                label: 'Ignite 2.x',
+                ignite: '2.2.0'
             },
             {
                 label: 'Ignite 2.0',


[48/50] [abbrv] ignite git commit: IGNITE-6287 Web Console: Improved DDL support: added checkbox "Use selected cache as default schema name".

Posted by ag...@apache.org.
IGNITE-6287 Web Console: Improved DDL support: added checkbox "Use selected cache as default schema name".


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

Branch: refs/heads/ignite-6305
Commit: a45677cf0b6b6ffa524fc10932c002d3b879f943
Parents: dc514c7
Author: Vasiliy Sisko <vs...@gridgain.com>
Authored: Mon Oct 9 19:23:23 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Oct 9 19:23:23 2017 +0700

----------------------------------------------------------------------
 .../ignite/internal/visor/query/VisorQueryTask.java  | 15 +--------------
 modules/web-console/backend/app/mongo.js             |  1 +
 .../frontend/app/modules/sql/sql.controller.js       | 14 +++++++++++++-
 .../frontend/public/stylesheets/style.scss           |  8 ++++++++
 modules/web-console/frontend/views/sql/sql.tpl.pug   | 10 ++++++++++
 5 files changed, 33 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a45677cf/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryTask.java
index a3668c8..933bacc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryTask.java
@@ -99,20 +99,7 @@ public class VisorQueryTask extends VisorOneNodeTask<VisorQueryTaskArg, VisorEit
                     if (c == null)
                         throw new SQLException("Fail to execute query. Cache not found: " + cacheName);
 
-                    try {
-                        qryCursor = c.withKeepBinary().query(qry);
-                    }
-                    catch (CacheException e) {
-                        // Work around for DDL without explicit schema name.
-                        if (X.hasCause(e, IgniteSQLException.class)
-                            && e.getMessage().contains("can only be executed on PUBLIC schema")) {
-                            qry.setSchema("PUBLIC");
-
-                            qryCursor = c.withKeepBinary().query(qry);
-                        }
-                        else
-                            throw e;
-                    }
+                    qryCursor = c.withKeepBinary().query(qry);
                 }
 
                 VisorQueryCursor<List<?>> cur = new VisorQueryCursor<>(qryCursor);

http://git-wip-us.apache.org/repos/asf/ignite/blob/a45677cf/modules/web-console/backend/app/mongo.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/mongo.js b/modules/web-console/backend/app/mongo.js
index ecc833f..a07f979 100644
--- a/modules/web-console/backend/app/mongo.js
+++ b/modules/web-console/backend/app/mongo.js
@@ -1036,6 +1036,7 @@ module.exports.factory = function(passportMongo, settings, pluginMongo, mongoose
             maxPages: Number,
             hideSystemColumns: Boolean,
             cacheName: String,
+            useAsDefaultSchema: Boolean,
             chartsOptions: {barChart: {stacked: Boolean}, areaChart: {style: String}},
             rate: {
                 value: Number,

http://git-wip-us.apache.org/repos/asf/ignite/blob/a45677cf/modules/web-console/frontend/app/modules/sql/sql.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/sql/sql.controller.js b/modules/web-console/frontend/app/modules/sql/sql.controller.js
index 8011b0f..a3fc0ca 100644
--- a/modules/web-console/frontend/app/modules/sql/sql.controller.js
+++ b/modules/web-console/frontend/app/modules/sql/sql.controller.js
@@ -32,6 +32,8 @@ const ENFORCE_JOIN_SINCE = [['1.7.9', '1.8.0'], ['1.8.4', '1.9.0'], '1.9.1'];
 
 const LAZY_QUERY_SINCE = [['2.1.4-p1', '2.2.0'], '2.2.1'];
 
+const DDL_SINCE = [['2.1.6', '2.2.0'], '2.3.0'];
+
 const _fullColName = (col) => {
     const res = [];
 
@@ -56,6 +58,7 @@ class Paragraph {
         self.qryType = paragraph.qryType || 'query';
         self.maxPages = 0;
         self.filter = '';
+        self.useAsDefaultSchema = false;
 
         _.assign(this, paragraph);
 
@@ -1381,6 +1384,15 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
             return false;
         };
 
+        $scope.ddlAvailable = (paragraph) => {
+            const cache = _.find($scope.caches, {name: paragraph.cacheName});
+
+            if (cache)
+                return !!_.find(cache.nodes, (node) => Version.since(node.version, ...DDL_SINCE));
+
+            return false;
+        };
+
         $scope.execute = (paragraph, local = false) => {
             const nonCollocatedJoins = !!paragraph.nonCollocatedJoins;
             const enforceJoinOrder = !!paragraph.enforceJoinOrder;
@@ -1399,7 +1411,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
                         .then(() => {
                             const args = paragraph.queryArgs = {
                                 type: 'QUERY',
-                                cacheName: paragraph.cacheName,
+                                cacheName: ($scope.ddlAvailable(paragraph) && !paragraph.useAsDefaultSchema) ? null : paragraph.cacheName,
                                 query: paragraph.query,
                                 pageSize: paragraph.pageSize,
                                 maxPages: paragraph.maxPages,

http://git-wip-us.apache.org/repos/asf/ignite/blob/a45677cf/modules/web-console/frontend/public/stylesheets/style.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/public/stylesheets/style.scss b/modules/web-console/frontend/public/stylesheets/style.scss
index eeb3a55..b259f1d 100644
--- a/modules/web-console/frontend/public/stylesheets/style.scss
+++ b/modules/web-console/frontend/public/stylesheets/style.scss
@@ -304,6 +304,14 @@ body > .wrapper > ui-view {
     }
 }
 
+.use-cache {
+    display: flex;
+
+    input[type="checkbox"] {
+        width: 20px;
+    }
+}
+
 .group-section {
     margin-top: 20px;
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/a45677cf/modules/web-console/frontend/views/sql/sql.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/sql/sql.tpl.pug b/modules/web-console/frontend/views/sql/sql.tpl.pug
index 724c53c..7ee966d 100644
--- a/modules/web-console/frontend/views/sql/sql.tpl.pug
+++ b/modules/web-console/frontend/views/sql/sql.tpl.pug
@@ -240,6 +240,16 @@ mixin paragraph-query
                                 td(style='width: 100%')
                                     input.labelField(id='cache_{{ [paragraph.id, $index].join("_") }}' type='radio' value='{{cache.name}}' ng-model='paragraph.cacheName')
                                     label(for='cache_{{ [paragraph.id, $index].join("_") }} ' ng-bind-html='cache.label')
+                    .settings-row
+                        .row(ng-if='ddlAvailable(paragraph)')
+                            label.tipLabel.use-cache(bs-tooltip data-placement='bottom'
+                                data-title=
+                                    'Use selected cache as default schema name.<br/>\
+                                    This will allow to execute query on specified cache without specify schema name.<br/>\
+                                    <b>NOTE:</b> In future version of Ignite this feature will be removed.'
+                                data-trigger='hover')
+                                input(type='checkbox' ng-model='paragraph.useAsDefaultSchema')
+                                span Use selected cache as default schema name
                 .empty-caches(ng-show='displayedCaches.length == 0 && caches.length != 0')
                     label Wrong caches filter
                 .empty-caches(ng-show='caches.length == 0')


[19/50] [abbrv] ignite git commit: Fixed affinityReadyFuture to use actual for result.

Posted by ag...@apache.org.
Fixed affinityReadyFuture to use actual for result.


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

Branch: refs/heads/ignite-6305
Commit: db69e90279d05ea980cf33ab4230c2c9d4dd2c01
Parents: b21f750
Author: sboikov <sb...@gridgain.com>
Authored: Tue Oct 3 16:42:01 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Tue Oct 3 16:42:01 2017 +0300

----------------------------------------------------------------------
 .../internal/processors/affinity/GridAffinityAssignmentCache.java  | 2 +-
 .../ignite/internal/processors/cache/GridCacheAffinityManager.java | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/db69e902/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
index f921251..cbc4eae 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
@@ -392,7 +392,7 @@ public class GridAffinityAssignmentCache {
                 log.debug("Completing topology ready future right away [head=" + aff.topologyVersion() +
                     ", topVer=" + topVer + ']');
 
-            fut.onDone(topVer);
+            fut.onDone(aff.topologyVersion());
         }
         else if (stopErr != null)
             fut.onDone(stopErr);

http://git-wip-us.apache.org/repos/asf/ignite/blob/db69e902/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
index 702b848..fbe1a95 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
@@ -99,7 +99,7 @@ public class GridCacheAffinityManager extends GridCacheManagerAdapter {
 
         IgniteInternalFuture<AffinityTopologyVersion> fut = aff.readyFuture(topVer);
 
-        return fut != null ? fut : new GridFinishedFuture<>(topVer);
+        return fut != null ? fut : cctx.shared().exchange().lastFinishedFuture();
     }
 
     /**


[30/50] [abbrv] ignite git commit: IGNITE-6529 JDBC: support column metadata 'nullable' property. This closes #2793.

Posted by ag...@apache.org.
IGNITE-6529 JDBC: support column metadata 'nullable' property. This closes #2793.


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

Branch: refs/heads/ignite-6305
Commit: c116bfc68a05376285946b8eae10ed6e51f848e0
Parents: e98e392
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Thu Oct 5 11:55:26 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Thu Oct 5 11:55:26 2017 +0300

----------------------------------------------------------------------
 .../internal/jdbc2/JdbcMetadataSelfTest.java    |  28 ++--
 .../jdbc/thin/JdbcThinMetadataSelfTest.java     |  33 ++--
 .../jdbc/thin/JdbcThinDatabaseMetadata.java     |   3 +-
 .../internal/jdbc/thin/JdbcThinTcpIo.java       |   4 +-
 .../internal/jdbc2/JdbcDatabaseMetadata.java    |  70 +++++++--
 .../cache/query/GridCacheQueryManager.java      |  87 ++++++++++-
 .../query/GridCacheQuerySqlMetadataJobV2.java   | 154 +++++++++++++++++++
 .../query/GridCacheQuerySqlMetadataV2.java      | 101 ++++++++++++
 .../cache/query/GridCacheSqlMetadata.java       |   8 +
 .../processors/odbc/jdbc/JdbcColumnMeta.java    |  10 ++
 .../processors/odbc/jdbc/JdbcColumnMetaV2.java  |  74 +++++++++
 .../odbc/jdbc/JdbcConnectionContext.java        |   4 +-
 .../odbc/jdbc/JdbcMetaColumnsResult.java        |  28 +++-
 .../odbc/jdbc/JdbcMetaColumnsResultV2.java      |  50 ++++++
 .../odbc/jdbc/JdbcRequestHandler.java           |  32 +++-
 .../processors/odbc/jdbc/JdbcResult.java        |   8 +
 16 files changed, 642 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMetadataSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMetadataSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMetadataSelfTest.java
index 6020a3a..bdc6644 100755
--- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMetadataSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMetadataSelfTest.java
@@ -42,7 +42,7 @@ import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.ConnectorConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteVersionUtils;
-import org.apache.ignite.internal.binary.BinaryMarshaller;
+import org.apache.ignite.internal.processors.query.QueryEntityEx;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
@@ -78,11 +78,16 @@ public class JdbcMetadataSelfTest extends GridCommonAbstractTest {
 
         cfg.setCacheConfiguration(
             cacheConfiguration("pers").setQueryEntities(Arrays.asList(
-                new QueryEntity(AffinityKey.class, Person.class)
-                    .setIndexes(Arrays.asList(
-                        new QueryIndex("orgId"),
-                        new QueryIndex().setFields(persFields))))
-            ),
+                new QueryEntityEx(
+                    new QueryEntity(AffinityKey.class.getName(), Person.class.getName())
+                        .addQueryField("name", String.class.getName(), null)
+                        .addQueryField("age", Integer.class.getName(), null)
+                        .addQueryField("orgId", Integer.class.getName(), null)
+                        .setIndexes(Arrays.asList(
+                            new QueryIndex("orgId"),
+                            new QueryIndex().setFields(persFields))))
+                    .setNotNullFields(new HashSet<>(Arrays.asList("age", "name")))
+            )),
             cacheConfiguration("org").setQueryEntities(Arrays.asList(
                 new QueryEntity(AffinityKey.class, Organization.class))));
 
@@ -208,7 +213,6 @@ public class JdbcMetadataSelfTest extends GridCommonAbstractTest {
      * @throws Exception If failed.
      */
     public void testGetColumns() throws Exception {
-        final boolean primitivesInformationIsLostAfterStore = ignite(0).configuration().getMarshaller() instanceof BinaryMarshaller;
         try (Connection conn = DriverManager.getConnection(BASE_URL)) {
             DatabaseMetaData meta = conn.getMetaData();
 
@@ -232,11 +236,15 @@ public class JdbcMetadataSelfTest extends GridCommonAbstractTest {
                 if ("NAME".equals(name)) {
                     assertEquals(VARCHAR, rs.getInt("DATA_TYPE"));
                     assertEquals("VARCHAR", rs.getString("TYPE_NAME"));
-                    assertEquals(1, rs.getInt("NULLABLE"));
-                } else if ("AGE".equals(name) || "ORGID".equals(name)) {
+                    assertEquals(0, rs.getInt("NULLABLE"));
+                } else if ("AGE".equals(name)) {
+                    assertEquals(INTEGER, rs.getInt("DATA_TYPE"));
+                    assertEquals("INTEGER", rs.getString("TYPE_NAME"));
+                    assertEquals(0, rs.getInt("NULLABLE"));
+                } else if ("ORGID".equals(name)) {
                     assertEquals(INTEGER, rs.getInt("DATA_TYPE"));
                     assertEquals("INTEGER", rs.getString("TYPE_NAME"));
-                    assertEquals(primitivesInformationIsLostAfterStore ? 1 : 0, rs.getInt("NULLABLE"));
+                    assertEquals(1, rs.getInt("NULLABLE"));
                 }
 
                 cnt++;

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
index 01b2e8a..abbe4e1 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
@@ -41,7 +41,7 @@ import org.apache.ignite.cache.affinity.AffinityKey;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteVersionUtils;
-import org.apache.ignite.internal.binary.BinaryMarshaller;
+import org.apache.ignite.internal.processors.query.QueryEntityEx;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
@@ -118,13 +118,15 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest {
         persFields.put("age", false);
 
         IgniteCache<AffinityKey, Person> personCache = jcache(grid(0), cacheConfiguration(
-            new QueryEntity(AffinityKey.class.getName(), Person.class.getName())
-                .addQueryField("name", String.class.getName(), null)
-                .addQueryField("age", Integer.class.getName(), null)
-                .addQueryField("orgId", Integer.class.getName(), null)
-                .setIndexes(Arrays.asList(
-                    new QueryIndex("orgId"),
-                    new QueryIndex().setFields(persFields)))
+            new QueryEntityEx(
+                new QueryEntity(AffinityKey.class.getName(), Person.class.getName())
+                    .addQueryField("name", String.class.getName(), null)
+                    .addQueryField("age", Integer.class.getName(), null)
+                    .addQueryField("orgId", Integer.class.getName(), null)
+                    .setIndexes(Arrays.asList(
+                        new QueryIndex("orgId"),
+                        new QueryIndex().setFields(persFields))))
+                .setNotNullFields(new HashSet<>(Arrays.asList("age", "name")))
             ), "pers");
 
         assert personCache != null;
@@ -251,9 +253,6 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest {
      * @throws Exception If failed.
      */
     public void testGetColumns() throws Exception {
-        final boolean primitivesInformationIsLostAfterStore = ignite(0).configuration().getMarshaller()
-            instanceof BinaryMarshaller;
-
         try (Connection conn = DriverManager.getConnection(URL)) {
             conn.setSchema("pers");
 
@@ -279,18 +278,22 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest {
                 if ("NAME".equals(name)) {
                     assert rs.getInt("DATA_TYPE") == VARCHAR;
                     assert "VARCHAR".equals(rs.getString("TYPE_NAME"));
+                    assert rs.getInt("NULLABLE") == 0;
+                } else if ("ORGID".equals(name)) {
+                    assert rs.getInt("DATA_TYPE") == INTEGER;
+                    assert "INTEGER".equals(rs.getString("TYPE_NAME"));
                     assert rs.getInt("NULLABLE") == 1;
-                } else if ("AGE".equals(name) || "ORGID".equals(name)) {
+                } else if ("AGE".equals(name)) {
                     assert rs.getInt("DATA_TYPE") == INTEGER;
                     assert "INTEGER".equals(rs.getString("TYPE_NAME"));
-                    assertEquals(primitivesInformationIsLostAfterStore ? 1 : 0, rs.getInt("NULLABLE"));
+                    assert rs.getInt("NULLABLE") == 0;
                 }
-                if ("_KEY".equals(name)) {
+                else if ("_KEY".equals(name)) {
                     assert rs.getInt("DATA_TYPE") == OTHER;
                     assert "OTHER".equals(rs.getString("TYPE_NAME"));
                     assert rs.getInt("NULLABLE") == 0;
                 }
-                if ("_VAL".equals(name)) {
+                else if ("_VAL".equals(name)) {
                     assert rs.getInt("DATA_TYPE") == OTHER;
                     assert "OTHER".equals(rs.getString("TYPE_NAME"));
                     assert rs.getInt("NULLABLE") == 0;

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java
index 2ce7983..8b26900 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java
@@ -29,7 +29,6 @@ import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import org.apache.ignite.internal.IgniteVersionUtils;
-import org.apache.ignite.internal.jdbc2.JdbcUtils;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcColumnMeta;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcIndexMeta;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaColumnsRequest;
@@ -845,7 +844,7 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData {
         row.add((Integer)null);
         row.add((Integer)null);
         row.add(10);
-        row.add(JdbcUtils.nullable(colMeta.columnName(), colMeta.dataTypeClass()) ? 1 : 0 );
+        row.add(colMeta.isNullable() ? 1 : 0);
         row.add((String)null);
         row.add((String)null);
         row.add(Integer.MAX_VALUE);

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
index 7ac9c2c..688f908 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
@@ -50,10 +50,10 @@ public class JdbcThinTcpIo {
     private static final ClientListenerProtocolVersion VER_2_1_0 = ClientListenerProtocolVersion.create(2, 1, 0);
 
     /** Version 2.3.1. */
-    private static final ClientListenerProtocolVersion VER_2_3_1 = ClientListenerProtocolVersion.create(2, 3, 1);
+    private static final ClientListenerProtocolVersion VER_2_3_0 = ClientListenerProtocolVersion.create(2, 3, 0);
 
     /** Current version. */
-    private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_3_1;
+    private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_3_0;
 
     /** Initial output stream capacity for handshake. */
     private static final int HANDSHAKE_MSG_SIZE = 13;

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcDatabaseMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcDatabaseMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcDatabaseMetadata.java
index 4c21cbd..03fde79 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcDatabaseMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcDatabaseMetadata.java
@@ -26,6 +26,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -59,7 +60,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     private final JdbcConnection conn;
 
     /** Metadata. */
-    private Map<String, Map<String, Map<String, String>>> meta;
+    private Map<String, Map<String, Map<String, ColumnInfo>>> meta;
 
     /** Index info. */
     private Collection<List<Object>> indexes;
@@ -714,7 +715,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
         List<List<?>> rows = new LinkedList<>();
 
         if (validCatalogPattern(catalog) && (tblTypes == null || Arrays.asList(tblTypes).contains("TABLE"))) {
-            for (Map.Entry<String, Map<String, Map<String, String>>> schema : meta.entrySet()) {
+            for (Map.Entry<String, Map<String, Map<String, ColumnInfo>>> schema : meta.entrySet()) {
                 if (matches(schema.getKey(), schemaPtrn)) {
                     for (String tbl : schema.getValue().keySet()) {
                         if (matches(tbl, tblNamePtrn))
@@ -796,14 +797,14 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
         int cnt = 0;
 
         if (validCatalogPattern(catalog)) {
-            for (Map.Entry<String, Map<String, Map<String, String>>> schema : meta.entrySet()) {
+            for (Map.Entry<String, Map<String, Map<String, ColumnInfo>>> schema : meta.entrySet()) {
                 if (matches(schema.getKey(), schemaPtrn)) {
-                    for (Map.Entry<String, Map<String, String>> tbl : schema.getValue().entrySet()) {
+                    for (Map.Entry<String, Map<String, ColumnInfo>> tbl : schema.getValue().entrySet()) {
                         if (matches(tbl.getKey(), tblNamePtrn)) {
-                            for (Map.Entry<String, String> col : tbl.getValue().entrySet()) {
+                            for (Map.Entry<String, ColumnInfo> col : tbl.getValue().entrySet()) {
                                 rows.add(columnRow(schema.getKey(), tbl.getKey(), col.getKey(),
-                                    JdbcUtils.type(col.getValue()), JdbcUtils.typeName(col.getValue()),
-                                    JdbcUtils.nullable(col.getKey(), col.getValue()), ++cnt));
+                                    JdbcUtils.type(col.getValue().typeName()), JdbcUtils.typeName(col.getValue().typeName()),
+                                    !col.getValue().isNotNull(), ++cnt));
                             }
                         }
                     }
@@ -925,9 +926,9 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
         List<List<?>> rows = new LinkedList<>();
 
         if (validCatalogPattern(catalog)) {
-            for (Map.Entry<String, Map<String, Map<String, String>>> schema : meta.entrySet()) {
+            for (Map.Entry<String, Map<String, Map<String, ColumnInfo>>> schema : meta.entrySet()) {
                 if (matches(schema.getKey(), schemaPtrn)) {
-                    for (Map.Entry<String, Map<String, String>> tbl : schema.getValue().entrySet()) {
+                    for (Map.Entry<String, Map<String, ColumnInfo>> tbl : schema.getValue().entrySet()) {
                         if (matches(tbl.getKey(), tblNamePtrn))
                             rows.add(Arrays.<Object>asList(null, schema.getKey(), tbl.getKey(), "_KEY", 1, "_KEY"));
                     }
@@ -1361,10 +1362,21 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
                 Collection<String> types = m.types();
 
-                Map<String, Map<String, String>> typesMap = U.newHashMap(types.size());
+                Map<String, Map<String, ColumnInfo>> typesMap = U.newHashMap(types.size());
 
                 for (String type : types) {
-                    typesMap.put(type.toUpperCase(), m.fields(type));
+                    Collection<String> notNullFields = m.notNullFields(type);
+
+                    Map<String, ColumnInfo> fields = new LinkedHashMap<>();
+
+                    for (Map.Entry<String, String> fld : m.fields(type).entrySet()) {
+                        ColumnInfo colInfo = new ColumnInfo(fld.getValue(),
+                            notNullFields == null ? false : notNullFields.contains(fld.getKey()));
+
+                        fields.put(fld.getKey(), colInfo);
+                    }
+
+                    typesMap.put(type.toUpperCase(), fields);
 
                     for (GridCacheSqlIndexMetadata idx : m.indexes(type)) {
                         int cnt = 0;
@@ -1435,7 +1447,41 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
         @Override public Collection<GridCacheSqlMetadata> call() throws Exception {
             IgniteCache cache = ignite.cache(cacheName);
 
-            return ((IgniteCacheProxy)cache).context().queries().sqlMetadata();
+            return ((IgniteCacheProxy)cache).context().queries().sqlMetadataV2();
+        }
+    }
+
+    /**
+     * Column info.
+     */
+    private static class ColumnInfo {
+        /** Class name. */
+        private final String typeName;
+
+        /** Not null flag. */
+        private final boolean notNull;
+
+        /**
+         * @param typeName Type name.
+         * @param notNull Not null flag.
+         */
+        private ColumnInfo(String typeName, boolean notNull) {
+            this.typeName = typeName;
+            this.notNull = notNull;
+        }
+
+        /**
+         * @return Type name.
+         */
+        public String typeName() {
+            return typeName;
+        }
+
+        /**
+         * @return Not null flag.
+         */
+        public boolean isNotNull() {
+            return notNull;
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
index f873461..64e74fb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryManager.java
@@ -113,6 +113,7 @@ import org.apache.ignite.lang.IgniteBiPredicate;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgniteCallable;
 import org.apache.ignite.lang.IgniteClosure;
+import org.apache.ignite.lang.IgniteProductVersion;
 import org.apache.ignite.lang.IgniteReducer;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.resources.IgniteInstanceResource;
@@ -145,6 +146,9 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
     /** Maximum number of query detail metrics to evict at once. */
     private static final int QRY_DETAIL_METRICS_EVICTION_LIMIT = 10_000;
 
+    /** Support 'not null' field constraint since v 2.3.0. */
+    private static final IgniteProductVersion NOT_NULLS_SUPPORT_VER = IgniteProductVersion.fromString("2.3.0");
+
     /** Comparator for priority queue with query detail metrics with priority to new metrics. */
     private static final Comparator<GridCacheQueryDetailMetricsAdapter> QRY_DETAIL_METRICS_PRIORITY_NEW_CMP =
         new Comparator<GridCacheQueryDetailMetricsAdapter>() {
@@ -1908,6 +1912,79 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
     }
 
     /**
+     * Gets SQL metadata with not nulls fields.
+     *
+     * @return SQL metadata.
+     * @throws IgniteCheckedException In case of error.
+     */
+    public Collection<GridCacheSqlMetadata> sqlMetadataV2() throws IgniteCheckedException {
+        if (!enterBusy())
+            throw new IllegalStateException("Failed to get metadata (grid is stopping).");
+
+        try {
+            Callable<Collection<CacheSqlMetadata>> job = new GridCacheQuerySqlMetadataJobV2();
+
+            // Remote nodes that have current cache.
+            Collection<ClusterNode> nodes = CU.affinityNodes(cctx, AffinityTopologyVersion.NONE);
+
+            Collection<Collection<CacheSqlMetadata>> res = new ArrayList<>(nodes.size() + 1);
+
+            IgniteInternalFuture<Collection<Collection<CacheSqlMetadata>>> rmtFut = null;
+
+            // Get metadata from remote nodes.
+            if (!nodes.isEmpty()) {
+                boolean allNodesNew = true;
+
+                for (ClusterNode n : nodes) {
+                    if (n.version().compareTo(NOT_NULLS_SUPPORT_VER) < 0)
+                        allNodesNew = false;
+                }
+
+                if (!allNodesNew)
+                    return sqlMetadata();
+
+                rmtFut = cctx.closures().callAsyncNoFailover(BROADCAST, Collections.singleton(job), nodes, true, 0);
+            }
+
+            // Get local metadata.
+            IgniteInternalFuture<Collection<CacheSqlMetadata>> locFut = cctx.closures().callLocalSafe(job, true);
+
+            if (rmtFut != null)
+                res.addAll(rmtFut.get());
+
+            res.add(locFut.get());
+
+            Map<String, Collection<CacheSqlMetadata>> map = new HashMap<>();
+
+            for (Collection<CacheSqlMetadata> col : res) {
+                for (CacheSqlMetadata meta : col) {
+                    String name = meta.cacheName();
+
+                    Collection<CacheSqlMetadata> cacheMetas = map.get(name);
+
+                    if (cacheMetas == null)
+                        map.put(name, cacheMetas = new LinkedList<>());
+
+                    cacheMetas.add(meta);
+                }
+            }
+
+            Collection<GridCacheSqlMetadata> col = new ArrayList<>(map.size());
+
+            // Metadata for current cache must be first in list.
+            col.add(new GridCacheQuerySqlMetadataV2(map.remove(cacheName)));
+
+            for (Collection<CacheSqlMetadata> metas : map.values())
+                col.add(new GridCacheQuerySqlMetadataV2(metas));
+
+            return col;
+        }
+        finally {
+            leaveBusy();
+        }
+    }
+
+    /**
      * @param <K> Key type.
      * @param <V> Value type.
      * @param includeBackups Include backups.
@@ -2079,7 +2156,7 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
     /**
      * Cache metadata.
      */
-    private static class CacheSqlMetadata implements GridCacheSqlMetadata {
+    public static class CacheSqlMetadata implements GridCacheSqlMetadata {
         /** */
         private static final long serialVersionUID = 0L;
 
@@ -2183,6 +2260,11 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
         }
 
         /** {@inheritDoc} */
+        @Override public Collection<String> notNullFields(String type) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
         @Override public Map<String, String> keyClasses() {
             return keyClasses;
         }
@@ -2236,7 +2318,7 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
     /**
      * Cache metadata index.
      */
-    private static class CacheSqlIndexMetadata implements GridCacheSqlIndexMetadata {
+    public static class CacheSqlIndexMetadata implements GridCacheSqlIndexMetadata {
         /** */
         private static final long serialVersionUID = 0L;
 
@@ -2371,6 +2453,7 @@ public abstract class GridCacheQueryManager<K, V> extends GridCacheManagerAdapte
 
         /**
          * @return Metadata.
+         * @throws IgniteCheckedException On error.
          */
         public List<GridQueryFieldMetadata> metaData() throws IgniteCheckedException {
             get(); // Ensure that result is ready.

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQuerySqlMetadataJobV2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQuerySqlMetadataJobV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQuerySqlMetadataJobV2.java
new file mode 100644
index 0000000..9907d1a
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQuerySqlMetadataJobV2.java
@@ -0,0 +1,154 @@
+/*
+ * 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.query;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.IgniteKernal;
+import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
+import org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor;
+import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
+import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
+import org.apache.ignite.internal.processors.task.GridInternal;
+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.internal.CU;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteCallable;
+import org.apache.ignite.resources.IgniteInstanceResource;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Metadata job.
+ */
+@GridInternal
+class GridCacheQuerySqlMetadataJobV2 implements IgniteCallable<Collection<GridCacheQueryManager.CacheSqlMetadata>> {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Number of fields to report when no fields defined. Includes _key and _val columns. */
+    private static final int NO_FIELDS_COLUMNS_COUNT = 2;
+
+    /** Grid */
+    @IgniteInstanceResource
+    private Ignite ignite;
+
+    /** {@inheritDoc} */
+    @Override public Collection<GridCacheQueryManager.CacheSqlMetadata> call() {
+        final GridKernalContext ctx = ((IgniteKernal)ignite).context();
+
+        Collection<String> cacheNames = F.viewReadOnly(ctx.cache().caches(),
+            new C1<IgniteInternalCache<?, ?>, String>() {
+                @Override public String apply(IgniteInternalCache<?, ?> c) {
+                    return c.name();
+                }
+            },
+            new P1<IgniteInternalCache<?, ?>>() {
+                @Override public boolean apply(IgniteInternalCache<?, ?> c) {
+                    return !CU.isSystemCache(c.name()) && !DataStructuresProcessor.isDataStructureCache(c.name());
+                }
+            }
+        );
+
+        return F.transform(cacheNames, new C1<String, GridCacheQueryManager.CacheSqlMetadata>() {
+            @Override public GridCacheQueryManager.CacheSqlMetadata apply(String cacheName) {
+                Collection<GridQueryTypeDescriptor> types = ctx.query().types(cacheName);
+
+                Collection<String> names = U.newHashSet(types.size());
+                Map<String, String> keyClasses = U.newHashMap(types.size());
+                Map<String, String> valClasses = U.newHashMap(types.size());
+                Map<String, Map<String, String>> fields = U.newHashMap(types.size());
+                Map<String, Collection<GridCacheSqlIndexMetadata>> indexes = U.newHashMap(types.size());
+                Map<String, Set<String>> notNullFields = U.newHashMap(types.size());
+
+                for (GridQueryTypeDescriptor type : types) {
+                    // Filter internal types (e.g., data structures).
+                    if (type.name().startsWith("GridCache"))
+                        continue;
+
+                    names.add(type.name());
+
+                    keyClasses.put(type.name(), type.keyClass().getName());
+                    valClasses.put(type.name(), type.valueClass().getName());
+
+                    int size = type.fields().isEmpty() ? NO_FIELDS_COLUMNS_COUNT : type.fields().size();
+
+                    Map<String, String> fieldsMap = U.newLinkedHashMap(size);
+                    HashSet<String> notNullFieldsSet = U.newHashSet(1);
+
+                    // _KEY and _VAL are not included in GridIndexingTypeDescriptor.valueFields
+                    if (type.fields().isEmpty()) {
+                        fieldsMap.put("_KEY", type.keyClass().getName());
+                        fieldsMap.put("_VAL", type.valueClass().getName());
+                    }
+
+                    for (Map.Entry<String, Class<?>> e : type.fields().entrySet()) {
+                        String fieldName = e.getKey();
+
+                        fieldsMap.put(fieldName.toUpperCase(), e.getValue().getName());
+
+                        if (type.property(fieldName).notNull())
+                            notNullFieldsSet.add(fieldName.toUpperCase());
+                    }
+
+                    fields.put(type.name(), fieldsMap);
+                    notNullFields.put(type.name(), notNullFieldsSet);
+
+                    Map<String, GridQueryIndexDescriptor> idxs = type.indexes();
+
+                    Collection<GridCacheSqlIndexMetadata> indexesCol = new ArrayList<>(idxs.size());
+
+                    for (Map.Entry<String, GridQueryIndexDescriptor> e : idxs.entrySet()) {
+                        GridQueryIndexDescriptor desc = e.getValue();
+
+                        // Add only SQL indexes.
+                        if (desc.type() == QueryIndexType.SORTED) {
+                            Collection<String> idxFields = new LinkedList<>();
+                            Collection<String> descendings = new LinkedList<>();
+
+                            for (String idxField : e.getValue().fields()) {
+                                String idxFieldUpper = idxField.toUpperCase();
+
+                                idxFields.add(idxFieldUpper);
+
+                                if (desc.descending(idxField))
+                                    descendings.add(idxFieldUpper);
+                            }
+
+                            indexesCol.add(new GridCacheQueryManager.CacheSqlIndexMetadata(e.getKey().toUpperCase(),
+                                idxFields, descendings, false));
+                        }
+                    }
+
+                    indexes.put(type.name(), indexesCol);
+                }
+
+                return new GridCacheQuerySqlMetadataV2(cacheName, names, keyClasses, valClasses, fields, indexes,
+                    notNullFields);
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQuerySqlMetadataV2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQuerySqlMetadataV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQuerySqlMetadataV2.java
new file mode 100644
index 0000000..66821c9
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQuerySqlMetadataV2.java
@@ -0,0 +1,101 @@
+/*
+ * 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.query;
+
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Cache metadata with not null field.
+ */
+public class GridCacheQuerySqlMetadataV2 extends GridCacheQueryManager.CacheSqlMetadata {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Not null fields. */
+    private Map<String, Set<String>> notNullFields;
+
+    /**
+     * Required by {@link Externalizable}.
+     */
+    public GridCacheQuerySqlMetadataV2() {
+        // No-op.
+    }
+
+    /**
+     * @param cacheName Cache name.
+     * @param types Types.
+     * @param keyClasses Key classes map.
+     * @param valClasses Value classes map.
+     * @param fields Fields maps.
+     * @param indexes Indexes.
+     * @param notNullFields Not null fields.
+     */
+    GridCacheQuerySqlMetadataV2(@Nullable String cacheName, Collection<String> types, Map<String, String> keyClasses,
+        Map<String, String> valClasses, Map<String, Map<String, String>> fields,
+        Map<String, Collection<GridCacheSqlIndexMetadata>> indexes, Map<String, Set<String>> notNullFields) {
+        super(cacheName, types, keyClasses, valClasses, fields, indexes);
+
+        this.notNullFields = notNullFields;
+    }
+
+    /**
+     * @param metas Meta data instances from different nodes.
+     */
+    GridCacheQuerySqlMetadataV2(Iterable<GridCacheQueryManager.CacheSqlMetadata> metas) {
+        super(metas);
+
+        notNullFields = new HashMap<>();
+
+        for (GridCacheQueryManager.CacheSqlMetadata meta : metas) {
+            if (meta instanceof GridCacheQuerySqlMetadataV2) {
+                GridCacheQuerySqlMetadataV2 metaV2 = (GridCacheQuerySqlMetadataV2)meta;
+
+                notNullFields.putAll(metaV2.notNullFields);
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<String> notNullFields(String type) {
+        return notNullFields.get(type);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeExternal(ObjectOutput out) throws IOException {
+        super.writeExternal(out);
+
+        U.writeMap(out, notNullFields);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        super.readExternal(in);
+
+        notNullFields = U.readHashMap(in);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/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..ddc2860 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
@@ -78,6 +78,14 @@ public interface GridCacheSqlMetadata extends Externalizable {
     @Nullable public Map<String, String> fields(String type);
 
     /**
+     * Gets not null fields.
+     *
+     * @param type Type name.
+     * @return Not null fields collection map or {@code null} if type name is unknown.
+     */
+    Collection<String> notNullFields(String type);
+
+    /**
      * @return Key classes.
      */
     public Map<String, String> keyClasses();

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java
index 9f145e0..d927c26 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.odbc.jdbc;
 import org.apache.ignite.internal.binary.BinaryReaderExImpl;
 import org.apache.ignite.internal.binary.BinaryWriterExImpl;
 import org.apache.ignite.internal.jdbc.thin.JdbcThinUtils;
+import org.apache.ignite.internal.jdbc2.JdbcUtils;
 import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
@@ -126,6 +127,15 @@ public class JdbcColumnMeta implements JdbcRawBinarylizable {
         return dataTypeClass;
     }
 
+    /**
+     * Return 'nullable' flag in compatibility mode (according with column name and column type).
+     *
+     * @return {@code true} in case the column allows null values. Otherwise returns {@code false}
+     */
+    public boolean isNullable() {
+        return JdbcUtils.nullable(colName, dataTypeClass);
+    }
+
     /** {@inheritDoc} */
     @Override public void writeBinary(BinaryWriterExImpl writer) {
         writer.writeString(schemaName);

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMetaV2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMetaV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMetaV2.java
new file mode 100644
index 0000000..a2b4acf
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMetaV2.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.odbc.jdbc;
+
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC column metadata.
+ */
+public class JdbcColumnMetaV2 extends JdbcColumnMeta{
+    /** Allow nulls . */
+    private boolean nullable;
+
+    /**
+     * Default constructor is used for serialization.
+     */
+    JdbcColumnMetaV2() {
+        // No-op.
+    }
+
+    /**
+     * @param schemaName Schema.
+     * @param tblName Table.
+     * @param colName Column.
+     * @param cls Type.
+     * @param nullable Allow nulls.
+     */
+    public JdbcColumnMetaV2(String schemaName, String tblName, String colName, Class<?> cls, boolean nullable) {
+        super(schemaName, tblName, colName, cls);
+
+        this.nullable = nullable;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isNullable() {
+        return nullable;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) {
+        super.writeBinary(writer);
+
+        writer.writeBoolean(nullable);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) {
+        super.readBinary(reader);
+
+        nullable = reader.readBoolean();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcColumnMetaV2.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java
index 38d1972..a6a7aa5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java
@@ -38,10 +38,10 @@ public class JdbcConnectionContext implements ClientListenerConnectionContext {
     private static final ClientListenerProtocolVersion VER_2_1_5 = ClientListenerProtocolVersion.create(2, 1, 5);
 
     /** Version 2.3.1: added "multiple statements query" feature. */
-    public static final ClientListenerProtocolVersion VER_2_3_1 = ClientListenerProtocolVersion.create(2, 3, 1);
+    public static final ClientListenerProtocolVersion VER_2_3_0 = ClientListenerProtocolVersion.create(2, 3, 0);
 
     /** Current version. */
-    private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_3_1;
+    private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_3_0;
 
     /** Supported versions. */
     private static final Set<ClientListenerProtocolVersion> SUPPORTED_VERS = new HashSet<>();

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResult.java
index da270de..9931ce0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResult.java
@@ -51,6 +51,25 @@ public class JdbcMetaColumnsResult extends JdbcResult {
     }
 
     /**
+     * Used by children classes.
+     * @param type Type ID.
+     */
+    protected JdbcMetaColumnsResult(byte type) {
+        super(type);
+    }
+
+    /**
+     * Used by children classes.
+     * @param type Type ID.
+     * @param meta Columns metadata.
+     */
+    protected JdbcMetaColumnsResult(byte type, Collection<JdbcColumnMeta> meta) {
+        super(type);
+
+        this.meta = new ArrayList<>(meta);
+    }
+
+    /**
      * @return Columns metadata.
      */
     public List<JdbcColumnMeta> meta() {
@@ -83,7 +102,7 @@ public class JdbcMetaColumnsResult extends JdbcResult {
             meta = new ArrayList<>(size);
 
             for (int i = 0; i < size; ++i) {
-                JdbcColumnMeta m = new JdbcColumnMeta();
+                JdbcColumnMeta m = createMetaColumn();
 
                 m.readBinary(reader);
 
@@ -92,6 +111,13 @@ public class JdbcMetaColumnsResult extends JdbcResult {
         }
     }
 
+    /**
+     * @return Empty columns metadata to deserialization.
+     */
+    protected JdbcColumnMeta createMetaColumn() {
+        return new JdbcColumnMeta();
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(JdbcMetaColumnsResult.class, this);

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResultV2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResultV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResultV2.java
new file mode 100644
index 0000000..2673a13
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResultV2.java
@@ -0,0 +1,50 @@
+/*
+ * 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.odbc.jdbc;
+
+import java.util.Collection;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC columns metadata result.
+ */
+public class JdbcMetaColumnsResultV2 extends JdbcMetaColumnsResult {
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaColumnsResultV2() {
+        super(META_COLUMNS_V2);
+    }
+
+    /**
+     * @param meta Columns metadata.
+     */
+    JdbcMetaColumnsResultV2(Collection<JdbcColumnMeta> meta) {
+        super(META_COLUMNS_V2, meta);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected JdbcColumnMeta createMetaColumn() {
+        return new JdbcColumnMetaV2();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaColumnsResultV2.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
index 202f813..166402f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
@@ -23,6 +23,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -43,6 +44,7 @@ import org.apache.ignite.internal.processors.odbc.ClientListenerRequestHandler;
 import org.apache.ignite.internal.processors.odbc.ClientListenerResponse;
 import org.apache.ignite.internal.processors.odbc.odbc.OdbcQueryGetColumnsMetaRequest;
 import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
+import org.apache.ignite.internal.processors.query.GridQueryProperty;
 import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
 import org.apache.ignite.internal.processors.query.IgniteSQLException;
 import org.apache.ignite.internal.processors.query.QueryUtils;
@@ -51,6 +53,7 @@ import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 
+import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcConnectionContext.VER_2_3_0;
 import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.BATCH_EXEC;
 import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.META_COLUMNS;
 import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.META_INDEXES;
@@ -291,7 +294,7 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
             qry.setSchema(schemaName);
 
             List<FieldsQueryCursor<List<?>>> results = ctx.query().querySqlFieldsNoCache(qry, true,
-                protocolVer.compareTo(JdbcConnectionContext.VER_2_3_1) < 0);
+                protocolVer.compareTo(VER_2_3_0) < 0);
 
             if (results.size() == 1) {
                 FieldsQueryCursor<List<?>> qryCur = results.get(0);
@@ -559,9 +562,10 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
      * @param req Get columns metadata request.
      * @return Response.
      */
+    @SuppressWarnings("unchecked")
     private JdbcResponse getColumnsMeta(JdbcMetaColumnsRequest req) {
         try {
-            Collection<JdbcColumnMeta> meta = new HashSet<>();
+            Collection<JdbcColumnMeta> meta = new LinkedHashSet<>();
 
             for (String cacheName : ctx.cache().publicCacheNames()) {
                 for (GridQueryTypeDescriptor table : ctx.query().types(cacheName)) {
@@ -572,11 +576,22 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
                         continue;
 
                     for (Map.Entry<String, Class<?>> field : table.fields().entrySet()) {
-                        if (!matches(field.getKey(), req.columnName()))
+                        String colName = field.getKey();
+
+                        if (!matches(colName, req.columnName()))
                             continue;
 
-                        JdbcColumnMeta columnMeta = new JdbcColumnMeta(table.schemaName(), table.tableName(),
-                            field.getKey(), field.getValue());
+                        JdbcColumnMeta columnMeta;
+
+                        if (protocolVer.compareTo(VER_2_3_0) >= 0) {
+                            GridQueryProperty prop = table.property(colName);
+
+                            columnMeta = new JdbcColumnMetaV2(table.schemaName(), table.tableName(),
+                                field.getKey(), field.getValue(), !prop.notNull());
+                        }
+                        else
+                            columnMeta = new JdbcColumnMeta(table.schemaName(), table.tableName(),
+                                field.getKey(), field.getValue());
 
                         if (!meta.contains(columnMeta))
                             meta.add(columnMeta);
@@ -584,7 +599,12 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
                 }
             }
 
-            JdbcMetaColumnsResult res = new JdbcMetaColumnsResult(meta);
+            JdbcMetaColumnsResult res;
+
+            if (protocolVer.compareTo(VER_2_3_0) >= 0)
+                res = new JdbcMetaColumnsResultV2(meta);
+            else
+                res = new JdbcMetaColumnsResult(meta);
 
             return new JdbcResponse(res);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/c116bfc6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
index c6c7438..6d460e6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
@@ -59,6 +59,9 @@ public class JdbcResult implements JdbcRawBinarylizable {
     /** Multiple statements query results. */
     static final byte QRY_EXEC_MULT = 13;
 
+    /** Columns metadata result V2. */
+    static final byte META_COLUMNS_V2 = 14;
+
     /** Success status. */
     private byte type;
 
@@ -147,6 +150,11 @@ public class JdbcResult implements JdbcRawBinarylizable {
 
                 break;
 
+            case META_COLUMNS_V2:
+                res = new JdbcMetaColumnsResultV2();
+
+                break;
+
             default:
                 throw new IgniteException("Unknown SQL listener request ID: [request ID=" + resId + ']');
         }


[50/50] [abbrv] ignite git commit: ignite-6305 Review fixes

Posted by ag...@apache.org.
ignite-6305 Review fixes


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

Branch: refs/heads/ignite-6305
Commit: b7bcab44dd58a7444d140c64599ae78f8555094c
Parents: ca832d5
Author: Andrey Gura <ag...@apache.org>
Authored: Mon Oct 9 17:09:06 2017 +0300
Committer: Andrey Gura <ag...@apache.org>
Committed: Mon Oct 9 17:09:06 2017 +0300

----------------------------------------------------------------------
 .../processors/cluster/ClusterProcessor.java    |  4 +-
 .../processors/cluster/GridUpdateNotifier.java  | 44 ++++++++++++++++++--
 2 files changed, 42 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b7bcab44/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
index 7591911..5f2c66c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
@@ -38,7 +38,6 @@ import org.apache.ignite.internal.IgniteDiagnosticInfo;
 import org.apache.ignite.internal.IgniteDiagnosticMessage;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteKernal;
-import org.apache.ignite.internal.IgniteProperties;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.cluster.IgniteClusterImpl;
 import org.apache.ignite.internal.managers.communication.GridIoPolicy;
@@ -109,8 +108,7 @@ public class ClusterProcessor extends GridProcessorAdapter {
     public ClusterProcessor(GridKernalContext ctx) {
         super(ctx);
 
-        notifyEnabled.set(IgniteSystemProperties.getBoolean(IGNITE_UPDATE_NOTIFIER,
-            Boolean.parseBoolean(IgniteProperties.get("ignite.update.notifier.enabled.by.default"))));
+        notifyEnabled.set(IgniteSystemProperties.getBoolean(IGNITE_UPDATE_NOTIFIER, true));
 
         cluster = new IgniteClusterImpl(ctx);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b7bcab44/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifier.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifier.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifier.java
index e92f216..ff834f6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifier.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifier.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.processors.cluster;
 
 import java.io.IOException;
+import java.util.Comparator;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.ignite.IgniteCheckedException;
@@ -37,6 +38,9 @@ class GridUpdateNotifier {
     /** Default encoding. */
     private static final String CHARSET = "UTF-8";
 
+    /** Version comparator. */
+    private static final VersionComparator VER_COMPARATOR = new VersionComparator();
+
     /** Throttling for logging out. */
     private static final long THROTTLE_PERIOD = 24 * 60 * 60 * 1000; // 1 day.
 
@@ -186,13 +190,16 @@ class GridUpdateNotifier {
 
         downloadUrl = downloadUrl != null ? downloadUrl : IgniteKernal.SITE;
 
-        if (latestVer != null)
-            if (latestVer.equals(ver)) {
+        if (latestVer != null) {
+            int cmp = VER_COMPARATOR.compare(latestVer, ver);
+
+            if (cmp == 0) {
                 if (!reportOnlyNew)
                     throttle(log, false, "Your version is up to date.");
             }
-            else
+            else if (cmp > 0)
                 throttle(log, true, "New version is available at " + downloadUrl + ": " + latestVer);
+        }
         else
             if (!reportOnlyNew)
                 throttle(log, false, "Update status is not available.");
@@ -321,4 +328,35 @@ class GridUpdateNotifier {
             return obtainMeta("downloadUrl=", line);
         }
     }
+
+    /**
+     * Ignite version comparator.
+     */
+    private static final class VersionComparator implements Comparator<String> {
+        /** Dot pattern. */
+        private static final String DOT_PATTERN = "\\.";
+
+        /** Dash pattern. */
+        private static final String DASH_PATTERN = "-";
+
+        /** {@inheritDoc} */
+        @Override public int compare(String o1, String o2) {
+            if (o1.equals(o2))
+                return 0;
+
+            String[] ver1 = o1.split(DOT_PATTERN, 3);
+            String[] ver2 = o2.split(DOT_PATTERN, 3);
+
+            assert ver1.length == 3;
+            assert ver2.length == 3;
+
+            if (Integer.valueOf(ver1[0]) >= Integer.valueOf(ver2[0]) &&
+                Integer.valueOf(ver1[1]) >= Integer.valueOf(ver2[1]) &&
+                Integer.valueOf(ver1[2].split(DASH_PATTERN)[0]) >= Integer.valueOf(ver2[2].split(DASH_PATTERN)[0]))
+
+                return 1;
+            else
+                return -1;
+        }
+    }
 }


[17/50] [abbrv] ignite git commit: IGNITE-6382 .NET: Set up NDepend project

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/b21f750f/modules/platforms/dotnet/Apache.Ignite.ndproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.ndproj b/modules/platforms/dotnet/Apache.Ignite.ndproj
new file mode 100644
index 0000000..9f5287b
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.ndproj
@@ -0,0 +1,11139 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<NDepend AppName="Apache.Ignite" Platform="DotNet" FileWrittenByProductVersion="2017.2.2.8962">
+  <OutputDir KeepXmlFiles="False">c:\w\incubator-ignite\modules\platforms\dotnet\NDependOut</OutputDir>
+  <Assemblies>
+    <Name>Apache.Ignite.Core</Name>
+  </Assemblies>
+  <FrameworkAssemblies>
+    <Name>mscorlib</Name>
+    <Name>System.Core</Name>
+    <Name>System.Xml</Name>
+    <Name>System</Name>
+    <Name>System.Configuration</Name>
+    <Name>System.Transactions</Name>
+  </FrameworkAssemblies>
+  <Dirs>
+    <Dir>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319</Dir>
+    <Dir>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\WPF</Dir>
+    <Dir>$(NdProjectDir)\Apache.Ignite.Core\bin\Debug</Dir>
+  </Dirs>
+  <MergeCodeGeneratedByCompiler>True</MergeCodeGeneratedByCompiler>
+  <Report Kind="0" SectionsEnabled="110591" XslPath="" Flags="261120" />
+  <BuildComparisonSetting ProjectMode="CurrentProject" BuildMode="NDaysAgoAnalysisResult" ProjectFileToCompareWith="" BuildFileToCompareWith="" NDaysAgo="30" />
+  <BaselineInUISetting ProjectMode="CurrentProject" BuildMode="NDaysAgoAnalysisResult" ProjectFileToCompareWith="" BuildFileToCompareWith="" NDaysAgo="30" />
+  <CoverageFiles CoverageDir="" UncoverableAttribute="" />
+  <TrendMetrics UseCustomLog="False" LogRecurrence="3" LogLabel="2" UseCustomDir="False" CustomDir="">
+    <Chart Name="Size" ShowInReport="True">
+      <Serie MetricName="# Lines of Code" MetricUnit="Loc" Color="#FF00BFFF" ChartType="Line" ScaleExp="0" />
+      <Serie MetricName="# Lines of Code Covered" MetricUnit="Loc" Color="#FF32CD32" ChartType="Area" ScaleExp="0" />
+      <Serie MetricName="# Lines of Code (NotMyCode)" MetricUnit="Loc" Color="#FFA9A9A9" ChartType="Area" ScaleExp="0" />
+      <Serie MetricName="# Lines of Comments" MetricUnit="Lines" Color="#FF008000" ChartType="Line" ScaleExp="0" />
+    </Chart>
+    <Chart Name="% Coverage and % Debt" ShowInReport="True">
+      <Serie MetricName="Percentage Code Coverage" MetricUnit="%" Color="#FF32CD32" ChartType="Area" ScaleExp="0" />
+      <Serie MetricName="Percentage Debt (Metric)" MetricUnit="%" Color="#FFFF0000" ChartType="Line" ScaleExp="0" />
+    </Chart>
+    <Chart Name="Issues" ShowInReport="True">
+      <Serie MetricName="# New Issues since Baseline" MetricUnit="issues" Color="#FFFF0000" ChartType="Line" ScaleExp="0" />
+      <Serie MetricName="# Issues Fixed since Baseline" MetricUnit="issues" Color="#FF32CD32" ChartType="Line" ScaleExp="0" />
+      <Serie MetricName="# Blocker/Critical/Major Issues" MetricUnit="issues" Color="#FFFF8C00" ChartType="Line" ScaleExp="0" />
+      <Serie MetricName="# Issues" MetricUnit="issues" Color="#FFFFD700" ChartType="Line" ScaleExp="-2" />
+    </Chart>
+    <Chart Name="Rules" ShowInReport="True">
+      <Serie MetricName="# Rules" MetricUnit="Rules" Color="#FF66CDAA" ChartType="Line" ScaleExp="0" />
+      <Serie MetricName="# Rules Violated" MetricUnit="Rules" Color="#FFFF8C00" ChartType="Area" ScaleExp="0" />
+      <Serie MetricName="# Critical Rules Violated" MetricUnit="Rules" Color="#FFFF0000" ChartType="Area" ScaleExp="0" />
+    </Chart>
+    <Chart Name="Quality Gates" ShowInReport="True">
+      <Serie MetricName="# Quality Gates Fail" MetricUnit="quality gates" Color="#FFFF0000" ChartType="Line" ScaleExp="0" />
+      <Serie MetricName="# Quality Gates Warn" MetricUnit="quality gates" Color="#FFFF8C00" ChartType="Line" ScaleExp="0" />
+      <Serie MetricName="# Quality Gates" MetricUnit="quality gates" Color="#FF32CD32" ChartType="Line" ScaleExp="0" />
+    </Chart>
+    <Chart Name="Debt" ShowInReport="True">
+      <Serie MetricName="Debt (Metric)" MetricUnit="man-days" Color="#FFFF0000" ChartType="Line" ScaleExp="0" />
+      <Serie MetricName="Annual Interest (Metric)" MetricUnit="man-days" Color="#FFFF8C00" ChartType="Line" ScaleExp="0" />
+    </Chart>
+  </TrendMetrics>
+  <HistoricAnalysisResult PersistRecurrence="3" UseCustomDir="False" CustomDir="" />
+  <SourceFileRebasing FromPath="" ToPath="" />
+  <PathVariables />
+  <RuleFiles />
+  <ProjectRules AreActive="True" />
+  <ProjectDebtSettings DebtSettingsStorage="0" SettingsFilePath="">
+    <DebtSettings>
+      <DebtFactor>1</DebtFactor>
+      <AnnualInterestFactor>1</AnnualInterestFactor>
+      <DebtDefault>0</DebtDefault>
+      <AnnualInterestDefault>0</AnnualInterestDefault>
+      <DebtStringFormat>$ManDay$</DebtStringFormat>
+      <MoneyPerManHour>50</MoneyPerManHour>
+      <Currency>USD</Currency>
+      <CurrencyLocation>After</CurrencyLocation>
+      <EstimatedNumberOfManDayToDevelop1000LogicalLinesOfCode>18</EstimatedNumberOfManDayToDevelop1000LogicalLinesOfCode>
+      <NumberOfWorkDayPerYear>240</NumberOfWorkDayPerYear>
+      <NumberOfWorkHourPerDay>8</NumberOfWorkHourPerDay>
+      <A2B_RatingThreshold>5</A2B_RatingThreshold>
+      <B2C_RatingThreshold>10</B2C_RatingThreshold>
+      <C2D_RatingThreshold>20</C2D_RatingThreshold>
+      <D2E_RatingThreshold>50</D2E_RatingThreshold>
+      <Low2Medium_SeverityThreshold>1200000000</Low2Medium_SeverityThreshold>
+      <Medium2High_SeverityThreshold>12000000000</Medium2High_SeverityThreshold>
+      <High2Critical_SeverityThreshold>72000000000</High2Critical_SeverityThreshold>
+      <Critical2Blocker_SeverityThreshold>360000000000</Critical2Blocker_SeverityThreshold>
+    </DebtSettings>
+  </ProjectDebtSettings>
+  <Queries>
+    <Group Name="Quality Gates" Active="True" ShownInReport="True">
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Quality Gates Evolution</Name>
+from qg in QualityGates
+let qgBaseline = qg.OlderVersion()
+let relyOnDiff = qgBaseline == null
+let evolution = relyOnDiff ? (TrendIcon?)null : 
+                // When a quality gate relies on diff between now and baseline
+                // it is not executed against the baseline
+                qg.ValueDiff() == 0d ?
+                TrendIcon.Constant :
+                (qg.ValueDiff() > 0 ? 
+                  ( qg.MoreIsBad ?  TrendIcon.RedUp: TrendIcon.GreenUp) :
+                  (!qg.MoreIsBad ?  TrendIcon.RedDown: TrendIcon.GreenDown))
+select new { qg, 
+   Evolution      =  evolution,
+
+   BaselineStatus =  relyOnDiff? (QualityGateStatus?) null : qgBaseline.Status,
+   Status         =  qg.Status,
+
+   BaselineValue  =  relyOnDiff? (null) : qgBaseline.ValueString,
+   Value          =  qg.ValueString, 
+}
+ 
+// <Description>
+// Show quality gates evolution between baseline and now.
+//
+// When a quality gate relies on diff between now and baseline (like *New Debt since Baseline*)
+// it is not executed against the baseline and as a consequence its evolution is not available.
+//
+// Double-click a quality gate for editing.
+// </Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Percentage Coverage" Unit="%" />
+failif value < 70%
+warnif value < 80%
+codeBase.PercentageCoverage
+
+//<Description>
+// Code coverage is a measure used to describe the degree to which the source code of a program 
+// is tested by a particular test suite. A program with high code coverage, measured as a percentage, 
+// has had more of its source code executed during testing which suggests it has a lower chance of 
+// containing undetected software bugs compared to a program with low code coverage.
+//
+// Code coverage is certainly the most important quality code metric. But coverage is not enough
+// the team needs to ensure that results are checked at test-time. These checks can be done both 
+// in test code, and in application code through assertions. The important part is that a test
+// must fail explicitely when a check gets unvalidated during the test execution.
+//
+// This quality gate define a warn threshold (70%) and a fail threshold (80%). These are 
+// indicative thresholds and in practice the more the better. To achieve high coverage and 
+// low risk, make sure that new and refactored classes gets 100% covered by tests and that
+// the application and test code contains as many checks/assertions as possible.
+//</Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Percentage Coverage on New Code" Unit="%" />
+failif value < 70%
+warnif value < 80%
+let newMethods = Application.Methods.Where(m => m.WasAdded() && m.NbLinesOfCode > 0)
+let locCovered = newMethods.Sum(m => m.NbLinesOfCodeCovered)
+let loc = newMethods.Sum(m => m.NbLinesOfCode)
+select 100d * locCovered / loc
+
+//<Description>
+// *New Code* is defined as methods added since the baseline.
+//
+// To achieve high code coverage it is essential that new code gets properly
+// tested and covered by tests. It is advised that all non-UI new classes gets
+// 100% covered.
+//
+// Typically 90% of a class is easy to cover by tests and 10% is hard to reach 
+// through tests. It means that this 10% remaining is not easily testable, which 
+// means it is not well designed, which often means that this code is especially 
+// **error-prone**. This is the reason why it is important to reach 100% coverage
+// for a class, to make sure that potentially *error-prone* code gets tested.
+//</Description>
+]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Percentage Coverage on Refactored Code" Unit="%" />
+failif value < 70%
+warnif value < 80%
+let newMethods = Application.Methods.Where(m => m.CodeWasChanged() && m.NbLinesOfCode > 0)
+let locCovered = newMethods.Sum(m => m.NbLinesOfCodeCovered)
+let loc = newMethods.Sum(m => m.NbLinesOfCode)
+select 100d * locCovered / loc
+
+//<Description>
+// *Refactored Code* is defined as methods where *code was changed* since the baseline.
+//
+// Comment changes and formatting changes are not considerd as refactoring.
+//
+// To achieve high code coverage it is essential that refactored code gets properly
+// tested and covered by tests. It is advised that when refactoring a class
+// or a method, it is important to also write tests to make sure it gets 100% covered.
+//
+// Typically 90% of a class is easy to cover by tests and 10% is hard to reach 
+// through tests. It means that this 10% remaining is not easily testable, which 
+// means it is not well designed, which often means that this code is especially 
+// **error-prone**. This is the reason why it is important to reach 100% coverage
+// for a class, to make sure that potentially *error-prone* code gets tested.
+//</Description>
+]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Blocker Issues" Unit="issues" />
+failif count > 0 issues
+from i in Issues
+where i.Severity == Severity.Blocker
+select new { i, i.Severity, i.Debt, i.AnnualInterest }
+
+//<Description>
+// An issue with the severity **Blocker** cannot move to production, it must be fixed.
+//
+// The severity of an issue is either defined explicitely in the rule source code,
+// either inferred from the issue *annual interest* and thresholds defined in the 
+// NDepend Project Properties > Issue and Debt.
+//</Description>
+
+]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Critical Issues" Unit="issues" />
+failif count > 10 issues
+warnif count > 0 issues
+
+from i in Issues
+where i.Severity == Severity.Critical
+select new { i, i.Severity, i.Debt, i.AnnualInterest }
+
+//<Description>
+// An issue with a severity level **Critical** shouldn't move to production. 
+// It still can for business imperative needs purposes, but at worst it must 
+// be fixed during the next iterations. 
+//
+// The severity of an issue is either defined explicitely in the rule source code,
+// either inferred from the issue *annual interest* and thresholds defined in the 
+// NDepend Project Properties > Issue and Debt.
+//</Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="New Blocker / Critical / High Issues" Unit="issues" />
+failif count > 0 issues
+from i in Issues
+where i.Severity.EqualsAny(Severity.Blocker, Severity.Critical, Severity.High) &&  
+      // Count both the new issues and the issues that became at least Critical
+      (i.WasAdded() || i.OlderVersion().Severity < Severity.High)
+select new { i, i.Severity, i.Debt, i.AnnualInterest }
+
+
+//<Description>
+// An issue with the severity **Blocker** cannot move to production, it must be fixed.
+//
+// An issue with a severity level **Critical** shouldn't move to production. 
+// It still can for business imperative needs purposes, but at worth it must be fixed 
+// during the next iterations. 
+//
+// An issue with a severity level **High** should be fixed quickly, but can wait until 
+// the next scheduled interval.
+//
+// The severity of an issue is either defined explicitely in the rule source code,
+// either inferred from the issue *annual interest* and thresholds defined in the 
+// NDepend Project Properties > Issue and Debt.
+//</Description>
+]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Critical Rules Violated" Unit="rules" />
+failif count > 0 rules
+from r in Rules where r.IsCritical && r.IsViolated()
+select new { r, issues = r.Issues() }
+
+//<Description>
+// The concept of critical rule is useful to pinpoint certain rules that 
+// should not be violated.
+//
+// A rule can be made critical just by checking the *Critical button* in the
+// rule edition control and then saving the rule.
+//
+// This quality gate fails if any critical rule gets any violations.
+//
+// When no baseline is available, rules that rely on diff are not counted.
+// If you observe that this quality gate count slightly decreases with no apparent reason,
+// the reason is certainly that rules that rely on diff are not counted
+// because the baseline is not defined.
+//</Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Percentage Debt" Unit="%" />
+failif value > 30%
+warnif value > 20%
+let timeToDev = codeBase.EffortToDevelop()
+let debt = Issues.Sum(i => i.Debt)
+select 100d * debt.ToManDay() / timeToDev.ToManDay()
+
+// <Description>
+// % Debt total is defined as a percentage on:
+//
+// • the estimated total effort to develop the code base
+//
+// • and the the estimated total time to fix all issues (the Debt)
+//
+// Estimated total effort to develop the code base is inferred from 
+// # lines of code of the code base and from the 
+// *Estimated number of man-day to develop 1000 logicial lines of code*
+// setting found in NDepend Project Properties > Issue and Debt.
+//
+// Debt documentation: http://www.ndepend.com/docs/technical-debt#Debt
+//
+// This quality gates fails if the estimated debt is more than 30%
+// of the estimated effort to develop the code base, and warns if the 
+// estimated debt is more than 20% of the estimated effort to develop 
+// the code base
+// </Description>]]></Query>
+      <Query Active="False" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Debt" Unit="man-days" />
+failif value > 50 man-days
+warnif value > 30 man-days
+Issues.Sum(i => i.Debt).ToManDay()
+
+//<Description>
+// This Quality Gate is disabled per default because the fail and warn 
+// thresholds of unacceptable Debt in man-days can only depend on the 
+// project size, number of developers and overall context.
+//
+// However you can refer to the default Quality Gate **Percentage Debt**.
+//
+// The Debt is defined as the sum of estimated effort to fix all issues.
+// Debt documentation: http://www.ndepend.com/docs/technical-debt#Debt
+//</Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="New Debt since Baseline" Unit="man-days" />
+failif value > 2 man-days
+warnif value > 0 man-days
+let debt = Issues.Sum(i => i.Debt)
+let debtInBaseline = IssuesInBaseline.Sum(i => i.Debt)
+select (debt - debtInBaseline).ToManDay()
+
+
+//<Description>
+// This Quality Gate fails if the estimated effort to fix new or worsened
+// issues (what is called the *New Debt since Baseline*) is higher
+// than 2 man-days.
+//
+// This Quality Gate warns if this estimated effort is positive.
+//
+// Debt documentation: http://www.ndepend.com/docs/technical-debt#Debt
+//</Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Debt Rating per Namespace" Unit="namespaces" />
+failif count > 0 namespaces
+
+from n in Application.Namespaces
+where n.DebtRating() != null &&
+      n.DebtRating().Value.EqualsAny(DebtRating.E, DebtRating.D)
+select new { 
+   n, 
+   debtRating = n.DebtRating(),
+   debtRatio = n.DebtRatio(),  // % of debt from which DebtRating is inferred
+   devTimeInManDay = n.EffortToDevelop().ToDebt(), 
+   debtInManDay = n.AllDebt(),
+   issues = n.AllIssues() 
+}
+
+// <Description>
+// Forbid namespaces with a poor Debt Rating equals to **E** or **D**.
+//
+// The **Debt Rating** for a code element is estimated by the value of the **Debt Ratio**
+// and from the various rating thresholds defined in this project *Debt Settings*. 
+//
+// The **Debt Ratio** of a code element is a percentage of **Debt Amount** (in floating man-days) 
+// compared to the **estimated effort to develop the code element** (also in floating man-days).
+//
+// The **estimated effort to develop the code element** is inferred from the code elements
+// number of lines of code, and from the project *Debt Settings* parameters 
+// *estimated number of man-days to develop 1000* **logical lines of code**.
+//
+// The **logical lines of code** corresponds to the number of debug breakpoints in a method
+// and doesn't depend on code formatting nor comments.
+//
+// The Quality Gate can be modified to match assemblies, types or methods
+// with a poor Debt Rating, instead of matching namespaces.
+// </Description>]]></Query>
+      <Query Active="False" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="Annual Interest" Unit="man-days" />
+failif value > 50 man-days
+warnif value > 30 man-days
+Issues.Sum(i => i.AnnualInterest).ToManDay()
+
+
+//<Description>
+// This Quality Gate is disabled per default because the fail and warn 
+// thresholds of unacceptable Annual-Interest in man-days can only depend
+// on the project size, number of developers and overall context.
+//
+// However you can refer to the default Quality Gate 
+// **New Annual Interest since Baseline**.
+//
+// The Annual-Interest is defined as the sum of estimated annual cost
+// in man-days, to leave all issues unfixed.
+//
+// Each rule can either provide a formula to compute the Annual-Interest 
+// per issue, or assign a **Severity** level for each issue. Some thresholds
+// defined in *Project Properties > Issue and Debt > Annual Interest* are
+// used to infer an Annual-Interest value from a Severity level.
+// Annual Interest documentation: http://www.ndepend.com/docs/technical-debt#AnnualInterest
+//</Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <QualityGate Name="New Annual Interest since Baseline" Unit="man-days" />
+failif value > 2 man-days
+warnif value > 0 man-days
+let ai = Issues.Sum(i => i.AnnualInterest)
+let aiInBaseline = IssuesInBaseline.Sum(i => i.AnnualInterest)
+select (ai - aiInBaseline).ToManDay()
+
+//<Description>
+// This Quality Gate fails if the estimated annual cost to leave all issues
+// unfixed, increased from more than 2 man-days since the baseline.
+//
+// This Quality Gate warns if this estimated annual cost is positive.
+//
+// This estimated annual cost is named the **Annual-Interest**.
+//
+// Each rule can either provide a formula to compute the Annual-Interest 
+// per issue, or assign a **Severity** level for each issue. Some thresholds
+// defined in *Project Properties > Issue and Debt > Annual Interest* are
+// used to infer an Annual-Interest value from a Severity level.
+// Annual Interest documentation: http://www.ndepend.com/docs/technical-debt#AnnualInterest
+//</Description>]]></Query>
+    </Group>
+    <Group Name="Hot Spots" Active="True" ShownInReport="True">
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types Hot Spots</Name>
+from t in JustMyCode.Types
+where t.AllDebt() > Debt.Zero && 
+      t.AllAnnualInterest() > AnnualInterest.Zero
+orderby t.AllDebt().Value.TotalMinutes descending
+select new { t, 
+   Debt = t.AllDebt(),
+   Issues = t.AllIssues(), // AllIssues = {types issues} union {members issues}
+   AnnualInterest = t.AllAnnualInterest(),
+   BreakingPoint = t.AllBreakingPoint(),
+   t.NbLinesOfCode,
+   // t.PercentageCoverage,  to uncomment if coverage data is imported
+   DebtRating = t.DebtRating(), 
+   DebtRatio = t.DebtRatio() 
+}
+
+//<Description>
+// This query lists **types with most Debt**,
+// or in other words, types with issues that would need 
+// the largest effort to get fixed.
+//
+// Both issues on the type and its members are
+// taken account.
+//
+// Since untested code often generates a lot of 
+// Debt, the type size and percentage coverage is shown
+// (just uncomment *t.PercentageCoverage* in the query 
+// source code once you've imported the coverage data).
+//
+// The *Debt Rating* and *Debt Ratio* are also shown
+// for informational purpose.
+//
+// --
+//
+// The amount of *Debt* is not a measure to prioritize
+// the effort to fix issues, it is an estimation of how far 
+// the team is from clean code that abides by the rules set.
+//
+// For each issue the *Annual Interest* estimates the annual 
+// cost to leave the issues unfixed. The *Severity* of an issue
+// is estimated through thresholds from the *Annual Interest*.
+//
+// The **Debt Breaking Point** represents the duration
+// from now when the estimated cost to leave the issue unfixed
+// costs as much as the estimated effort to fix it.
+//
+// Hence the shorter the **Debt Breaking Point** 
+// the largest the **Return on Investment** for fixing 
+// the issue. The **Breaking Point is the right metric
+// to prioritize issues fix**.
+//</Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Types to Fix Priority</Name>
+from t in JustMyCode.Types
+where t.AllBreakingPoint() > TimeSpan.Zero &&
+      t.AllDebt().Value > 30.ToMinutes()
+orderby t.AllBreakingPoint().TotalMinutes ascending
+select new { t, 
+   BreakingPoint = t.AllBreakingPoint(),
+   Debt = t.AllDebt(),
+   AnnualInterest = t.AllAnnualInterest(),
+   Issues = t.AllIssues(),
+   t.NbLinesOfCode,
+   // t.PercentageCoverage,  to uncomment if coverage data is imported
+   DebtRating = t.DebtRating(), 
+   DebtRatio = t.DebtRatio() 
+}
+
+//<Description>
+// This query lists types per increasing
+// **Debt Breaking Point**.
+//
+// For each issue the *Debt* estimates the
+// effort to fix the issue, and the *Annual Interest*
+// estimates the annual cost to leave the issue unfixed.
+// The *Severity* of an issue is estimated through 
+// thresholds from the *Annual Interest* of the issue.
+//
+// The **Debt Breaking Point** represents the duration
+// from now when the estimated cost to leave the issue unfixed
+// costs as much as the estimated effort to fix it.
+//
+// Hence the shorter the **Debt Breaking Point** 
+// the largest the **Return on Investment** for fixing 
+// the issues.
+//
+// Often new and refactored types since baseline will be 
+// listed first, because issues on these types get a 
+// higher *Annual Interest* because it is important to
+// focus first on new issues.
+// 
+//
+// --
+//
+// Both issues on the type and its members are
+// taken account.
+//
+// Only types with at least 30 minutes of Debt are listed
+// to avoid parasiting the list with the numerous
+// types with small *Debt*, on which the *Breaking Point*
+// value makes less sense. 
+//
+// The *Annual Interest* estimates the cost per year
+// in man-days to leave these issues unfixed.
+//
+// Since untested code often generates a lot of 
+// Debt, the type size and percentage coverage is shown
+// (just uncomment *t.PercentageCoverage* in the query 
+// source code once you've imported the coverage data).
+//
+// The *Debt Rating* and *Debt Ratio* are also shown
+// for informational purpose.
+//</Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Issues to Fix Priority</Name>
+from i in Issues
+// Don't show first issues with BreakingPoint equals to zero.
+orderby i.BreakingPoint != TimeSpan.Zero ? i.BreakingPoint : TimeSpan.MaxValue
+select new { i, 
+   Debt = i.Debt,
+   AnnualInterest = i.AnnualInterest,
+   BreakingPoint = i.BreakingPoint,
+   CodeElement = i.CodeElement
+}
+
+//<Description>
+// This query lists issues per increasing
+// **Debt Breaking Point**.
+//
+// Double-click an issue to edit its rule and
+// select the issue in the rule result. This way
+// you can view all information concerning the issue.
+//
+// For each issue the *Debt* estimates the
+// effort to fix the issue, and the *Annual Interest*
+// estimates the annual cost to leave the issue unfixed.
+// The *Severity* of an issue is estimated through 
+// thresholds from the *Annual Interest* of the issue.
+//
+// The **Debt Breaking Point** represents the duration
+// from now when the estimated cost to leave the issue unfixed
+// costs as much as the estimated effort to fix it.
+//
+// Hence the shorter the **Debt Breaking Point** 
+// the largest the **Return on Investment** for fixing 
+// the issue.
+//
+// Often issues on new and refactored code elements since 
+// baseline will be listed first, because such issues get a 
+// higher *Annual Interest* because it is important to
+// focus first on new issues on recent code.
+//</Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Debt and Issues per Rule</Name>
+from r in Rules
+where r.IsViolated()
+orderby r.Debt().Value descending
+select new { 
+   r, 
+   Issues = r.Issues(), 
+   Debt = r.Debt(), 
+   AnnualInterest = r.AnnualInterest(), 
+   BreakingPoint = r.BreakingPoint(),
+   Category = r.Category
+}
+
+//<Description>
+// This query lists violated rules with most *Debt* first.
+//
+// A rule violated has issues. For each issue the *Debt* 
+// estimates the effort to fix the issue.
+//
+// --
+//
+// The amount of *Debt* is not a measure to prioritize
+// the effort to fix issues, it is an estimation of how far 
+// the team is from clean code that abides by the rules set.
+//
+// For each issue the *Annual Interest* estimates the annual 
+// cost to leave the issues unfixed. The *Severity* of an issue
+// is estimated through thresholds from the *Annual Interest*.
+//
+// The **Debt Breaking Point** represents the duration
+// from now when the estimated cost to leave the issue unfixed
+// costs as much as the estimated effort to fix it.
+//
+// Hence the shorter the **Debt Breaking Point** 
+// the largest the **Return on Investment** for fixing 
+// the issue. The **Breaking Point is the right metric
+// to prioritize issues fix**.
+//
+// --
+//
+// Notice that rules can be grouped in *Rule Category*. This
+// way you'll see categories that generate most *Debt*.
+//
+// Typically the rules that generate most *Debt* are the 
+// ones related to *Code Coverage by Tests*, *Architecture*
+// and *Code Smells*.
+//</Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>New Debt and Issues per Rule</Name>
+from r in Rules
+where r.IsViolated() && r.IssuesAdded().Count() > 0
+orderby r.DebtDiff().Value descending
+select new { 
+   r, 
+   IssuesAdded = r.IssuesAdded(),
+   IssuesFixed = r.IssuesFixed(),
+   Issues = r.Issues(), 
+   Debt = r.Debt(), 
+   DebtDiff = r.DebtDiff(),
+   Category = r.Category
+}
+
+//<Description>
+// This query lists violated rules that have new issues
+// since baseline, with most **new Debt** first.
+//
+// A rule violated has issues. For each issue the *Debt* 
+// estimates the effort to fix the issue.
+//
+// --
+//
+// New issues since the baseline are consequence of recent code 
+// refactoring sessions. They represent good opportunities
+// of fix because the code recently refactored is fresh in 
+// the developers mind, which means fixing now costs less
+// than fixing later.
+//
+// Fixing issues on recently touched code is also a good way 
+// to foster practices that will lead to higher code quality 
+// and maintainability, including writing unit-tests
+// and avoiding unnecessary complex code.
+//
+// --
+//
+// Notice that rules can be grouped in *Rule Category*. This
+// way you'll see categories that generate most *Debt*.
+//
+// Typically the rules that generate most *Debt* are the 
+// ones related to *Code Coverage by Tests*, *Architecture*
+// and *Code Smells*.
+//</Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Debt and Issues per Code Element</Name>
+from elem in CodeElements
+where elem.HasIssue()
+orderby elem.Debt().Value descending
+select new { 
+   elem, 
+   Issues = elem.Issues(), 
+   Debt = elem.Debt(), 
+   AnnualInterest = elem.AnnualInterest(), 
+   BreakingPoint = elem.BreakingPoint()
+}
+
+//<Description>
+// This query lists code elements that have issues, 
+// with most *Debt* first.
+//
+// For each code element the *Debt* estimates 
+// the effort to fix the element issues.
+//
+// The amount of *Debt* is not a measure to prioritize
+// the effort to fix issues, it is an estimation of how far 
+// the team is from clean code that abides by the rules set.
+//
+// For each element the *Annual Interest* estimates the annual 
+// cost to leave the elements issues unfixed. The *Severity* of an 
+// issue is estimated through thresholds from the *Annual Interest*
+// of the issue.
+//
+// The **Debt Breaking Point** represents the duration
+// from now when the estimated cost to leave the issues unfixed
+// costs as much as the estimated effort to fix it.
+//
+// Hence the shorter the **Debt Breaking Point** 
+// the largest the **Return on Investment** for fixing 
+// the issue. The **Breaking Point is the right metric
+// to prioritize issues fix**.
+//</Description>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>New Debt and Issues per Code Element</Name>
+from elem in CodeElements
+where elem.HasIssue() && elem.IssuesAdded().Count() > 0
+orderby elem.DebtDiff().Value descending
+select new { 
+   elem, 
+   IssuesAdded = elem.IssuesAdded(),
+   IssuesFixed = elem.IssuesFixed(),
+   Issues = elem.Issues(), 
+   Debt = elem.Debt(), 
+   DebtDiff = elem.DebtDiff()
+}
+    //<Description>
+// This query lists code elements that have new issues
+// since baseline, with most **new Debt** first.
+//
+// For each code element the *Debt* estimates 
+// the effort to fix the element issues.
+//
+// New issues since the baseline are consequence of recent code 
+// refactoring sessions. They represent good opportunities
+// of fix because the code recently refactored is fresh in 
+// the developers mind, which means fixing now costs less
+// than fixing later.
+//
+// Fixing issues on recently touched code is also a good way 
+// to foster practices that will lead to higher code quality 
+// and maintainability, including writing unit-tests
+// and avoiding unnecessary complex code.
+//</Description>
+]]></Query>
+    </Group>
+    <Group Name="Code Smells" Active="True" ShownInReport="False">
+      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid types too big</Name>
+warnif count > 0 from t in JustMyCode.Types where 
+
+   // First filter on type to optimize 
+   t.NbLinesOfCode > 200 
+   // # IL Instructions is commented, because with LINQ syntax, a few lines of code can compile to hundreds of IL instructions.
+   // || t.NbILInstructions > 3000
+
+   // What matters is the # lines of code in JustMyCode
+   let locJustMyCode = t.MethodsAndContructors.Where(m => JustMyCode.Contains(m)).Sum(m => m.NbLinesOfCode)
+   where locJustMyCode > 200
+
+   let isStaticWithNoMutableState = (t.IsStatic && t.Fields.Any(f => !f.IsImmutable))
+   let staticFactor = (isStaticWithNoMutableState ? 0.2 : 1)
+
+   orderby locJustMyCode descending
+select new { 
+   t, 
+   locJustMyCode, 
+   t.NbILInstructions,
+   t.Methods, 
+   t.Fields,
+   
+   Debt = (staticFactor*locJustMyCode.Linear(200, 1, 2000, 10)).ToHours().ToDebt(),
+
+   // The annual interest varies linearly from interest for severity major for 300 loc
+   // to interest for severity critical for 2000 loc
+   AnnualInterest = staticFactor*(locJustMyCode.Linear(
+                          200,  Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
+                          2000, Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
+}
+
+//<Description>
+// This rule matches types with more than 200 lines of code.
+// **Only lines of code in JustMyCode methods are taken account.**
+//
+// Types where *NbLinesOfCode > 200* are extremely complex 
+// to develop and maintain.
+// See the definition of the NbLinesOfCode metric here 
+// http://www.ndepend.com/docs/code-metrics#NbLinesOfCode
+//
+// Maybe you are facing the **God Class** phenomenon:
+// A **God Class** is a class that controls way too many other classes 
+// in the system and has grown beyond all logic to become 
+// *The Class That Does Everything*.
+//</Description>
+
+//<HowToFix>
+// Types with many lines of code
+// should be split in a group of smaller types.
+// 
+// To refactor a *God Class* you'll need patience, 
+// and you might even need to recreate everything from scratch.
+// Here are a few refactoring advices:
+//
+// • The logic in the *God Class* must be splitted in smaller classes.
+// These smaller classes can eventually become private classes nested
+// in the original *God Class*, whose instances objects become 
+// composed of instances of smaller nested classes.
+//
+// • Smaller classes partitioning should be driven by the multiple
+// responsibilities handled by the *God Class*. To identify these 
+// responsibilities it often helps to look for subsets of methods
+// strongly coupled with subsets of fields.
+//
+// • If the *God Class* contains way more logic than states, a good 
+// option can be to define one or several static classes that 
+// contains no static field but only pure static methods. A pure static 
+// method is a function that computes a result only from inputs
+// parameters, it doesn't read nor assign any static or instance field.
+// The main advantage of pure static methods is that they are easily
+// testable.
+// 
+// • Try to maintain the interface of the *God Class* at first 
+// and delegate calls to the new extracted classes. 
+// In the end the *God Class* should be a pure facade without its own logic.
+// Then you can keep it for convenience or throw it away and 
+// start to use the new classes only.
+//
+// • Unit Tests can help: write tests for each method before extracting it 
+// to ensure you don't break functionality.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// varies linearly from 1 hour for a 200 lines of code type,
+// up to 10 hours for a type with 2.000 or more lines of code.
+//
+// In Debt and Interest computation, this rule takes account of the fact 
+// that static types with no mutable fields are just a collection of 
+// static methods that can be easily splitted and moved from one type 
+// to another.
+//</HowToFix>]]></Query>
+      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid types with too many methods</Name>
+warnif count > 0 from t in JustMyCode.Types 
+
+  // Optimization: Fast discard of non-relevant types 
+  where t.Methods.Count() > 20
+
+  // Don't match these methods
+  let methods = t.Methods.Where(
+       m => !(m.IsGeneratedByCompiler ||
+              m.IsConstructor || m.IsClassConstructor ||
+              m.IsPropertyGetter || m.IsPropertySetter ||
+              m.IsEventAdder || m.IsEventRemover))
+
+  where methods.Count() > 20 
+  orderby methods.Count() descending
+
+  let isStaticWithNoMutableState = (t.IsStatic && t.Fields.Any(f => !f.IsImmutable))
+  let staticFactor = (isStaticWithNoMutableState ? 0.2 : 1)
+
+select new { 
+   t, 
+   nbMethods = methods.Count(),
+   instanceMethods = methods.Where(m => !m.IsStatic), 
+   staticMethods = methods.Where(m => m.IsStatic),
+
+   t.NbLinesOfCode,
+
+   Debt = (staticFactor*methods.Count().Linear(20, 1, 200, 10)).ToHours().ToDebt(),
+
+   // The annual interest varies linearly from interest for severity major for 30 methods
+   // to interest for severity critical for 200 methods
+   AnnualInterest = (staticFactor*methods.Count().Linear(
+                              20,  Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
+                              200, Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
+}
+
+//<Description>
+// This rule matches types with more than 20 methods. 
+// Such type might be hard to understand and maintain.
+//
+// Notice that methods like constructors or property 
+// and event accessors are not taken account.
+//
+// Having many methods for a type might be a symptom
+// of too many responsibilities implemented.
+//
+// Maybe you are facing the **God Class** phenomenon:
+// A **God Class** is a class that controls way too many other classes 
+// in the system and has grown beyond all logic to become 
+// *The Class That Does Everything*.
+//</Description>
+
+//<HowToFix>
+// To refactor properly a *God Class* please read *HowToFix advices* 
+// from the default rule **Types to Big**.
+////
+// The estimated Debt, which means the effort to fix such issue,
+// varies linearly from 1 hour for a type with 20 methods,
+// up to 10 hours for a type with 200 or more methods.
+//
+// In Debt and Interest computation, this rule takes account of the fact 
+// that static types with no mutable fields are just a collection of 
+// static methods that can be easily splitted and moved from one type 
+// to another.
+//</HowToFix>]]></Query>
+      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid types with too many fields</Name>
+warnif count > 0 from t in JustMyCode.Types 
+
+  // Optimization: Fast discard of non-relevant types 
+  where !t.IsEnumeration &&
+         t.Fields.Count() > 15
+        
+  // Count instance fields and non-constant static fields
+  let fields = t.Fields.Where(f =>
+          !f.IsGeneratedByCompiler &&
+          !f.IsLiteral &&
+          !(f.IsStatic && f.IsInitOnly) &&
+           JustMyCode.Contains(f) )
+
+  where fields.Count() > 15
+ 
+  let methodsAssigningFields = fields.SelectMany(f => f.MethodsAssigningMe)
+
+  orderby fields.Count() descending
+select new { 
+   t, 
+   instanceFields = fields.Where(f => !f.IsStatic),
+   staticFields = fields.Where(f => f.IsStatic),
+methodsAssigningFields ,   
+
+   // See definition of Size of Instances metric here:
+   // http://www.ndepend.com/docs/code-metrics#SizeOfInst
+   t.SizeOfInst,
+
+   Debt = fields.Count().Linear(15, 1, 200, 10).ToHours().ToDebt(),
+
+   // The annual interest varies linearly from interest for severity major for 30 methods
+   // to interest for severity critical for 200 methods
+   AnnualInterest = fields.Count().Linear(15,  Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
+                                          200, Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes).ToMinutes().ToAnnualInterest()
+}
+
+//<Description>
+// This rule matches types with more than 15 fields. 
+// Such type might be hard to understand and maintain.
+//
+// Notice that constant fields and static-readonly fields are not counted.
+// Enumerations types are not counted also.
+//
+// Having many fields for a type might be a symptom
+// of too many responsibilities implemented.
+//</Description>
+
+//<HowToFix>
+// To refactor such type and increase code quality and maintainability,
+// certainly you'll have to group subsets of fields into smaller types
+// and dispatch the logic implemented into the methods 
+// into these smaller types.
+//
+// More refactoring advices can be found in the default rule 
+// **Types to Big**, *HowToFix* section.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// varies linearly from 1 hour for a type with 15 fields,
+// to up to 10 hours for a type with 200 or more fields. 
+//</HowToFix>]]></Query>
+      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid methods too big, too complex</Name>
+warnif count > 0 from m in JustMyCode.Methods where 
+   m.ILNestingDepth > 2 &&
+  (m.NbLinesOfCode > 35 ||
+   m.CyclomaticComplexity > 20 ||
+   m.ILCyclomaticComplexity > 60)
+
+  let complexityScore = m.NbLinesOfCode/2 + m.CyclomaticComplexity + m.ILCyclomaticComplexity/3 + 3*m.ILNestingDepth
+
+  orderby complexityScore descending,
+          m.CyclomaticComplexity descending,
+          m.ILCyclomaticComplexity descending,
+          m.ILNestingDepth descending
+select new { 
+   m, 
+   m.NbLinesOfCode,
+   m.CyclomaticComplexity, 
+   m.ILCyclomaticComplexity,
+   m.ILNestingDepth,
+   complexityScore,
+
+   Debt = complexityScore.Linear(30, 40,    400, 8*60).ToMinutes().ToDebt(),
+
+   // The annual interest varies linearly from interest for severity minor 
+   // to interest for severity major
+   AnnualInterest = complexityScore .Linear(30,     Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
+                                            200, 2*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
+   
+}
+
+//<Description>
+// This rule matches methods where *ILNestingDepth* > 2
+// and (*NbLinesOfCode* > 35 
+// or *CyclomaticComplexity* > 20
+// or *ILCyclomaticComplexity* > 60)
+// Such method is typically hard to understand and maintain.
+//
+// Maybe you are facing the **God Method** phenomenon.
+// A "God Method" is a method that does way too many processes in the system 
+// and has grown beyond all logic to become *The Method That Does Everything*.
+// When need for new processes increases suddenly some programmers realize: 
+// why should I create a new method for each processe if I can only add an *if*.
+//
+// See the definition of the *CyclomaticComplexity* metric here:
+// http://www.ndepend.com/docs/code-metrics#CC
+//
+// See the definition of the *ILCyclomaticComplexity* metric here:
+// http://www.ndepend.com/docs/code-metrics#ILCC
+//
+// See the definition of the *ILNestingDepth* metric here:
+// http://www.ndepend.com/docs/code-metrics#ILNestingDepth
+//</Description>
+
+//<HowToFix>
+// A large and complex method should be split in smaller methods, 
+// or even one or several classes can be created for that.
+//
+// During this process it is important to question the scope of each
+// variable local to the method. This can be an indication if
+// such local variable will become an instance field of the newly created class(es).
+//
+// Large *switch…case* structures might be refactored through the help
+// of a set of types that implement a common interface, the interface polymorphism
+// playing the role of the *switch cases tests*.
+//
+// Unit Tests can help: write tests for each method before extracting it 
+// to ensure you don't break functionality.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// varies from 40 minutes to 8 hours, linearly from a weighted complexity score.
+//</HowToFix>]]></Query>
+      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="True"><![CDATA[// <Name>Avoid methods with too many parameters</Name>
+warnif count > 0 from m in JustMyCode.Methods where 
+  m.NbParameters >= 7
+  orderby m.NbParameters descending
+select new { 
+   m, 
+   m.NbParameters,
+
+   Debt = m.NbParameters.Linear(7, 1,  40, 6).ToHours().ToDebt(),
+
+   // The annual interest varies linearly from interest for severity Medium for 7 parameters
+   // to interest for severity Critical for 40 parameters
+   AnnualInterest = m.NbParameters.Linear(7,  Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
+                                          40, Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes).ToMinutes().ToAnnualInterest()
+}
+
+//<Description>
+// This rule matches methods with more than 8 parameters.
+// Such method is painful to call and might degrade performance.
+// See the definition of the *NbParameters* metric here: 
+// http://www.ndepend.com/docs/code-metrics#NbParameters
+//</Description>
+
+//<HowToFix>
+// More properties/fields can be added to the declaring type to 
+// handle numerous states. An alternative is to provide 
+// a class or a structure dedicated to handle arguments passing.
+// For example see the class *System.Diagnostics.ProcessStartInfo* 
+// and the method *System.Diagnostics.Process.Start(ProcessStartInfo)*.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// varies linearly from 1 hour for a method with 7 parameters,
+// up to 6 hours for a methods with 40 or more parameters.
+//</HowToFix>]]></Query>
+      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid methods with too many local variables</Name>
+warnif count > 0 from m in JustMyCode.Methods where 
+  m.NbVariables > 15 
+  orderby m.NbVariables descending
+select new { 
+   m, 
+   m.NbVariables,
+
+   Debt = m.NbVariables.Linear(15, 1,   80, 6).ToHours().ToDebt(),
+
+   // The annual interest varies linearly from interest for severity Medium for 15 variables
+   // to interest for severity Critical for 80 variables
+   AnnualInterest = m.NbVariables.Linear(15,  Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
+                                         80,  Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes).ToMinutes().ToAnnualInterest()
+
+}
+
+//<Description>
+// This rule matches methods with more than 15 variables.
+//
+// Methods where *NbVariables > 8* are hard to understand and maintain.
+// Methods where *NbVariables > 15* are extremely complex and must be refactored. 
+//
+// See the definition of the *Nbvariables* metric here: 
+// http://www.ndepend.com/docs/code-metrics#Nbvariables
+//</Description>
+
+//<HowToFix>
+// To refactor such method and increase code quality and maintainability,
+// certainly you'll have to split the method into several smaller methods
+// or even create one or several classes to implement the logic.
+//
+// During this process it is important to question the scope of each
+// variable local to the method. This can be an indication if
+// such local variable will become an instance field of the newly created class(es).
+//
+// The estimated Debt, which means the effort to fix such issue,
+// varies linearly from 10 minutes for a method with 15 variables,
+// up to 2 hours for a methods with 80 or more variables.
+//</HowToFix>]]></Query>
+      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid methods with too many overloads</Name>
+warnif count > 0 
+
+let lookup = JustMyCode.Methods.Where(m =>
+   m.NbOverloads >= 6 && 
+  !m.IsOperator && // Don't report operator overload
+
+   // Don't match overloads due tu the visitor pattern, based on a naming convention.
+  !m.SimpleName.ToLower().StartsWithAny("visit", "dispatch")
+).ToLookup(m => m.ParentType.FullName + "."+ m.SimpleName)
+
+from @group in lookup
+let overloads = @group.ToArray()
+orderby overloads.Length descending
+
+select new { 
+   m = @group.First(), 
+   overloads,
+   Debt = (3*overloads.Length).ToMinutes().ToDebt(),
+   Severity = Severity.Medium
+}
+
+//<Description>
+// Method overloading is the ability to create multiple methods of the same name 
+// with different implementations, and various set of parameters.
+//
+// This rule matches sets of methods with 6 overloads or more.
+//
+// Such method set might be a problem to maintain 
+// and provokes coupling higher than necessary.
+//
+// See the definition of the *NbOverloads* metric here 
+// http://www.ndepend.com/docs/code-metrics#NbOverloads
+//</Description>
+
+//<HowToFix>
+// Typically the *too many overloads* phenomenon appears when an algorithm
+// takes a various set of in-parameters. Each overload is presented as 
+// a facility to provide a various set of in-parameters.
+// In such situation, the C# and VB.NET language feature named 
+// *Named and Optional arguments* should be used.
+//
+// The *too many overloads* phenomenon can also be a consequence of the usage
+// of the **visitor design pattern** http://en.wikipedia.org/wiki/Visitor_pattern 
+// since a method named *Visit()* must be provided for each sub type.
+// For this reason, the default version of this rule doesn't match overloads whose name
+// start with "visit" or "dispatch" (case-unsensitive) to avoid match 
+// overload visitors, and you can adapt this rule to your own naming convention.
+//
+// Sometime *too many overloads* phenomenon is not the symptom of a problem,
+// for example when a *numeric to something conversion* method applies to 
+// all numeric and nullable numeric types.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// is of 3 minutes per method overload.
+//</HowToFix>]]></Query>
+      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid methods potentially poorly commented</Name>
+warnif count > 0 from m in JustMyCode.Methods where 
+  m.PercentageComment < 10 && 
+  m.NbLinesOfCode > 20  
+
+  let nbLinesOfCodeNotCommented = m.NbLinesOfCode - m.NbLinesOfComment
+
+  orderby nbLinesOfCodeNotCommented descending
+
+select new { 
+   m, 
+   m.PercentageComment, 
+   m.NbLinesOfCode, 
+   m.NbLinesOfComment,
+   nbLinesOfCodeNotCommented,
+
+   Debt = nbLinesOfCodeNotCommented .Linear(20, 2,  200, 20).ToMinutes().ToDebt(),
+
+   // The annual interest varies linearly from interest for severity major for 300 loc
+   // to interest for severity critical for 2000 loc
+   AnnualInterest = m.PercentageComment.Linear(
+                         0,  8 *(Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes), 
+                         20,     Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes).ToMinutes().ToAnnualInterest()  
+}
+
+//<Description>
+// This rule matches methods with less than 10% of comment lines and that have 
+// at least 20 lines of code. Such method might need to be more commented.
+//
+// See the definitions of the *Comments metric* here:
+// http://www.ndepend.com/docs/code-metrics#PercentageComment
+// http://www.ndepend.com/docs/code-metrics#NbLinesOfComment
+// 
+// Notice that only comments about the method implementation
+// (comments in method body) are taken account.
+//</Description>
+
+//<HowToFix>
+// Typically add more comment. But code commenting is subject to controversy.
+// While poorly written and designed code would needs a lot of comment 
+// to be understood, clean code doesn't need that much comment, especially
+// if variables and methods are properly named and convey enough information.
+// Unit-Test code can also play the role of code commenting.
+//
+// However, even when writing clean and well-tested code, one will have
+// to write **hacks** at a point, usually to circumvent some API limitations or bugs.
+// A hack is a non-trivial piece of code, that doesn't make sense at first glance,
+// and that took time and web research to be found.
+// In such situation comments must absolutely be used to express the intention, 
+// the need for the hacks and the source where the solution has been found.
+//
+// The estimated Debt, which means the effort to comment such method,
+// varies linearly from 2 minutes for 10 lines of code not commented,
+// up to 20 minutes for 200 or more, lines of code not commented.
+//</HowToFix>]]></Query>
+      <Query Active="False" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid types with poor cohesion</Name>
+warnif count > 0 from t in JustMyCode.Types where 
+  t.LCOM > 0.8  && 
+  t.NbFields > 10 && 
+  t.NbMethods >10 
+
+  let poorCohesionScore = 1/(1.01 - t.LCOM)
+  orderby poorCohesionScore descending
+
+  select new { 
+   t, 
+   t.LCOM, 
+   t.NbMethods, 
+   t.NbFields,
+   poorCohesionScore,
+
+   Debt = poorCohesionScore.Linear(5, 5, 50, 4*60).ToMinutes().ToDebt(),
+
+   // The annual interest varies linearly from interest for severity Medium for low poorCohesionScore
+   // to 4 times interest for severity High for high poorCohesionScore
+   AnnualInterest = poorCohesionScore.Linear(5,     Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
+                                             50, 4*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
+   
+}
+
+//<Description>
+// This rule is based on the *LCOM code metric*,
+// LCOM stands for **Lack Of Cohesion of Methods**.
+// See the definition of the LCOM metric here 
+// http://www.ndepend.com/docs/code-metrics#LCOM
+//
+// The LCOM metric measures the fact that most methods are using most fields.
+// A class is considered utterly cohesive (which is good)
+// if all its methods use all its instance fields.
+//
+// Only types with enough methods and fields are taken account to avoid bias.
+// The LCOM takes its values in the range [0-1].
+//
+// This rule matches types with LCOM higher than 0.8.
+// Such value generally pinpoints a **poorly cohesive class**.
+//</Description>
+
+//<HowToFix>
+// To refactor a poorly cohesive type and increase code quality and maintainability,
+// certainly you'll have to split the type into several smaller and more cohesive types
+// that together, implement the same logic.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// varies linearly from 5 minutes for a type with a low poorCohesionScore,
+// up to 4 hours for a type with high poorCohesionScore.
+//</HowToFix>]]></Query>
+    </Group>
+    <Group Name="Code Smells Regression" Active="True" ShownInReport="False">
+      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>From now, all types added should respect basic quality principles</Name>
+warnif count > 0 from t in JustMyCode.Types where
+
+// Only match types added since Baseline.
+// Uncomment this line to match also refactored types since Baseline.
+// (t.WasAdded() || t.CodeWasChanged()) &&
+   t.WasAdded() &&
+
+// Eliminate interfaces, enumerations or types only with constant fields
+// by making sure we are matching type with code.
+t.NbLinesOfCode > 10 &&
+
+// Optimization: Fast discard of non-relevant types 
+(t.Fields.Count() > 20 || t.Methods.Count() > 20)
+      
+// Count instance fields and non-constant static fields
+let fields = t.Fields.Where(f => 
+      !f.IsLiteral &&
+      !(f.IsStatic && f.IsInitOnly))
+
+// Don't match these methods
+let methods = t.Methods.Where(
+   m => !(m.IsConstructor || m.IsClassConstructor ||
+          m.IsGeneratedByCompiler ||
+          m.IsPropertyGetter || m.IsPropertySetter ||
+          m.IsEventAdder || m.IsEventRemover))
+  
+where 
+
+// Low Quality types     Metrics' definitions are available here:
+//     http://www.ndepend.com/docs/code-metrics#MetricsOnTypes
+(  // Types with too many methods
+   fields.Count() > 20 ||
+
+   methods.Count() > 20 ||
+               
+   // Complex Types that use more than 50 other types
+   t.NbTypesUsed > 50
+)
+select new { 
+   t, 
+   t.NbLinesOfCode, 
+
+   instanceMethods = methods.Where(m => !m.IsStatic), 
+   staticMethods = methods.Where(m => m.IsStatic),
+  
+   instanceFields = fields.Where(f => !f.IsStatic),
+   staticFields = fields.Where(f => f.IsStatic),
+  
+   t.TypesUsed,
+
+   // Constant Debt estimation, since for such type rules in category "Code Smells" 
+   // accurately estimate the Debt.
+   Debt     = 10.ToMinutes().ToDebt(),
+
+   // The Severity is higher for new types than for refactored types 
+   AnnualInterest= (t.WasAdded() ? 3 : 1) *
+                    Severity.High.AnnualInterestThreshold()
+}
+
+//<Description>
+// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
+// This rule operates only on types added since baseline.
+//
+// This rule can be easily modified to also match types refactored since baseline,
+// that don't satisfy all quality criterions.
+//
+// Types matched by this rule not only have been recently added or refactored,
+// but also somehow violate one or several basic quality principles,
+// whether it has too many methods,
+// it has too many fields,
+// or is using too many types.
+// Any of these criterions is often a symptom of a type with too many responsibilities.
+//
+// Notice that to count methods and fields, methods like constructors 
+// or property and event accessors are not taken account.
+// Notice that constants fields and static-readonly fields are not counted.
+// Enumerations types are not counted also.
+//</Description>
+
+//<HowToFix>
+// To refactor such type and increase code quality and maintainability,
+// certainly you'll have to split the type into several smaller types
+// that together, implement the same logic.
+//
+// Issues of this rule have a constant 10 minutes Debt, because the Debt,
+// which means the effort to fix such issue, is already estimated for issues
+// of rules in the category **Code Smells**.
+//
+// However issues of this rule have a **High** severity, with even more 
+// interests for issues on new types since baseline, because the proper time 
+// to increase the quality of these types is **now**, before they get commited 
+// in the next production release.
+//</HowToFix>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>From now, all types added should be 100% covered by tests</Name>
+warnif count > 0 from t in JustMyCode.Types where
+
+// Only match types added since Baseline.
+// Uncomment this line to match also refactored types since Baseline.
+// (t.WasAdded() || t.CodeWasChanged()) &&
+   t.WasAdded() &&
+
+  // …that are not 100% covered by tests
+  t.PercentageCoverage < 100
+
+  let methodsCulprit = t.Methods.Where(m => m.PercentageCoverage < 100)
+
+select new { 
+   t, 
+   t.PercentageCoverage, 
+   methodsCulprit,
+   t.NbLinesOfCode,
+
+   // Constant Debt estimation, since for such type rules in category "Coverage" 
+   // accurately estimate the untested code Debt.
+   Debt     = 10.ToMinutes().ToDebt(),
+
+   // The Severity is higher for new types than for refactored types 
+   AnnualInterest= (t.WasAdded() ? 3 : 1) *
+                    Severity.High.AnnualInterestThreshold()
+}
+
+//<Description>
+// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
+// This rule operates only on types added since baseline.
+//
+// This rule can be easily modified to also match types refactored since baseline,
+// that are not 100% covered by tests.
+//
+// This rule is executed only if some code coverage data is imported
+// from some code coverage files.
+//
+// Often covering 10% of remaining uncovered code of a class, 
+// requires as much work as covering the first 90%.
+// For this reason, typically teams estimate that 90% coverage is enough.
+// However *untestable code* usually means *poorly written code* 
+// which usually leads to *error prone code*.
+// So it might be worth refactoring and making sure to cover the 10% remaining code
+// because **most tricky bugs might come from this small portion of hard-to-test code**.
+//
+// Not all classes should be 100% covered by tests (like UI code can be hard to test)
+// but you should make sure that most of the logic of your application
+// is defined in some *easy-to-test classes*, 100% covered by tests.
+//
+// In this context, this rule warns when a type added or refactored since the baseline,
+// is not fully covered by tests.
+//</Description>
+
+//<HowToFix>
+// Write more unit-tests dedicated to cover code not covered yet.
+// If you find some *hard-to-test code*, it is certainly a sign that this code
+// is not *well designed* and hence, needs refactoring.
+//
+// You'll find code impossible to cover by unit-tests, like calls to *MessageBox.Show()*.
+// An infrastructure must be defined to be able to *mock* such code at test-time.
+//
+// Issues of this rule have a constant 10 minutes Debt, because the Debt,
+// which means the effort to write tests for the culprit type, is already 
+// estimated for issues in the category **Code Coverage**. 
+//
+// However issues of this rule have a **High** severity, with even more 
+// interests for issues on new types since baseline, because the proper time 
+// to write tests for these types is **now**, before they get commited 
+// in the next production release.
+//</HowToFix>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>From now, all methods added should respect basic quality principles</Name>
+warnif count > 0 from m in JustMyCode.Methods where
+
+// Only match methods added since Baseline.
+// Uncomment this line to match also refactored methods since Baseline.
+// (m.WasAdded() || m.CodeWasChanged()) &&
+   m.WasAdded() &&
+ 
+// Low Quality methods// Metrics' definitions
+(  m.NbLinesOfCode > 30 ||          // http://www.ndepend.com/docs/code-metrics#NbLinesOfCode
+   m.NbILInstructions > 200 ||      // http://www.ndepend.com/docs/code-metrics#NbILInstructions
+   m.CyclomaticComplexity > 20 ||   // http://www.ndepend.com/docs/code-metrics#CC
+   m.ILCyclomaticComplexity > 50 || // http://www.ndepend.com/docs/code-metrics#ILCC
+   m.ILNestingDepth > 4 ||          // http://www.ndepend.com/docs/code-metrics#ILNestingDepth
+   m.NbParameters > 5 ||            // http://www.ndepend.com/docs/code-metrics#NbParameters
+   m.NbVariables > 8 ||             // http://www.ndepend.com/docs/code-metrics#NbVariables
+   m.NbOverloads > 6 )
+select new { 
+   m, 
+   m.NbLinesOfCode,
+   m.NbILInstructions,
+   m.CyclomaticComplexity, 
+   m.ILCyclomaticComplexity,
+   m.ILNestingDepth, 
+   m.NbParameters, 
+   m.NbVariables, 
+   m.NbOverloads, // http://www.ndepend.com/docs/code-metrics#NbOverloads
+
+   // Constant Debt estimation, since for such method rules in category "Code Smells" 
+   // accurately estimate the Debt.
+   Debt     = 5.ToMinutes().ToDebt(),
+
+   // The Severity is higher for new methods than for refactored methods
+   AnnualInterest= (m.WasAdded() ? 3 : 1) *
+                   Severity.High.AnnualInterestThreshold()
+}  
+
+//<Description>
+// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
+// This rule operates only on methods added or refactored since the baseline.
+//
+// This rule can be easily modified to also match methods refactored since baseline,
+// that don't satisfy all quality criterions.
+//
+// Methods matched by this rule not only have been recently added or refactored,
+// but also somehow violate one or several basic quality principles,
+// whether it is too large (too many *lines of code*), 
+// too complex (too many *if*, *switch case*, loops…)
+// has too many variables, too many parameters
+// or has too many overloads.
+//</Description>
+
+//<HowToFix>
+// To refactor such method and increase code quality and maintainability,
+// certainly you'll have to split the method into several smaller methods
+// or even create one or several classes to implement the logic.
+//
+// During this process it is important to question the scope of each
+// variable local to the method. This can be an indication if
+// such local variable will become an instance field of the newly created class(es).
+//
+// Large *switch…case* structures might be refactored through the help
+// of a set of types that implement a common interface, the interface polymorphism
+// playing the role of the *switch cases tests*.
+//
+// Unit Tests can help: write tests for each method before extracting it 
+// to ensure you don't break functionality.
+//
+// Issues of this rule have a constant 5 minutes Debt, because the Debt,
+// which means the effort to fix such issue, is already estimated for issues
+// of rules in the category **Code Smells**.
+// 
+// However issues of this rule have a **High** severity, with even more 
+// interests for issues on new methods since baseline, because the proper time 
+// to increase the quality of these methods is **now**, before they get commited 
+// in the next production release.
+//</HowToFix>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid decreasing code coverage by tests of types</Name>
+warnif count > 0 
+from t in JustMyCode.Types where
+  t.IsPresentInBothBuilds() && t.CoverageDataAvailable && t.OlderVersion().CoverageDataAvailable
+let locDiff = (int)t.NbLinesOfCode.Value - (int)t.OlderVersion().NbLinesOfCode.Value
+where locDiff >= 0
+let uncoveredLoc  = (int)t.NbLinesOfCodeNotCovered.Value - ((int)t.OlderVersion().NbLinesOfCodeNotCovered.Value + locDiff)
+where uncoveredLoc > 0
+
+orderby uncoveredLoc descending
+
+select new { 
+   t,
+   OldCoveragePercent = t.OlderVersion().PercentageCoverage,
+   NewCoveragePercent = t.PercentageCoverage,
+   OldLoc = t.OlderVersion().NbLinesOfCode,
+   NewLoc = t.NbLinesOfCode,
+   uncoveredLoc,
+
+   Debt = uncoveredLoc.Linear(1, 15,  100, 3*60).ToMinutes().ToDebt(),
+
+   // The annual interest varies linearly from interest for severity High for one line of code that is not covered by tests anymore
+   // to interest for severity Critical for 50 lines of code that are not covered by tests anymore
+   AnnualInterest = uncoveredLoc.Linear(1,    Severity.High.AnnualInterestThreshold().Value.TotalMinutes, 
+                                        50, 2*Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes).ToMinutes().ToAnnualInterest()
+   
+
+}
+
+//<Description>
+// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
+//
+// This rule is executed only if some code coverage data is imported
+// from some code coverage files.
+//
+// This rule warns when the number of lines of a type covered by tests
+// decreased since the baseline. In case the type faced some refactoring
+// since the baseline, this loss in coverage is estimated only for types 
+// with more lines of code, where # lines of code covered now is lower
+// than # lines of code covered in baseline + the extra number of
+// lines of code.
+//
+// Such situation can mean that some tests have been removed
+// but more often, this means that the type has been modified,
+// and that changes haven't been covered properly by tests.
+//
+// To visualize changes in code, right-click a matched type and select:
+//
+// • Compare older and newer versions of source file
+//
+// • or Compare older and newer versions disassembled with Reflector
+//</Description>
+
+//<HowToFix>
+// Write more unit-tests dedicated to cover changes in matched types
+// not covered yet.
+// If you find some *hard-to-test code*, it is certainly a sign that this code
+// is not *well designed* and hence, needs refactoring.
+//
+// The estimated Debt, which means the effort to cover by test 
+// code that used to be covered, varies linearly 15 minutes to 3 hours,
+// depending on the number of lines of code that are not covered by tests anymore.
+//
+// Severity of issues of this rule varies from **High** to **Critical** 
+// depending on the number of lines of code that are not covered by tests anymore.
+// Because the loss in code coverage happened since the baseline,
+// the severity is high because it is important to focus on these issues 
+// **now**, before such code gets released in production.
+//</HowToFix>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid making complex methods even more complex</Name>
+warnif count > 0 
+
+let complexityScoreProc = new Func<IMethod, double>(m => 
+    (m.CyclomaticComplexity + m.ILCyclomaticComplexity/3 + 5*m.ILNestingDepth).Value)
+
+from m in JustMyCode.Methods where
+ !m.IsAbstract &&
+  m.IsPresentInBothBuilds() &&
+  m.CodeWasChanged() &&
+  m.OlderVersion().CyclomaticComplexity > 6 
+
+let complexityScore = complexityScoreProc(m)
+let oldComplexityScore = complexityScoreProc(m.OlderVersion())
+where complexityScore > oldComplexityScore 
+
+let complexityScoreDiff = complexityScoreProc(m) - complexityScoreProc(m.OlderVersion())
+orderby complexityScoreDiff descending
+
+select new { 
+   m,
+   oldComplexityScore ,
+   complexityScore ,
+   diff= complexityScoreDiff,
+
+   Debt = complexityScoreDiff.Linear(1, 15,   50, 60).ToMinutes().ToDebt(),
+
+   // The annual interest varies linearly from interest for severity Medium for a tiny complexity increment
+   // to interest for severity critical for 2000 loc
+   AnnualInterest = complexityScoreDiff.Linear(1,     Severity.High.AnnualInterestThreshold().Value.TotalMinutes, 
+                                               50, 4*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
+   
+}
+
+//<Description>
+// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
+//
+// The method complexity is measured through the code metric
+// *Cyclomatic Complexity* defined here:
+// http://www.ndepend.com/docs/code-metrics#CC
+//
+// This rule warns when a method already complex
+// (i.e with *Cyclomatic Complexity* higher than 6)
+// become even more complex since the baseline.
+//
+// This rule needs assemblies PDB files and source code 
+// to be available at analysis time, because the *Cyclomatic Complexity*
+// is inferred from the source code and source code location
+// is inferred from PDB files. See:
+// http://www.ndepend.com/docs/ndepend-analysis-inputs-explanation
+//
+// To visualize changes in code, right-click a matched method and select:
+//
+// • Compare older and newer versions of source file
+//
+// • or Compare older and newer versions disassembled with Reflector
+//</Description>
+
+//<HowToFix>
+// A large and complex method should be split in smaller methods, 
+// or even one or several classes can be created for that.
+//
+// During this process it is important to question the scope of each
+// variable local to the method. This can be an indication if
+// such local variable will become an instance field of the newly created class(es).
+//
+// Large *switch…case* structures might be refactored through the help
+// of a set of types that implement a common interface, the interface polymorphism
+// playing the role of the *switch cases tests*.
+//
+// Unit Tests can help: write tests for each method before extracting it 
+// to ensure you don't break functionality.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// varies linearly from 15 to 60 minutes depending on the extra complexity added.
+//
+// Issues of this rule have a **High** severity, because it is important to focus 
+// on these issues **now**, before such code gets released in production.
+//</HowToFix>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid making large methods even larger</Name>
+
+warnif count > 0 
+from m in JustMyCode.Methods where
+ !m.IsAbstract &&
+
+ // Eliminate constructors from match, since they get larger
+ // as soons as some fields initialization are added.
+ !m.IsConstructor &&
+ !m.IsClassConstructor &&
+
+  // Filter just here for optimization
+  m.NbLinesOfCode > 15 &&
+
+  m.IsPresentInBothBuilds() &&
+  m.CodeWasChanged() 
+
+let oldLoc = m.OlderVersion().NbLinesOfCode
+where oldLoc > 15 && m.NbLinesOfCode > oldLoc
+
+let diff = m.NbLinesOfCode - oldLoc
+where diff > 0
+orderby diff descending 
+
+select new { 
+   m,
+   oldLoc,
+   newLoc = m.NbLinesOfCode,
+   diff,
+
+   Debt = diff.Linear(1, 10,   100, 60).ToMinutes().ToDebt(),
+
+   // The annual interest varies linearly from interest for severity Medium for a tiny complexity increment
+   // to interest for severity critical for 2000 loc
+   AnnualInterest = diff .Linear(1,      Severity.High.AnnualInterestThreshold().Value.TotalMinutes, 
+                                 100, 4*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
+   
+}
+
+//<Description>
+// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
+//
+// This rule warns when a method already large
+// (i.e with more than 15 lines of code)
+// become even larger since the baseline.
+//
+// The method size is measured through the code metric
+// *# Lines of Code* defined here:
+// http://www.ndepend.com/docs/code-metrics#NbLinesOfCode
+//
+// This rule needs assemblies PDB files 
+// to be available at analysis time, because the *# Lines of Code*
+// is inferred from PDB files. See:
+// http://www.ndepend.com/docs/ndepend-analysis-inputs-explanation
+//
+// To visualize changes in code, right-click a matched method and select:
+//
+// • Compare older and newer versions of source file
+//
+// • or Compare older and newer versions disassembled with Reflector
+//</Description>
+
+//<HowToFix>
+// Usually too big methods should be split in smaller methods.
+//
+// But long methods with no branch conditions, that typically initialize some data,
+// are not necessarily a problem to maintain, and might not need refactoring.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// varies linearly from 5 to 20 minutes depending 
+// on the number of lines of code added.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// varies linearly from 10 to 60 minutes depending on the extra complexity added.
+//
+// Issues of this rule have a **High** severity, because it is important to focus 
+// on these issues **now**, before such code gets released in production.
+//</HowToFix>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid adding methods to a type that already had many methods</Name>
+
+warnif count > 0 
+
+// Don't count constructors and methods generated by the compiler!
+let getMethodsProc = new Func<IType, IList<IMethod>>(
+   t => t.Methods.Where(m =>
+      !m.IsConstructor && !m.IsClassConstructor && 
+      !m.IsGeneratedByCompiler).ToArray()) 
+
+
+from t in JustMyCode.Types where
+  
+  t.NbMethods > 30 &&   // Just here for optimization
+
+  t.IsPresentInBothBuilds()
+
+  // Optimization: fast discard of non-relevant types
+  where t.OlderVersion().NbMethods > 30
+
+  let oldMethods = getMethodsProc(t.OlderVersion())
+  where oldMethods.Count > 30
+
+  let newMethods = getMethodsProc(t)
+  where newMethods.Count > oldMethods.Count
+
+  let addedMethods = newMethods.Where(m => m.WasAdded())
+  let removedMethods = oldMethods.Where(m => m.WasRemoved())
+
+  orderby addedMethods.Count() descending
+
+select new { 
+   t,
+   nbOldMethods = oldMethods.Count,
+   nbNewMethods = newMethods.Count,
+   addedMethods,
+   removedMethods,
+
+   Debt           = (10*addedMethods.Count()).ToMinutes().ToDebt(),
+   AnnualInterest =     addedMethods.Count().Linear(
+          1,       Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes, 
+          100,  4*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
+}
+
+//<Description>
+// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
+//
+// Types where number of methods is greater than 15 
+// might be hard to understand and maintain.
+//
+// This rule lists types that already had more than 15 methods
+// at the baseline time, and for which new methods have been added.
+//
+// Having many methods for a type might be a symptom
+// of too many responsibilities implemented.
+//
+// Notice that constructors and methods generated by the compiler 
+// are not taken account.
+//</Description>
+
+//<HowToFix>
+// To refactor such type and increase code quality and maintainability,
+// certainly you'll have to split the type into several smaller types
+// that together, implement the same logic.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// is equal to 10 minutes per method added.
+//
+// Issues of this rule have a **High** severity, because it is important to focus 
+// on these issues **now**, before such code gets released in production.
+//</HowToFix>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid adding instance fields to a type that already had many instance fields</Name>
+
+warnif count > 0 
+
+let getFieldsProc = new Func<IType, IList<IField>>(
+   t => t.Fields.Where(f => 
+          !f.IsLiteral &&
+          !f.IsGeneratedByCompiler &&
+          !f.IsStatic).ToArray()) 
+
+
+from t in JustMyCode.Types where
+  
+ !t.IsEnumeration &&
+  t.IsPresentInBothBuilds()
+
+  // Optimization: fast discard of non-relevant types
+  where t.OlderVersion().NbFields > 15
+
+  let oldFields = getFieldsProc(t.OlderVersion())
+  where oldFields.Count > 15
+
+  let newFields = getFieldsProc(t)
+  where newFields.Count > oldFields.Count
+
+  let addedFields = newFields.Where(f => f.WasAdded())
+  let removedFields = oldFields.Where(f => f.WasRemoved())
+
+  orderby addedFields.Count() descending
+
+select new { 
+   t,
+   nbOldFields = oldFields.Count,
+   nbNewFields = newFields.Count,
+   addedFields,
+   removedFields,
+
+   Debt           = (10*addedFields.Count()).ToMinutes().ToDebt(),
+   AnnualInterest =     addedFields.Count().Linear(
+          1,       Severity.High.AnnualInterestThreshold().Value.TotalMinutes, 
+          100,  4*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
+
+}
+
+//<Description>
+// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
+//
+// Types where number of fields is greater than 15 
+// might be hard to understand and maintain.
+//
+// This rule lists types that already had more than 15 fields
+// at the baseline time, and for which new fields have been added.
+//
+// Having many fields for a type might be a symptom
+// of too many responsibilities implemented.
+//
+// Notice that *constants* fields and *static-readonly* fields are not taken account.
+// Enumerations types are not taken account also.
+//</Description>
+
+//<HowToFix>
+// To refactor such type and increase code quality and maintainability,
+// certainly you'll have to group subsets of fields into smaller types
+// and dispatch the logic implemented into the methods 
+// into these smaller types.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// is equal to 10 minutes per field added.
+//
+// Issues of this rule have a **High** severity, because it is important to focus 
+// on these issues **now**, before such code gets released in production.
+//</HowToFix>]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[//<Name>Avoid transforming an immutable type into a mutable one</Name>
+
+warnif count > 0
+from t in Application.Types where
+   t.CodeWasChanged() &&
+   t.OlderVersion().IsImmutable &&
+  !t.IsImmutable && 
+  // Don't take account of immutable types transformed into static types (not deemed as immutable)
+  !t.IsStatic
+
+let culpritFields = t.InstanceFields.Where(f => f.IsImmutable)
+select new {
+   t, 
+   culpritFields,
+   Debt = (10 + 10*culpritFields.Count()).ToMinutes().ToDebt(),
+   Severity = Severity.High
+}
+
+//<Description>
+// This rule is executed only if a *baseline for comparison* is defined (*diff mode*).
+//
+// A type is considered as *immutable* if its instance fields
+// cannot be modified once an instance has been built by a constructor.
+//
+// Being immutable has several fortunate consequences for a type.
+// For example its instance objects can be used concurrently 
+// from several threads without the need to synchronize accesses.
+//
+// Hence users of such type often rely on the fact that the type is immutable.
+// If an immutable type becomes mutable, there are chances that this will break 
+// users code.
+//
+// This is why this rule warns about such immutable type that become mutable.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// is equal to 2 minutes per instance field that became mutable.
+//</Description>
+
+//<HowToFix>
+// If being immutable is an important property for a matched type,
+// then the code must be refactored to preserve immutability.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// is equal to 10 minutes plus 10 minutes per instance fields of
+// the matched type that is now mutable.
+//
+// Issues of this rule have a **High** severity, because it is important to focus 
+// on these issues **now**, before such code gets released in production.
+//</HowToFix>]]></Query>
+    </Group>
+    <Group Name="Object Oriented Design" Active="True" ShownInReport="True">
+      <Query Active="False" DisplayList="True" DisplayStat="True" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Avoid interfaces too big</Name>
+warnif count > 0 
+
+from i in JustMyCode.Types
+where i.IsInterface && i.NbMethods >= 10 // Optimization  First threshold
+
+// A get;set; property count as one method
+let properties = i.Methods.Where(m => m.SimpleName.Length > 4 && (m.IsPropertyGetter || m.IsPropertySetter))
+  .Distinct(m => m.SimpleName.Substring(4, m.SimpleName.Length -4))
+
+// An event count as one method
+let events = i.Methods.Where(m => (m.IsEventAdder|| m.IsEventRemover))
+  .Distinct(m => m.SimpleName.Replace("add_","").Replace("remove_",""))
+
+let methods = i.Methods.Where(m => !m.IsPropertyGetter && !m.IsPropertySetter && !m.IsEventAdder && !m.IsEventRemover)
+let methodsCount = methods.Count() + properties.Count() + events.Count()
+where methodsCount >= 10
+let publicFactor = i.IsPubliclyVisible ? 1 : 0.5
+orderby methodsCount descending
+select new {  
+   i, 
+   Methods= methods,
+   Properties = properties,
+   Events = events,
+   Debt = (publicFactor*methodsCount.Linear(10, 20,   100, 7*60)).ToMinutes().ToDebt(),
+   // The annual interest varies linearly from interest for severity Medium for an interface with 10 methods
+   // to interest for severity Critical for an interface with 100 methods and more
+   AnnualInterest = (publicFactor*methodsCount.Linear(
+                       10,  Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes,
+                       100, Severity.Critical.AnnualInterestThreshold().Value.TotalMinutes))
+                     .ToMinutes().ToAnnualInterest()
+}
+
+
+//<Description>
+// This rule matches interfaces with more than 10 methods.
+// Interfaces are abstractions and are meant to simplify the code structure.
+// An interface should represent a single responsibility.
+// Making an interface too large, too complex, necessarily means
+// that the interface has too many responsibilities.
+//
+// A property with getter or setter or both count as one method.
+// An event count as one method.
+//</Description>
+
+//<HowToFix>
+// Typically to fix such issue, the interface must be refactored
+// in a grape of smaller *single-responsibility* interfaces.
+//
+// A classic example is a *ISession* large interface, responsible
+// for holding states, run commands and offer various accesses
+// and facilities.
+//
+// The classic problem for a large public interface is that it has
+// many clients that consume it. As a consequence splitting it in 
+// smaller interfaces has an important impact and it is not always
+// feasible.
+//
+// The estimated Debt, which means the effort to fix such issue,
+// varies linearly from 20 minutes for an interface with 10 methods,
+// up to 7 hours for an interface with 100 or more methods.
+// The Debt is divided by two if the interface is not publicly
+// visible, because in such situation only the current project is impacted
+// by the refactoring.
+//</HowToFix>
+]]></Query>
+      <Query Active="True" DisplayList="True" DisplayStat="False" DisplaySelectionView="False" IsCriticalRule="False"><![CDATA[// <Name>Base class should not use derivatives</Name>
+warnif count > 0 
+let excludedTypes = new[] {"TcpDiscoveryIpFinderBase", "EvictionPolicyBase", "PlatformTargetAdapter"}
+from baseClass in JustMyCode.Types
+where baseClass.IsClass  && !excludedTypes.Contains(baseClass.Name)
+      && baseClass.NbChildren > 0 // <-- for optimization!
+let derivedClassesUsed = baseClass.DerivedTypes.UsedBy(baseClass)
+   // Don't warn when a base class is using nested private derived class
+   .Where(derivedClass => 
+            !(derivedClass.IsNested && 
+              derivedClass.Visibility == Visibility.Private && 
+              derivedClass.ParentType == baseClass
+              ))
+where derivedClassesUsed.Count() > 0
+
+let derivedClassesMemberUsed = derivedClassesUsed.SelectMany(c => c.Members).UsedBy(baseClass)
+orderby derivedClassesMemberUsed.Count() descending
+
+select new { 
+   baseClass, 
+   derivedClassesUsed,
+   derivedClassesMemberUsed,
+
+   Debt = 3*(derivedClassesUsed.Count()+derivedClassesMemberUsed.Count()).ToMinutes().ToDebt(),
+   Severity = Severity.High
+}
+
+//<Description>
+// In *Object-Oriented Programming*, the **open/closed principle** states:
+// *software entities (components, classes, methods, etc.) should be open 
+// for extension, but closed for modification*. 
+// http://en.wikipedia.org/wiki/Open/closed_principle
+//
+// Hence a base class should be designed properly to make it easy to derive from,
+// this is *extension*. But creating a new derived class, or modifying an
+// existing one, shouldn't provoke any *modification* in the base class.
+// And if a base class is using some derivative classes somehow, there
+// are good chances that such *modification* will be needed.
+//
+// Extending the base class is not anymore a simple operation,
+// this is not good design.
+//
+// Note that this rule doesn't warn when a base class is using a derived class 
+// that is nested in t

<TRUNCATED>

[13/50] [abbrv] ignite git commit: IGNITE-6422 Visor CMD: Fixed cache statistics output.

Posted by ag...@apache.org.
IGNITE-6422 Visor CMD: Fixed cache statistics output.


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

Branch: refs/heads/ignite-6305
Commit: 16d23700d25961aae8d75e11c55349fab78f2a79
Parents: 5764960
Author: vsisko <vs...@gridgain.com>
Authored: Mon Oct 2 23:08:40 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Oct 2 23:08:40 2017 +0700

----------------------------------------------------------------------
 .../cache/VisorCacheAggregatedMetrics.java      | 24 ++++++-------
 .../commands/cache/VisorCacheCommand.scala      | 38 ++++++++++----------
 2 files changed, 31 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/16d23700/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 ccefa67..a0258cc 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
@@ -208,35 +208,35 @@ public class VisorCacheAggregatedMetrics extends VisorDataTransferObject {
 
     /**
      * @param metric Metrics to process.
-     * @return Off heap entries count.
+     * @return Off heap primary entries count.
      */
-    private long getOffHeapEntriesCount(VisorCacheMetrics metric) {
-        return metric.getOffHeapEntriesCount();
+    private long getOffHeapPrimaryEntriesCount(VisorCacheMetrics metric) {
+        return metric.getOffHeapPrimaryEntriesCount();
     }
 
     /**
-     * @return Minimum number of elements in off heap.
+     * @return Minimum number of primary elements in off heap.
      */
-    public long getMinimumOffHeapSize() {
+    public long getMinimumOffHeapPrimarySize() {
         if (minOffHeapSize == null) {
             minOffHeapSize = Long.MAX_VALUE;
 
             for (VisorCacheMetrics metric : metrics.values())
-                minOffHeapSize = Math.min(minOffHeapSize, getOffHeapEntriesCount(metric));
+                minOffHeapSize = Math.min(minOffHeapSize, getOffHeapPrimaryEntriesCount(metric));
         }
 
         return minOffHeapSize;
     }
 
     /**
-     * @return Average number of elements in off heap.
+     * @return Average number of primary elements in off heap.
      */
-    public double getAverageOffHeapSize() {
+    public double getAverageOffHeapPrimarySize() {
         if (avgOffHeapSize == null) {
             avgOffHeapSize = 0.0d;
 
             for (VisorCacheMetrics metric : metrics.values())
-                avgOffHeapSize += getOffHeapEntriesCount(metric);
+                avgOffHeapSize += getOffHeapPrimaryEntriesCount(metric);
 
             avgOffHeapSize /= metrics.size();
         }
@@ -245,14 +245,14 @@ public class VisorCacheAggregatedMetrics extends VisorDataTransferObject {
     }
 
     /**
-     * @return Maximum number of elements in off heap in the cache.
+     * @return Maximum number of primary elements in off heap.
      */
-    public long getMaximumOffHeapSize() {
+    public long getMaximumOffHeapPrimarySize() {
         if (maxOffHeapSize == null) {
             maxOffHeapSize = Long.MIN_VALUE;
 
             for (VisorCacheMetrics metric : metrics.values())
-                maxOffHeapSize = Math.max(maxOffHeapSize, getOffHeapEntriesCount(metric));
+                maxOffHeapSize = Math.max(maxOffHeapSize, getOffHeapPrimaryEntriesCount(metric));
         }
 
         return maxOffHeapSize;

http://git-wip-us.apache.org/repos/asf/ignite/blob/16d23700/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheCommand.scala
----------------------------------------------------------------------
diff --git a/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheCommand.scala b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheCommand.scala
index f754275..dde3289 100755
--- a/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheCommand.scala
+++ b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheCommand.scala
@@ -328,12 +328,12 @@ class VisorCacheCommand {
                         ad.getMode,
                         ad.getNodes.size(),
                         (
-                            "min: " + (ad.getMinimumHeapSize + ad.getMinimumOffHeapSize) +
-                                " (" + ad.getMinimumHeapSize + " / " + ad.getMinimumOffHeapSize + ")",
-                            "avg: " + formatDouble(ad.getAverageHeapSize + ad.getAverageOffHeapSize) +
-                                " (" + formatDouble(ad.getAverageHeapSize) + " / " + formatDouble(ad.getAverageOffHeapSize) + ")",
-                            "max: " + (ad.getMaximumHeapSize + ad.getMaximumOffHeapSize) +
-                                " (" + ad.getMaximumHeapSize + " / " + ad.getMaximumOffHeapSize + ")"
+                            "min: " + (ad.getMinimumHeapSize + ad.getMinimumOffHeapPrimarySize) +
+                                " (" + ad.getMinimumHeapSize + " / " + ad.getMinimumOffHeapPrimarySize + ")",
+                            "avg: " + formatDouble(ad.getAverageHeapSize + ad.getAverageOffHeapPrimarySize) +
+                                " (" + formatDouble(ad.getAverageHeapSize) + " / " + formatDouble(ad.getAverageOffHeapPrimarySize) + ")",
+                            "max: " + (ad.getMaximumHeapSize + ad.getMaximumOffHeapPrimarySize) +
+                                " (" + ad.getMaximumHeapSize + " / " + ad.getMaximumOffHeapPrimarySize + ")"
                             ),
                         (
                             "min: " + ad.getMinimumHits,
@@ -385,13 +385,13 @@ class VisorCacheCommand {
 
                     csT += ("Name(@)", cacheNameVar)
                     csT += ("Nodes", m.size())
-                    csT += ("Total size Min/Avg/Max", (ad.getMinimumHeapSize + ad.getMinimumOffHeapSize) + " / " +
-                        formatDouble(ad.getAverageHeapSize + ad.getAverageOffHeapSize) + " / " +
-                        (ad.getMaximumHeapSize + ad.getMaximumOffHeapSize))
+                    csT += ("Total size Min/Avg/Max", (ad.getMinimumHeapSize + ad.getMinimumOffHeapPrimarySize) + " / " +
+                        formatDouble(ad.getAverageHeapSize + ad.getAverageOffHeapPrimarySize) + " / " +
+                        (ad.getMaximumHeapSize + ad.getMaximumOffHeapPrimarySize))
                     csT += ("  Heap size Min/Avg/Max", ad.getMinimumHeapSize + " / " +
                         formatDouble(ad.getAverageHeapSize) + " / " + ad.getMaximumHeapSize)
-                    csT += ("  Off-heap size Min/Avg/Max", ad.getMinimumOffHeapSize + " / " +
-                        formatDouble(ad.getAverageOffHeapSize) + " / " + ad.getMaximumOffHeapSize)
+                    csT += ("  Off-heap size Min/Avg/Max", ad.getMinimumOffHeapPrimarySize + " / " +
+                        formatDouble(ad.getAverageOffHeapPrimarySize) + " / " + ad.getMaximumOffHeapPrimarySize)
 
                     val ciT = VisorTextTable()
 
@@ -408,9 +408,9 @@ class VisorCacheCommand {
                             formatDouble(nm.getCurrentCpuLoad * 100d) + " %",
                             X.timeSpan2HMSM(nm.getUpTime),
                             (
-                                "Total: " + (cm.getHeapEntriesCount + cm.getOffHeapEntriesCount()),
+                                "Total: " + (cm.getHeapEntriesCount + cm.getOffHeapPrimaryEntriesCount),
                                 "  Heap: " + cm.getHeapEntriesCount,
-                                "  Off-Heap: " + cm.getOffHeapEntriesCount(),
+                                "  Off-Heap: " + cm.getOffHeapPrimaryEntriesCount,
                                 "  Off-Heap Memory: " + formatMemory(cm.getOffHeapAllocatedSize)
                             ),
                             (
@@ -644,12 +644,12 @@ class VisorCacheCommand {
                 mkCacheName(ad.getName),
                 ad.getMode,
                 (
-                    "min: " + (ad.getMinimumHeapSize + ad.getMinimumOffHeapSize) +
-                        " (" + ad.getMinimumHeapSize + " / " + ad.getMinimumOffHeapSize + ")",
-                    "avg: " + formatDouble(ad.getAverageHeapSize + ad.getAverageOffHeapSize) +
-                        " (" + formatDouble(ad.getAverageHeapSize) + " / " + formatDouble(ad.getAverageOffHeapSize) + ")",
-                    "max: " + (ad.getMaximumHeapSize + ad.getMaximumOffHeapSize) +
-                        " (" + ad.getMaximumHeapSize + " / " + ad.getMaximumOffHeapSize + ")"
+                    "min: " + (ad.getMinimumHeapSize + ad.getMinimumOffHeapPrimarySize) +
+                        " (" + ad.getMinimumHeapSize + " / " + ad.getMinimumOffHeapPrimarySize + ")",
+                    "avg: " + formatDouble(ad.getAverageHeapSize + ad.getAverageOffHeapPrimarySize) +
+                        " (" + formatDouble(ad.getAverageHeapSize) + " / " + formatDouble(ad.getAverageOffHeapPrimarySize) + ")",
+                    "max: " + (ad.getMaximumHeapSize + ad.getMaximumOffHeapPrimarySize) +
+                        " (" + ad.getMaximumHeapSize + " / " + ad.getMaximumOffHeapPrimarySize + ")"
                 ))
         })
 


[25/50] [abbrv] ignite git commit: IGNITE-6547 Support logging timestamp for WAL tx and data records - Fixes #2792.

Posted by ag...@apache.org.
IGNITE-6547 Support logging timestamp for WAL tx and data records - Fixes #2792.

Signed-off-by: Alexey Goncharuk <al...@gmail.com>


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

Branch: refs/heads/ignite-6305
Commit: e6e1ca9a5a9155a550258b112415b65845d6bcef
Parents: 78f77b1
Author: Dmitriy Govorukhin <dm...@gmail.com>
Authored: Wed Oct 4 18:54:49 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Wed Oct 4 18:54:49 2017 +0300

----------------------------------------------------------------------
 .../internal/pagemem/wal/record/DataRecord.java |  20 +-
 .../pagemem/wal/record/TimeStampRecord.java     |  57 ++++++
 .../internal/pagemem/wal/record/TxRecord.java   |  52 +++--
 .../reader/StandaloneWalRecordsIterator.java    |   2 +-
 .../wal/serializer/RecordDataV1Serializer.java  |   6 +-
 .../wal/serializer/RecordDataV2Serializer.java  |  49 ++++-
 .../wal/serializer/TxRecordSerializer.java      |   3 +-
 .../cache/transactions/IgniteTxAdapter.java     |   3 +-
 .../db/wal/IgniteWalSerializerVersionTest.java  | 205 ++++++++++++++++++-
 9 files changed, 365 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e6e1ca9a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/DataRecord.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/DataRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/DataRecord.java
index 0e92383..ac569bd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/DataRecord.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/DataRecord.java
@@ -27,7 +27,7 @@ import org.apache.ignite.internal.util.typedef.internal.S;
  * This record contains information about operation we want to do.
  * Contains operation type (put, remove) and (Key, Value, Version) for each {@link DataEntry}
  */
-public class DataRecord extends WALRecord {
+public class DataRecord extends TimeStampRecord {
     /** */
     @GridToStringInclude
     private List<DataEntry> writeEntries;
@@ -59,6 +59,24 @@ public class DataRecord extends WALRecord {
     }
 
     /**
+     * @param writeEntry Write entry.
+     * @param timestamp TimeStamp.
+     */
+    public DataRecord(DataEntry writeEntry, long timestamp) {
+        this(Collections.singletonList(writeEntry), timestamp);
+    }
+
+    /**
+     * @param writeEntries Write entries.
+     * @param timestamp TimeStamp.
+     */
+    public DataRecord(List<DataEntry> writeEntries, long timestamp) {
+        super(timestamp);
+
+        this.writeEntries = writeEntries;
+    }
+
+    /**
      * @return Collection of write entries.
      */
     public List<DataEntry> writeEntries() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6e1ca9a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/TimeStampRecord.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/TimeStampRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/TimeStampRecord.java
new file mode 100644
index 0000000..3f29dfd
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/TimeStampRecord.java
@@ -0,0 +1,57 @@
+/*
+ * 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.pagemem.wal.record;
+
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ * Base class for records with timeStamp.
+ * All records which support timeStamp should be inherited from {@code TimeStampRecord}.
+ */
+public abstract class TimeStampRecord extends WALRecord {
+    /** Timestamp. */
+    protected long timestamp;
+
+    /**
+     *
+     */
+    protected TimeStampRecord() {
+        timestamp = U.currentTimeMillis();
+    }
+
+    /**
+     * @param timestamp TimeStamp.
+     */
+    protected TimeStampRecord(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    /**
+     * @param timestamp TimeStamp.
+     */
+    public void timestamp(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    /**
+     * @return TimeStamp.
+     */
+    public long timestamp() {
+        return timestamp;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6e1ca9a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/TxRecord.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/TxRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/TxRecord.java
index ce1e28e..f933fa9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/TxRecord.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/TxRecord.java
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable;
  * Logical data record indented for transaction (tx) related actions.<br>
  * This record is marker of begin, prepare, commit, and rollback transactions.
  */
-public class TxRecord extends WALRecord {
+public class TxRecord extends TimeStampRecord {
     /** Transaction state. */
     private TransactionState state;
 
@@ -49,28 +49,51 @@ public class TxRecord extends WALRecord {
     /** If transaction is remote, primary node for this backup node. */
     @Nullable private Object primaryNode;
 
-    /** Timestamp of Tx state change. */
-    private long timestamp;
-
     /**
      *
      * @param state Transaction state.
      * @param nearXidVer Transaction id.
      * @param writeVer Transaction entries write topology version.
      * @param participatingNodes Primary -> Backup nodes participating in transaction.
+     * @param primaryNode Primary node.
      */
-    public TxRecord(TransactionState state,
-                    GridCacheVersion nearXidVer,
-                    GridCacheVersion writeVer,
-                    @Nullable Map<Object, Collection<Object>> participatingNodes,
-                    @Nullable Object primaryNode,
-                    long timestamp) {
+    public TxRecord(
+        TransactionState state,
+        GridCacheVersion nearXidVer,
+        GridCacheVersion writeVer,
+        @Nullable Map<Object, Collection<Object>> participatingNodes,
+        @Nullable Object primaryNode
+    ) {
+        this.state = state;
+        this.nearXidVer = nearXidVer;
+        this.writeVer = writeVer;
+        this.participatingNodes = participatingNodes;
+        this.primaryNode = primaryNode;
+    }
+
+    /**
+     * @param state Transaction state.
+     * @param nearXidVer Transaction id.
+     * @param writeVer Transaction entries write topology version.
+     * @param participatingNodes Primary -> Backup nodes participating in transaction.
+     * @param primaryNode Primary node.
+     * @param timestamp TimeStamp.
+     */
+    public TxRecord(
+        TransactionState state,
+        GridCacheVersion nearXidVer,
+        GridCacheVersion writeVer,
+        @Nullable Map<Object, Collection<Object>> participatingNodes,
+        @Nullable Object primaryNode,
+        long timestamp
+    ) {
+        super(timestamp);
+
         this.state = state;
         this.nearXidVer = nearXidVer;
         this.writeVer = writeVer;
         this.participatingNodes = participatingNodes;
         this.primaryNode = primaryNode;
-        this.timestamp = timestamp;
     }
 
     /** {@inheritDoc} */
@@ -148,13 +171,6 @@ public class TxRecord extends WALRecord {
         return primaryNode;
     }
 
-    /**
-     * @return Timestamp of Tx state change in millis.
-     */
-    public long timestamp() {
-        return timestamp;
-    }
-
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(TxRecord.class, this, "super", super.toString());

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6e1ca9a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
index f1258a0..24b2148 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
@@ -305,7 +305,7 @@ class StandaloneWalRecordsIterator extends AbstractWalRecordsIterator {
 
             postProcessedEntries.add(postProcessedEntry);
         }
-        return new DataRecord(postProcessedEntries);
+        return new DataRecord(postProcessedEntries, dataRec.timestamp());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6e1ca9a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java
index 8b5e6ba..e583df3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java
@@ -384,7 +384,7 @@ public class RecordDataV1Serializer implements RecordDataSerializer {
                 for (int i = 0; i < entryCnt; i++)
                     entries.add(readDataEntry(in));
 
-                res = new DataRecord(entries);
+                res = new DataRecord(entries, 0L);
 
                 break;
 
@@ -1322,7 +1322,7 @@ public class RecordDataV1Serializer implements RecordDataSerializer {
      * @param buf Buffer to write to.
      * @param entry Data entry.
      */
-    private static void putDataEntry(ByteBuffer buf, DataEntry entry) throws IgniteCheckedException {
+    static void putDataEntry(ByteBuffer buf, DataEntry entry) throws IgniteCheckedException {
         buf.putInt(entry.cacheId());
 
         if (!entry.key().putValue(buf))
@@ -1390,7 +1390,7 @@ public class RecordDataV1Serializer implements RecordDataSerializer {
      * @param in Input to read from.
      * @return Read entry.
      */
-    private DataEntry readDataEntry(ByteBufferBackedDataInput in) throws IOException, IgniteCheckedException {
+    DataEntry readDataEntry(ByteBufferBackedDataInput in) throws IOException, IgniteCheckedException {
         int cacheId = in.readInt();
 
         int keySize = in.readInt();

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6e1ca9a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV2Serializer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV2Serializer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV2Serializer.java
index 2b55c5f..c02f36e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV2Serializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV2Serializer.java
@@ -19,7 +19,11 @@ package org.apache.ignite.internal.processors.cache.persistence.wal.serializer;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
 import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.pagemem.wal.record.DataEntry;
+import org.apache.ignite.internal.pagemem.wal.record.DataRecord;
 import org.apache.ignite.internal.pagemem.wal.record.WALRecord;
 import org.apache.ignite.internal.processors.cache.persistence.wal.ByteBufferBackedDataInput;
 import org.apache.ignite.internal.processors.cache.persistence.wal.RecordDataSerializer;
@@ -46,12 +50,35 @@ public class RecordDataV2Serializer implements RecordDataSerializer {
         if (record instanceof HeaderRecord)
             throw new UnsupportedOperationException("Getting size of header records is forbidden since version 2 of serializer");
 
-        return delegateSerializer.size(record);
+        switch (record.type()) {
+            case DATA_RECORD:
+                return delegateSerializer.size(record) + 8/*timestamp*/;
+
+            default:
+                return delegateSerializer.size(record);
+        }
     }
 
     /** {@inheritDoc} */
-    @Override public WALRecord readRecord(WALRecord.RecordType type, ByteBufferBackedDataInput in) throws IOException, IgniteCheckedException {
-        return delegateSerializer.readRecord(type, in);
+    @Override public WALRecord readRecord(
+        WALRecord.RecordType type,
+        ByteBufferBackedDataInput in
+    ) throws IOException, IgniteCheckedException {
+        switch (type) {
+            case DATA_RECORD:
+                int entryCnt = in.readInt();
+                long timeStamp = in.readLong();
+
+                List<DataEntry> entries = new ArrayList<>(entryCnt);
+
+                for (int i = 0; i < entryCnt; i++)
+                    entries.add(delegateSerializer.readDataEntry(in));
+
+                return new DataRecord(entries, timeStamp);
+
+            default:
+                return delegateSerializer.readRecord(type, in);
+        }
     }
 
     /** {@inheritDoc} */
@@ -59,6 +86,20 @@ public class RecordDataV2Serializer implements RecordDataSerializer {
         if (record instanceof HeaderRecord)
             throw new UnsupportedOperationException("Writing header records is forbidden since version 2 of serializer");
 
-        delegateSerializer.writeRecord(record, buf);
+        switch (record.type()) {
+            case DATA_RECORD:
+                DataRecord dataRec = (DataRecord)record;
+
+                buf.putInt(dataRec.writeEntries().size());
+                buf.putLong(dataRec.timestamp());
+
+                for (DataEntry dataEntry : dataRec.writeEntries())
+                    RecordDataV1Serializer.putDataEntry(buf, dataEntry);
+
+                break;
+
+            default:
+                delegateSerializer.writeRecord(record, buf);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6e1ca9a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/TxRecordSerializer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/TxRecordSerializer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/TxRecordSerializer.java
index 448bdbc..e8b324d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/TxRecordSerializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/TxRecordSerializer.java
@@ -75,9 +75,8 @@ public class TxRecordSerializer {
 
                 buf.putInt(backupNodes.size());
 
-                for (Object backupNode : backupNodes) {
+                for (Object backupNode : backupNodes)
                     writeConsistentId(backupNode, buf);
-                }
             }
         }
         else {

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6e1ca9a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
index b5178b5..00c637e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
@@ -1116,8 +1116,7 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter implement
                             nearXidVersion(),
                             writeVersion(),
                             participatingNodes,
-                            remote() ? nodeId() : null,
-                            U.currentTimeMillis()
+                            remote() ? nodeId() : null
                     );
 
                     try {

http://git-wip-us.apache.org/repos/asf/ignite/blob/e6e1ca9a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/IgniteWalSerializerVersionTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/IgniteWalSerializerVersionTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/IgniteWalSerializerVersionTest.java
index f31d0f9..ddf74c8 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/IgniteWalSerializerVersionTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/IgniteWalSerializerVersionTest.java
@@ -17,23 +17,38 @@
 
 package org.apache.ignite.internal.processors.cache.persistence.db.wal;
 
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.PersistentStoreConfiguration;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager;
+import org.apache.ignite.internal.pagemem.wal.WALIterator;
+import org.apache.ignite.internal.pagemem.wal.WALPointer;
+import org.apache.ignite.internal.pagemem.wal.record.DataEntry;
+import org.apache.ignite.internal.pagemem.wal.record.DataRecord;
+import org.apache.ignite.internal.pagemem.wal.record.TimeStampRecord;
+import org.apache.ignite.internal.pagemem.wal.record.TxRecord;
+import org.apache.ignite.internal.pagemem.wal.record.WALRecord;
 import org.apache.ignite.internal.processors.cache.persistence.wal.RecordSerializer;
 import org.apache.ignite.internal.processors.cache.persistence.wal.serializer.RecordV1Serializer;
 import org.apache.ignite.internal.processors.cache.persistence.wal.serializer.RecordV2Serializer;
 import org.apache.ignite.internal.util.typedef.internal.GPC;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteBiTuple;
+import org.apache.ignite.lang.IgniteCallable;
 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.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.TransactionState;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_WAL_SERIALIZER_VERSION;
+import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.DFLT_STORE_DIR;
 
 /**
  *
@@ -46,7 +61,7 @@ public class IgniteWalSerializerVersionTest extends GridCommonAbstractTest {
     @Override protected IgniteConfiguration getConfiguration(String name) throws Exception {
         IgniteConfiguration cfg = super.getConfiguration(name);
 
-        ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(IP_FINDER);
+        cfg.setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(IP_FINDER));
 
         cfg.setPersistentStoreConfiguration(new PersistentStoreConfiguration());
 
@@ -101,4 +116,192 @@ public class IgniteWalSerializerVersionTest extends GridCommonAbstractTest {
 
         stopGrid();
     }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testCheckDifferentSerializerVersionsAndLogTimestamp() throws Exception {
+        IgniteCallable<List<WALRecord>> recordsFactory = new IgniteCallable<List<WALRecord>>() {
+            @Override public List<WALRecord> call() throws Exception {
+                WALRecord rec0 = new DataRecord(Collections.<DataEntry>emptyList());
+
+                WALRecord rec1 = new TxRecord(
+                    TransactionState.PREPARED,
+                    null,
+                    null,
+                    null,
+                    null
+                );
+
+                return Arrays.asList(rec0, rec1);
+            }
+        };
+
+        long time0 = U.currentTimeMillis();
+
+        check(new Checker(
+            1,
+            RecordV1Serializer.class,
+            recordsFactory,
+            Arrays.asList(0L, time0)
+        ));
+
+        long time1 = U.currentTimeMillis();
+
+        check(new Checker(
+            2,
+            RecordV2Serializer.class,
+            recordsFactory,
+            Arrays.asList(time1, time1)
+        ));
+    }
+
+    /**
+     *
+     */
+    public static class Checker {
+        /** */
+        private final int serializerVer;
+
+        /** */
+        private final Class serializer;
+
+        /** */
+        private final List<Long> timeStamps;
+
+        /** */
+        private final IgniteCallable<List<WALRecord>> recordsToWrite;
+
+        /**
+         *
+         */
+        public Checker(
+            int serializerVer,
+            Class serializer,
+            IgniteCallable<List<WALRecord>> recordsToWrite,
+            List<Long> timeStamps) {
+            this.serializerVer = serializerVer;
+            this.serializer = serializer;
+            this.timeStamps = timeStamps;
+            this.recordsToWrite = recordsToWrite;
+        }
+
+        /**
+         *
+         */
+        public int serializerVersion() {
+            return serializerVer;
+        }
+
+        /**
+         *
+         */
+        public Class serializer() {
+            return serializer;
+        }
+
+        /**
+         *
+         */
+        public List<Long> getTimeStamps() {
+            return timeStamps;
+        }
+
+        /**
+         *
+         */
+        public List<WALRecord> recordsToWrite() throws Exception {
+            return recordsToWrite.call();
+        }
+
+        /**
+         *
+         */
+        public void assertRecords(long exp, WALRecord act) {
+            if (act instanceof TimeStampRecord) {
+                TimeStampRecord act0 = (TimeStampRecord)act;
+
+                if (exp == 0L)
+                    assertTrue(act0.timestamp() == 0L);
+                else{
+                    long diff = Math.abs(exp - act0.timestamp());
+
+                    assertTrue(String.valueOf(diff), diff < 10_000);
+                }
+            }
+            else
+                fail();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void check(Checker checker) throws Exception {
+        System.setProperty(IGNITE_WAL_SERIALIZER_VERSION, Integer.toString(checker.serializerVersion()));
+
+        IgniteEx ig0 = (IgniteEx)startGrid();
+
+        ig0.active(true);
+
+        IgniteWriteAheadLogManager wal = ig0.context().cache().context().wal();
+
+        RecordSerializer ser0 = U.field(wal, "serializer");
+
+        assertTrue(ser0.getClass().getName().equals(checker.serializer().getName()));
+
+        List<WALRecord> recs = checker.recordsToWrite();
+
+        assertTrue(!recs.isEmpty());
+
+        WALPointer p = null;
+
+        for (WALRecord rec : recs) {
+            WALPointer p0 = wal.log(rec);
+
+            if (p == null)
+                p = p0;
+        }
+
+        wal.fsync(null);
+
+        Iterator<Long> itToCheck = checker.getTimeStamps().iterator();
+
+        try (WALIterator it = wal.replay(p)) {
+            while (it.hasNext()) {
+                IgniteBiTuple<WALPointer, WALRecord> tup0 = it.next();
+
+                checker.assertRecords(itToCheck.next(), tup0.get2());
+            }
+        }
+
+        stopGrid();
+
+        System.clearProperty(IGNITE_WAL_SERIALIZER_VERSION);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        stopAllGrids();
+
+        deleteWorkFiles();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        stopAllGrids();
+
+        deleteWorkFiles();
+    }
+
+    /**
+     * @throws IgniteCheckedException If failed.
+     */
+    private void deleteWorkFiles() throws IgniteCheckedException {
+        deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), DFLT_STORE_DIR, false));
+    }
 }


[22/50] [abbrv] ignite git commit: IGNITE-6285 Enhance persistent store paths handling - Fixes #2775.

Posted by ag...@apache.org.
IGNITE-6285 Enhance persistent store paths handling - Fixes #2775.

Signed-off-by: Alexey Goncharuk <al...@gmail.com>


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

Branch: refs/heads/ignite-6305
Commit: 62f3c4c52f5aad82e51e93b7981e670090cddd4c
Parents: 855fe4b
Author: dpavlov <dp...@gridgain.com>
Authored: Wed Oct 4 09:46:16 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Wed Oct 4 09:46:16 2017 +0300

----------------------------------------------------------------------
 .../FoldersReuseCompatibilityTest.java          | 224 ++++++
 ...itePersistenceCompatibilityAbstractTest.java |   3 +
 .../IgniteCompatibilityBasicTestSuite.java      |   3 +
 .../apache/ignite/IgniteSystemProperties.java   |   7 +
 .../ignite/internal/GridKernalContext.java      |   6 +
 .../ignite/internal/GridKernalContextImpl.java  |  17 +-
 .../apache/ignite/internal/IgniteKernal.java    |   4 +-
 .../discovery/GridDiscoveryManager.java         |  55 +-
 .../cache/binary/BinaryMetadataFileStore.java   |   6 +-
 .../GridCacheDatabaseSharedManager.java         |  91 ++-
 .../IgniteCacheDatabaseSharedManager.java       |  13 +-
 .../persistence/file/FilePageStoreManager.java  |  29 +-
 .../filename/PdsConsistentIdProcessor.java      | 568 +++++++++++++++
 .../persistence/filename/PdsFolderSettings.java | 138 ++++
 .../filename/PdsFoldersResolver.java            |  33 +
 .../wal/FileWriteAheadLogManager.java           |  20 +-
 .../wal/reader/StandaloneGridKernalContext.java |  32 +-
 .../spi/discovery/tcp/TcpDiscoverySpi.java      |   4 +-
 .../tcp/internal/TcpDiscoveryNode.java          |  15 +
 .../IgniteUidAsConsistentIdMigrationTest.java   | 712 +++++++++++++++++++
 .../db/wal/IgniteWalRecoveryTest.java           |  13 +-
 .../db/wal/reader/IgniteWalReaderTest.java      | 187 +++--
 .../db/wal/reader/MockWalIteratorFactory.java   |  25 +-
 .../ignite/testsuites/IgnitePdsTestSuite2.java  |   4 +
 24 files changed, 1995 insertions(+), 214 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/FoldersReuseCompatibilityTest.java
----------------------------------------------------------------------
diff --git a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/FoldersReuseCompatibilityTest.java b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/FoldersReuseCompatibilityTest.java
new file mode 100644
index 0000000..1775013
--- /dev/null
+++ b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/FoldersReuseCompatibilityTest.java
@@ -0,0 +1,224 @@
+/*
+ * 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.compatibility.persistence;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.TreeSet;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.MemoryConfiguration;
+import org.apache.ignite.configuration.MemoryPolicyConfiguration;
+import org.apache.ignite.configuration.PersistentStoreConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.GridCacheAbstractFullApiSelfTest;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteInClosure;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.jetbrains.annotations.NotNull;
+
+import static org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor.parseSubFolderName;
+
+/**
+ * Test for new and old style persistent storage folders generation and compatible startup of current ignite version
+ */
+public class FoldersReuseCompatibilityTest extends IgnitePersistenceCompatibilityAbstractTest {
+    /** Cache name for test. */
+    private static final String CACHE_NAME = "dummy";
+
+    /** Key to store in previous version of ignite */
+    private static final String KEY = "ObjectFromPast";
+
+    /** Value to store in previous version of ignite */
+    private static final String VAL = "ValueFromPast";
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        // No-op. super.afterTest();
+        stopAllGrids();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        final IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        configPersistence(cfg);
+
+        return cfg;
+    }
+
+    /**
+     * Test startup of current ignite version using DB storage folder from previous version of Ignite. Expected to start
+     * successfully with existing DB
+     *
+     * @throws Exception if failed.
+     */
+    public void testFoldersReuseCompatibility_2_2() throws Exception {
+        runFoldersReuse("2.2.0");
+    }
+
+    /**
+     * Test startup of current ignite version using DB storage folder from previous version of Ignite. Expected to start
+     * successfully with existing DB
+     *
+     * @throws Exception if failed.
+     */
+    public void testFoldersReuseCompatibility_2_1() throws Exception {
+        runFoldersReuse("2.1.0");
+    }
+
+    /**
+     * Test startup of current ignite version using DB storage folder from previous version of Ignite. Expected to start
+     * successfully with existing DB
+     *
+     * @param ver 3 digit Ignite version to check compatibility with
+     * @throws Exception if failed.
+     */
+    private void runFoldersReuse(String ver) throws Exception {
+        final IgniteEx grid = startGrid(1, ver, new ConfigurationClosure(), new PostStartupClosure());
+
+        grid.close();
+        stopAllGrids();
+
+        IgniteEx ignite = startGrid(0);
+
+        ignite.active(true);
+        ignite.getOrCreateCache("cache2createdForNewGrid").put("Object", "Value");
+        assertEquals(1, ignite.context().discovery().topologyVersion());
+
+        assertPdsDirsDefaultExist(U.maskForFileName(ignite.cluster().node().consistentId().toString()));
+
+        assertEquals(VAL, ignite.cache(CACHE_NAME).get(KEY));
+
+        assertNodeIndexesInFolder();// should not create any new style directories
+
+        stopAllGrids();
+    }
+
+    /** Started node test actions closure. */
+    private static class PostStartupClosure implements IgniteInClosure<Ignite> {
+        /** {@inheritDoc} */
+        @Override public void apply(Ignite ignite) {
+            ignite.active(true);
+            ignite.getOrCreateCache(CACHE_NAME).put(KEY, VAL);
+        }
+    }
+
+    /** Setup compatible node closure. */
+    private static class ConfigurationClosure implements IgniteInClosure<IgniteConfiguration> {
+        /** {@inheritDoc} */
+        @Override public void apply(IgniteConfiguration cfg) {
+            cfg.setLocalHost("127.0.0.1");
+            TcpDiscoverySpi disco = new TcpDiscoverySpi();
+            disco.setIpFinder(GridCacheAbstractFullApiSelfTest.LOCAL_IP_FINDER);
+
+            cfg.setDiscoverySpi(disco);
+
+            configPersistence(cfg);
+        }
+    }
+
+    /**
+     * Setup persistence for compatible and current version node.
+     *
+     * @param cfg ignite config to setup.
+     */
+    private static void configPersistence(IgniteConfiguration cfg) {
+        final PersistentStoreConfiguration psCfg = new PersistentStoreConfiguration();
+
+        cfg.setPersistentStoreConfiguration(psCfg);
+
+        final MemoryConfiguration memCfg = new MemoryConfiguration();
+        final MemoryPolicyConfiguration memPolCfg = new MemoryPolicyConfiguration();
+
+        memPolCfg.setMaxSize(32 * 1024 * 1024); // we don't need much memory for this test
+        memCfg.setMemoryPolicies(memPolCfg);
+        cfg.setMemoryConfiguration(memCfg);
+    }
+
+    /**
+     * @param indexes expected new style node indexes in folders
+     * @throws IgniteCheckedException if failed
+     */
+    private void assertNodeIndexesInFolder(Integer... indexes) throws IgniteCheckedException {
+        assertEquals(new TreeSet<>(Arrays.asList(indexes)), getAllNodeIndexesInFolder());
+    }
+
+    /**
+     * @return set of all indexes of nodes found in work folder
+     * @throws IgniteCheckedException if failed.
+     */
+    @NotNull private Set<Integer> getAllNodeIndexesInFolder() throws IgniteCheckedException {
+        final File curFolder = new File(U.defaultWorkDirectory(), PdsConsistentIdProcessor.DB_DEFAULT_FOLDER);
+        final Set<Integer> indexes = new TreeSet<>();
+        final File[] files = curFolder.listFiles(PdsConsistentIdProcessor.DB_SUBFOLDERS_NEW_STYLE_FILTER);
+
+        for (File file : files) {
+            final PdsConsistentIdProcessor.FolderCandidate uid
+                = parseSubFolderName(file, log);
+
+            if (uid != null)
+                indexes.add(uid.nodeIndex());
+        }
+
+        return indexes;
+    }
+
+    /**
+     * Checks existence of all storage-related directories
+     *
+     * @param subDirName sub directories name expected
+     * @throws IgniteCheckedException if IO error occur
+     */
+    private void assertPdsDirsDefaultExist(String subDirName) throws IgniteCheckedException {
+        assertDirectoryExist("binary_meta", subDirName);
+        assertDirectoryExist(PersistentStoreConfiguration.DFLT_WAL_STORE_PATH, subDirName);
+        assertDirectoryExist(PersistentStoreConfiguration.DFLT_WAL_ARCHIVE_PATH, subDirName);
+        assertDirectoryExist(PdsConsistentIdProcessor.DB_DEFAULT_FOLDER, subDirName);
+    }
+
+    /**
+     * Checks one folder existence
+     *
+     * @param subFolderNames subfolders array to touch
+     * @throws IgniteCheckedException if IO error occur
+     */
+    private void assertDirectoryExist(String... subFolderNames) throws IgniteCheckedException {
+        File curFolder = new File(U.defaultWorkDirectory());
+
+        for (String name : subFolderNames) {
+            curFolder = new File(curFolder, name);
+        }
+
+        final String path;
+        try {
+            path = curFolder.getCanonicalPath();
+        }
+        catch (IOException e) {
+            throw new IgniteCheckedException("Failed to convert path: [" + curFolder.getAbsolutePath() + "]", e);
+        }
+
+        assertTrue("Directory " + Arrays.asList(subFolderNames).toString()
+            + " is expected to exist [" + path + "]", curFolder.exists() && curFolder.isDirectory());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/IgnitePersistenceCompatibilityAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/IgnitePersistenceCompatibilityAbstractTest.java b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/IgnitePersistenceCompatibilityAbstractTest.java
index d76b862..f39b6f6 100644
--- a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/IgnitePersistenceCompatibilityAbstractTest.java
+++ b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/persistence/IgnitePersistenceCompatibilityAbstractTest.java
@@ -45,6 +45,9 @@ public abstract class IgnitePersistenceCompatibilityAbstractTest extends IgniteC
     @Override protected void afterTest() throws Exception {
         super.afterTest();
 
+        //protection if test failed to finish, e.g. by error
+        stopAllGrids();
+
         assert deleteDefaultDBWorkDirectory() : "Couldn't delete DB work directory.";
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testsuites/IgniteCompatibilityBasicTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testsuites/IgniteCompatibilityBasicTestSuite.java b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testsuites/IgniteCompatibilityBasicTestSuite.java
index b54b396..351a0e7 100644
--- a/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testsuites/IgniteCompatibilityBasicTestSuite.java
+++ b/modules/compatibility/src/test/java/org/apache/ignite/compatibility/testsuites/IgniteCompatibilityBasicTestSuite.java
@@ -19,6 +19,7 @@ package org.apache.ignite.compatibility.testsuites;
 
 import junit.framework.TestSuite;
 import org.apache.ignite.compatibility.persistence.DummyPersistenceCompatibilityTest;
+import org.apache.ignite.compatibility.persistence.FoldersReuseCompatibilityTest;
 
 /**
  * Compatibility tests basic test suite.
@@ -33,6 +34,8 @@ public class IgniteCompatibilityBasicTestSuite {
 
         suite.addTestSuite(DummyPersistenceCompatibilityTest.class);
 
+        suite.addTestSuite(FoldersReuseCompatibilityTest.class);
+
         return suite;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index e1e72f7..d7b4de9 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -737,6 +737,13 @@ public final class IgniteSystemProperties {
     public static final String IGNITE_WAL_SERIALIZER_VERSION = "IGNITE_WAL_SERIALIZER_VERSION";
 
     /**
+     * When set to {@code true}, Data store folders are generated only by consistent id, and no consistent ID will be
+     * set based on existing data store folders. This option also enables compatible folder generation mode as it was
+     * before 2.3.
+     */
+    public static final String IGNITE_DATA_STORAGE_FOLDER_BY_CONSISTENT_ID = "IGNITE_DATA_STORAGE_FOLDER_BY_CONSISTENT_ID";
+
+    /**
      * Enforces singleton.
      */
     private IgniteSystemProperties() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
index 99c7cce..210b401 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
@@ -34,6 +34,7 @@ import org.apache.ignite.internal.managers.indexing.GridIndexingManager;
 import org.apache.ignite.internal.managers.loadbalancer.GridLoadBalancerManager;
 import org.apache.ignite.internal.processors.affinity.GridAffinityProcessor;
 import org.apache.ignite.internal.processors.cache.GridCacheProcessor;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsFoldersResolver;
 import org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor;
 import org.apache.ignite.internal.processors.closure.GridClosureProcessor;
 import org.apache.ignite.internal.processors.cluster.ClusterProcessor;
@@ -643,4 +644,9 @@ public interface GridKernalContext extends Iterable<GridComponent> {
      * @return Platform processor.
      */
     public PlatformProcessor platform();
+
+    /**
+     * @return PDS mode folder name resolver, also generates consistent ID in case new folder naming is used
+     */
+    public PdsFoldersResolver pdsFolderResolver();
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
index 07e5970..1f0292c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
@@ -49,6 +49,7 @@ import org.apache.ignite.internal.processors.affinity.GridAffinityProcessor;
 import org.apache.ignite.internal.processors.cache.CacheConflictResolutionManager;
 import org.apache.ignite.internal.processors.cache.GridCacheProcessor;
 import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsFoldersResolver;
 import org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor;
 import org.apache.ignite.internal.processors.closure.GridClosureProcessor;
 import org.apache.ignite.internal.processors.cluster.ClusterProcessor;
@@ -377,6 +378,9 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
     /** */
     private volatile boolean disconnected;
 
+    /** PDS mode folder name resolver, also generates consistent ID in case new folder naming is used */
+    private PdsFoldersResolver pdsFolderRslvr;
+
     /**
      * No-arg constructor is required by externalization.
      */
@@ -536,7 +540,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
         else if (comp instanceof GridCacheProcessor)
             cacheProc = (GridCacheProcessor)comp;
         else if (comp instanceof GridClusterStateProcessor)
-            stateProc =(GridClusterStateProcessor)comp;
+            stateProc = (GridClusterStateProcessor)comp;
         else if (comp instanceof GridTaskSessionProcessor)
             sesProc = (GridTaskSessionProcessor)comp;
         else if (comp instanceof GridPortProcessor)
@@ -576,9 +580,11 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
         else if (comp instanceof PlatformProcessor)
             platformProc = (PlatformProcessor)comp;
         else if (comp instanceof PoolProcessor)
-            poolProc = (PoolProcessor) comp;
+            poolProc = (PoolProcessor)comp;
         else if (comp instanceof GridMarshallerMappingProcessor)
             mappingProc = (GridMarshallerMappingProcessor)comp;
+        else if (comp instanceof PdsFoldersResolver)
+            pdsFolderRslvr = (PdsFoldersResolver)comp;
         else if (!(comp instanceof DiscoveryNodeValidationProcessor
                 || comp instanceof PlatformPluginProcessor))
             assert (comp instanceof GridPluginComponent) : "Unknown manager class: " + comp.getClass();
@@ -1005,7 +1011,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
     }
 
     /** {@inheritDoc} */
-    public Map<String, ? extends ExecutorService> customExecutors() {
+    @Override public Map<String, ? extends ExecutorService> customExecutors() {
         return customExecSvcs;
     }
 
@@ -1069,6 +1075,11 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
         this.disconnected = disconnected;
     }
 
+    /**{@inheritDoc}*/
+    @Override public PdsFoldersResolver pdsFolderResolver() {
+        return pdsFolderRslvr;
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(GridKernalContextImpl.class, this);

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index f5d736a..759bf64 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -115,6 +115,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheProxy;
 import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
 import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
 import org.apache.ignite.internal.processors.cache.persistence.MemoryPolicy;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor;
 import org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor;
 import org.apache.ignite.internal.processors.closure.GridClosureProcessor;
 import org.apache.ignite.internal.processors.cluster.ClusterProcessor;
@@ -930,13 +931,14 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
 
             // Assign discovery manager to context before other processors start so they
             // are able to register custom event listener.
-            GridManager discoMgr = new GridDiscoveryManager(ctx);
+            final GridManager discoMgr = new GridDiscoveryManager(ctx);
 
             ctx.add(discoMgr, false);
 
             // Start processors before discovery manager, so they will
             // be able to start receiving messages once discovery completes.
             try {
+                startProcessor(new PdsConsistentIdProcessor(ctx));
                 startProcessor(createComponent(DiscoveryNodeValidationProcessor.class, ctx));
                 startProcessor(new  GridAffinityProcessor(ctx));
                 startProcessor(createComponent(GridSegmentationProcessor.class, ctx));

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
index 527399d..14485d2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.managers.discovery;
 
+import java.io.Serializable;
 import java.lang.management.GarbageCollectorMXBean;
 import java.lang.management.ManagementFactory;
 import java.lang.management.MemoryMXBean;
@@ -116,6 +117,7 @@ import org.apache.ignite.spi.discovery.DiscoverySpiListener;
 import org.apache.ignite.spi.discovery.DiscoverySpiNodeAuthenticator;
 import org.apache.ignite.spi.discovery.DiscoverySpiOrderSupport;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode;
 import org.apache.ignite.thread.IgniteThread;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -281,12 +283,12 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     /** */
     private final CountDownLatch startLatch = new CountDownLatch(1);
 
-    /** */
-    private Object consistentId;
-
     /** Discovery spi registered flag. */
     private boolean registeredDiscoSpi;
 
+    /** Local node compatibility consistent ID. */
+    private Serializable consistentId;
+
     /** @param ctx Context. */
     public GridDiscoveryManager(GridKernalContext ctx) {
         super(ctx, ctx.config().getDiscoverySpi());
@@ -549,6 +551,13 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
             @Override public void onLocalNodeInitialized(ClusterNode locNode) {
                 for (IgniteInClosure<ClusterNode> lsnr : locNodeInitLsnrs)
                     lsnr.apply(locNode);
+
+                if (locNode instanceof TcpDiscoveryNode) {
+                    final TcpDiscoveryNode node = (TcpDiscoveryNode)locNode;
+
+                    if (consistentId != null)
+                        node.setConsistentId(consistentId);
+                }
             }
 
             @Override public void onDiscovery(
@@ -2017,22 +2026,42 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
 
     /**
      * @return Consistent ID.
+     * @deprecated Use PdsConsistentIdProcessor to get actual consistent ID
      */
-    public Object consistentId() {
-        if (consistentId == null) {
-            try {
-                inject();
-            }
-            catch (IgniteCheckedException e) {
-                throw new IgniteException("Failed to init consistent ID.", e);
-            }
+    @Deprecated
+    public Serializable consistentId() {
+        if (consistentId == null)
+            consistentId = getInjectedDiscoverySpi().consistentId();
+
+        return consistentId;
+    }
 
-            consistentId = getSpi().consistentId();
+    /**
+     * Performs injection of discovery SPI if needed, then provides DiscoverySpi SPI.
+     * Manual injection is required because normal startup of SPI is done after processor started.
+     *
+     * @return Wrapped DiscoverySpi SPI.
+     */
+    private DiscoverySpi getInjectedDiscoverySpi() {
+        try {
+            inject();
+        }
+        catch (IgniteCheckedException e) {
+            throw new IgniteException("Failed to init consistent ID.", e);
         }
+        return getSpi();
+    }
 
-        return consistentId;
+    /**
+     * Sets TCP local node consistent ID. This setter is to be called before node init in SPI
+     *
+     * @param consistentId New value of consistent ID to be used in local node initialization
+     */
+    public void consistentId(final Serializable consistentId) {
+        this.consistentId = consistentId;
     }
 
+
     /** @return Topology version. */
     public long topologyVersion() {
         return topSnap.get().topVer.topologyVersion();

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java
index 2d4114f..420cde5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java
@@ -34,7 +34,7 @@ import org.jetbrains.annotations.Nullable;
  * which may lead to segmentation of nodes from cluster.
  */
 class BinaryMetadataFileStore {
-    /** */
+    /** Link to resolved binary metadata directory. Null for non persistent mode */
     private File workDir;
 
     /** */
@@ -68,14 +68,14 @@ class BinaryMetadataFileStore {
         if (binaryMetadataFileStoreDir != null)
             workDir = binaryMetadataFileStoreDir;
         else {
-            String consId = U.maskForFileName(ctx.discovery().consistentId().toString());
+            final String subFolder = ctx.pdsFolderResolver().resolveFolders().folderName();
 
             workDir = new File(U.resolveWorkDirectory(
                 ctx.config().getWorkDirectory(),
                 "binary_meta",
                 false
             ),
-                consId);
+                subFolder);
         }
 
         U.ensureDirectory(workDir, "directory for serialized binary metadata", log);

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
index 9f1ccb4..2d89942 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
@@ -62,6 +62,7 @@ import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.PersistenceMetrics;
+import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.CheckpointWriteOrder;
 import org.apache.ignite.configuration.DataPageEvictionMode;
 import org.apache.ignite.configuration.IgniteConfiguration;
@@ -74,6 +75,7 @@ import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
 import org.apache.ignite.internal.NodeStoppingException;
+import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager;
 import org.apache.ignite.internal.mem.DirectMemoryProvider;
 import org.apache.ignite.internal.pagemem.FullPageId;
 import org.apache.ignite.internal.pagemem.PageIdUtils;
@@ -280,8 +282,11 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
     /** */
     private final ConcurrentMap<Integer, IgniteInternalFuture> idxRebuildFuts = new ConcurrentHashMap<>();
 
-    /** Lock holder. */
-    private FileLockHolder fileLockHolder;
+    /**
+     * Lock holder for compatible folders mode. Null if lock holder was created at start node. <br>
+     * In this case lock is held on PDS resover manager and it is not required to manage locking here
+     */
+    @Nullable private FileLockHolder fileLockHolder;
 
     /** Lock wait time. */
     private final long lockWaitTime;
@@ -367,7 +372,9 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
 
         snapshotMgr = cctx.snapshot();
 
-        if (!cctx.kernalContext().clientNode()) {
+        final GridKernalContext kernalCtx = cctx.kernalContext();
+
+        if (!kernalCtx.clientNode()) {
             IgnitePageStoreManager store = cctx.pageStore();
 
             assert store instanceof FilePageStoreManager : "Invalid page store manager was created: " + store;
@@ -379,7 +386,11 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
             if (!U.mkdirs(cpDir))
                 throw new IgniteCheckedException("Could not create directory for checkpoint metadata: " + cpDir);
 
-            fileLockHolder = new FileLockHolder(storeMgr.workDir().getPath(), cctx.kernalContext(), log);
+            final FileLockHolder preLocked = kernalCtx.pdsFolderResolver()
+                .resolveFolders()
+                .getLockedFileLockHolder();
+            if (preLocked == null)
+                fileLockHolder = new FileLockHolder(storeMgr.workDir().getPath(), kernalCtx, log);
 
             persStoreMetrics.wal(cctx.wal());
         }
@@ -488,8 +499,11 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
         /* Must be here, because after deactivate we can invoke activate and file lock must be already configured */
         stopping = false;
 
-        if (!cctx.localNode().isClient())
-            fileLockHolder = new FileLockHolder(storeMgr.workDir().getPath(), cctx.kernalContext(), log);
+        if (!cctx.localNode().isClient()) {
+            //we replace lock with new instance (only if we're responsible for locking folders)
+            if (fileLockHolder != null)
+                fileLockHolder = new FileLockHolder(storeMgr.workDir().getPath(), cctx.kernalContext(), log);
+        }
     }
 
     /**
@@ -592,20 +606,24 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
 
     /** {@inheritDoc} */
     @Override public void lock() throws IgniteCheckedException {
-        if (log.isDebugEnabled())
-            log.debug("Try to capture file lock [nodeId=" +
-                cctx.localNodeId() + " path=" + fileLockHolder.lockPath() + "]");
+        if (fileLockHolder != null) {
+            if (log.isDebugEnabled())
+                log.debug("Try to capture file lock [nodeId=" +
+                    cctx.localNodeId() + " path=" + fileLockHolder.lockPath() + "]");
 
-        fileLockHolder.tryLock(lockWaitTime);
+            fileLockHolder.tryLock(lockWaitTime);
+        }
     }
 
     /** {@inheritDoc} */
     @Override public void unLock() {
-        if (log.isDebugEnabled())
-            log.debug("Release file lock [nodeId=" +
-                cctx.localNodeId() + " path=" + fileLockHolder.lockPath() + "]");
+        if (fileLockHolder != null) {
+            if (log.isDebugEnabled())
+                log.debug("Release file lock [nodeId=" +
+                    cctx.localNodeId() + " path=" + fileLockHolder.lockPath() + "]");
 
-        fileLockHolder.release();
+            fileLockHolder.release();
+        }
     }
 
     /** {@inheritDoc} */
@@ -628,7 +646,8 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
         if (!cctx.kernalContext().clientNode()) {
             unLock();
 
-            fileLockHolder.close();
+            if (fileLockHolder != null)
+                fileLockHolder.close();
         }
 
         unRegistrateMetricsMBean();
@@ -875,7 +894,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
                             idxRebuildFuts.remove(cacheId, rebuildFut);
 
                             log().info("Finished indexes rebuilding for cache: [name=" + cacheCtx.config().getName()
-                                    + ", grpName=" + cacheCtx.config().getGroupName());
+                                + ", grpName=" + cacheCtx.config().getGroupName());
                         }
                     });
                 }
@@ -1189,7 +1208,6 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
 
     /**
      * For debugging only. TODO: remove.
-     *
      */
     public Map<T2<Integer, Integer>, T2<Long, WALPointer>> reservedForPreloading() {
         return reservedForPreloading;
@@ -2310,7 +2328,6 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
                     cpRec.addCacheGroupState(grp.groupId(), state);
                 }
 
-
                 cpPagesTuple = beginAllCheckpoints();
 
                 hasPages = hasPageForWrite(cpPagesTuple.get1());
@@ -2400,7 +2417,8 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
         }
 
         /**
-         * @return tuple with collections of FullPageIds obtained from each PageMemory and overall number of dirty pages.
+         * @return tuple with collections of FullPageIds obtained from each PageMemory and overall number of dirty
+         * pages.
          */
         private IgniteBiTuple<Collection<GridMultiCollectionWrapper<FullPageId>>, Integer> beginAllCheckpoints() {
             Collection<GridMultiCollectionWrapper<FullPageId>> res = new ArrayList(memoryPolicies().size());
@@ -2792,9 +2810,9 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
     }
 
     /**
-     * Checkpoint history. Holds chronological ordered map with {@link GridCacheDatabaseSharedManager.CheckpointEntry CheckpointEntries}.
-     * Data is loaded from corresponding checkpoint directory.
-     * This directory holds files for checkpoint start and end.
+     * Checkpoint history. Holds chronological ordered map with {@link GridCacheDatabaseSharedManager.CheckpointEntry
+     * CheckpointEntries}. Data is loaded from corresponding checkpoint directory. This directory holds files for
+     * checkpoint start and end.
      */
     @SuppressWarnings("PublicInnerClass")
     public class CheckpointHistory {
@@ -3117,7 +3135,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
     /**
      *
      */
-    private static class FileLockHolder {
+    public static class FileLockHolder implements AutoCloseable {
         /** Lock file name. */
         private static final String lockFileName = "lock";
 
@@ -3130,8 +3148,8 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
         /** Lock. */
         private FileLock lock;
 
-        /** Id. */
-        private GridKernalContext ctx;
+        /** Kernal context to generate Id of locked node in file. */
+        @NotNull private GridKernalContext ctx;
 
         /** Logger. */
         private IgniteLogger log;
@@ -3139,7 +3157,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
         /**
          * @param path Path.
          */
-        private FileLockHolder(String path, GridKernalContext ctx, IgniteLogger log) {
+        public FileLockHolder(String path, @NotNull GridKernalContext ctx, IgniteLogger log) {
             try {
                 file = Paths.get(path, lockFileName).toFile();
 
@@ -3168,7 +3186,14 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
             sb.a("[").a(ctx.localNodeId().toString()).a("]");
 
             //write ip addresses
-            sb.a(ctx.discovery().localNode().addresses());
+            final GridDiscoveryManager discovery = ctx.discovery();
+
+            if (discovery != null) { //discovery may be not up and running
+                final ClusterNode node = discovery.localNode();
+
+                if (node != null)
+                    sb.a(node.addresses());
+            }
 
             //write ports
             sb.a("[");
@@ -3264,17 +3289,13 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
             return content;
         }
 
-        /**
-         *
-         */
-        private void release() {
+        /** Releases file lock */
+        public void release() {
             U.releaseQuiet(lock);
         }
 
-        /**
-         *
-         */
-        private void close() {
+        /** Closes file channel */
+        public void close() {
             U.closeQuiet(lockFile);
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java
index 6ea6eff..d7682f0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java
@@ -50,6 +50,7 @@ import org.apache.ignite.internal.processors.cache.persistence.evict.NoOpPageEvi
 import org.apache.ignite.internal.processors.cache.persistence.evict.PageEvictionTracker;
 import org.apache.ignite.internal.processors.cache.persistence.evict.Random2LruPageEvictionTracker;
 import org.apache.ignite.internal.processors.cache.persistence.evict.RandomLruPageEvictionTracker;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsFolderSettings;
 import org.apache.ignite.internal.processors.cache.persistence.freelist.FreeList;
 import org.apache.ignite.internal.processors.cache.persistence.freelist.FreeListImpl;
 import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList;
@@ -939,17 +940,21 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
      *
      * @throws IgniteCheckedException If resolving swap directory fails.
      */
-    @Nullable protected File buildAllocPath(MemoryPolicyConfiguration plc) throws IgniteCheckedException {
+    @Nullable private File buildAllocPath(MemoryPolicyConfiguration plc) throws IgniteCheckedException {
         String path = plc.getSwapFilePath();
 
         if (path == null)
             return null;
 
-        String consId = String.valueOf(cctx.discovery().consistentId());
+        final PdsFolderSettings folderSettings = cctx.kernalContext().pdsFolderResolver().resolveFolders();
+        final String folderName;
 
-        consId = consId.replaceAll("[:,\\.]", "_");
+        if(folderSettings.isCompatible())
+            folderName = String.valueOf(folderSettings.consistentId()).replaceAll("[:,\\.]", "_");
+        else
+            folderName = folderSettings.folderName();
 
-        return buildPath(path, consId);
+        return buildPath(path, folderName);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
index a20bda1..ed82127 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
@@ -47,6 +47,7 @@ import org.apache.ignite.internal.processors.cache.CacheGroupContext;
 import org.apache.ignite.internal.processors.cache.CacheGroupDescriptor;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedManagerAdapter;
 import org.apache.ignite.internal.processors.cache.StoredCacheData;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsFolderSettings;
 import org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteCacheSnapshotManager;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.marshaller.Marshaller;
@@ -93,7 +94,7 @@ public class FilePageStoreManager extends GridCacheSharedManagerAdapter implemen
     /** */
     private PersistentStoreConfiguration pstCfg;
 
-    /** Absolute directory for file page store */
+    /** Absolute directory for file page store. Includes consistent id based folder. */
     private File storeWorkDir;
 
     /** */
@@ -117,29 +118,13 @@ public class FilePageStoreManager extends GridCacheSharedManagerAdapter implemen
 
     /** {@inheritDoc} */
     @Override public void start0() throws IgniteCheckedException {
-        if (cctx.kernalContext().clientNode())
+        final GridKernalContext ctx = cctx.kernalContext();
+        if (ctx.clientNode())
             return;
 
-        String consId = U.maskForFileName(cctx.kernalContext().discovery().consistentId().toString());
-
-        if (pstCfg.getPersistentStorePath() != null) {
-            File workDir0 = new File(pstCfg.getPersistentStorePath());
-
-            if (!workDir0.isAbsolute())
-                workDir0 = U.resolveWorkDirectory(
-                    igniteCfg.getWorkDirectory(),
-                    pstCfg.getPersistentStorePath(),
-                    false
-                );
+        final PdsFolderSettings folderSettings = ctx.pdsFolderResolver().resolveFolders();
 
-            storeWorkDir = new File(workDir0, consId);
-        }
-        else
-            storeWorkDir = new File(U.resolveWorkDirectory(
-                igniteCfg.getWorkDirectory(),
-                DFLT_STORE_DIR,
-                false
-            ), consId);
+        storeWorkDir = new File(folderSettings.persistentStoreRootPath(), folderSettings.folderName());
 
         U.ensureDirectory(storeWorkDir, "page store work directory", log);
     }
@@ -551,7 +536,7 @@ public class FilePageStoreManager extends GridCacheSharedManagerAdapter implemen
     }
 
     /**
-     * @return Store work dir.
+     * @return Store work dir. Includes consistent-id based folder
      */
     public File workDir() {
         return storeWorkDir;

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/PdsConsistentIdProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/PdsConsistentIdProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/PdsConsistentIdProcessor.java
new file mode 100644
index 0000000..c73a952
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/PdsConsistentIdProcessor.java
@@ -0,0 +1,568 @@
+/*
+ * 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.persistence.filename;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.io.Serializable;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.PersistentStoreConfiguration;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.processors.GridProcessorAdapter;
+import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.apache.ignite.internal.util.typedef.internal.SB;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_DATA_STORAGE_FOLDER_BY_CONSISTENT_ID;
+import static org.apache.ignite.IgniteSystemProperties.getBoolean;
+
+/**
+ * Component for resolving PDS storage file names, also used for generating consistent ID for case PDS mode is enabled
+ */
+public class PdsConsistentIdProcessor extends GridProcessorAdapter implements PdsFoldersResolver {
+    /** Database subfolders constant prefix. */
+    private static final String DB_FOLDER_PREFIX = "node";
+
+    /** Node index and uid separator in subfolders name. */
+    private static final String NODEIDX_UID_SEPARATOR = "-";
+
+    /** Constant node subfolder prefix and node index pattern (nodeII, where II - node index as decimal integer) */
+    private static final String NODE_PATTERN = DB_FOLDER_PREFIX + "[0-9]*" + NODEIDX_UID_SEPARATOR;
+
+    /** Uuid as string pattern. */
+    private static final String UUID_STR_PATTERN = "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}";
+
+    /**
+     * Subdir (nodeII-UID, where II - node index as decimal integer, UID - string representation of consistent ID)
+     * pattern.
+     */
+    private static final String SUBDIR_PATTERN = NODE_PATTERN + UUID_STR_PATTERN;
+
+    /** Database subfolders for new style filter. */
+    public static final FileFilter DB_SUBFOLDERS_NEW_STYLE_FILTER = new FileFilter() {
+        @Override public boolean accept(File pathname) {
+            return pathname.isDirectory() && pathname.getName().matches(SUBDIR_PATTERN);
+        }
+    };
+
+    /** Database subfolders for old style filter. */
+    private static final FileFilter DB_SUBFOLDERS_OLD_STYLE_FILTER = new FileFilter() {
+        @Override public boolean accept(File pathname) {
+            return pathname.isDirectory()
+                && !"wal".equals(pathname.getName())
+                && !pathname.getName().matches(SUBDIR_PATTERN);
+        }
+    };
+
+    /** Database default folder. */
+    public static final String DB_DEFAULT_FOLDER = "db";
+
+    /** Config. */
+    private IgniteConfiguration cfg;
+
+    /** Logger. */
+    private IgniteLogger log;
+
+    /** Context. */
+    private GridKernalContext ctx;
+
+    /** Cached folder settings. */
+    private PdsFolderSettings settings;
+
+    /**
+     * Creates folders resolver
+     *
+     * @param ctx Context.
+     */
+    public PdsConsistentIdProcessor(final GridKernalContext ctx) {
+        super(ctx);
+
+        this.cfg = ctx.config();
+        this.log = ctx.log(PdsFoldersResolver.class);
+        this.ctx = ctx;
+    }
+
+    /**
+     * Prepares compatible PDS folder settings. No locking is performed, consistent ID is not overridden.
+     *
+     * @param pstStoreBasePath DB storage base path or null if persistence is not enabled.
+     * @param consistentId compatibility consistent ID
+     * @return PDS folder settings compatible with previous versions.
+     */
+    private PdsFolderSettings compatibleResolve(
+        @Nullable final File pstStoreBasePath,
+        @NotNull final Serializable consistentId) {
+
+        if (cfg.getConsistentId() != null) {
+            // compatible mode from configuration is used fot this case, no locking, no consitent id change
+            return new PdsFolderSettings(pstStoreBasePath, cfg.getConsistentId());
+        }
+
+        return new PdsFolderSettings(pstStoreBasePath, consistentId);
+    }
+
+    /** {@inheritDoc} */
+    @Override public PdsFolderSettings resolveFolders() throws IgniteCheckedException {
+        if (settings == null) {
+            settings = prepareNewSettings();
+
+            if (!settings.isCompatible()) {
+                if (log.isInfoEnabled())
+                    log.info("Consistent ID used for local node is [" + settings.consistentId() + "] " +
+                        "according to persistence data storage folders");
+
+                ctx.discovery().consistentId(settings.consistentId());
+            }
+        }
+        return settings;
+    }
+
+    /**
+     * Creates new settings when we don't have cached one.
+     *
+     * @return new settings with prelocked directory (if appropriate).
+     * @throws IgniteCheckedException if IO failed.
+     */
+    private PdsFolderSettings prepareNewSettings() throws IgniteCheckedException {
+        final File pstStoreBasePath = resolvePersistentStoreBasePath();
+        //here deprecated method is used to get compatible version of consistentId
+        final Serializable consistentId = ctx.discovery().consistentId();
+
+        if (!cfg.isPersistentStoreEnabled())
+            return compatibleResolve(pstStoreBasePath, consistentId);
+
+        if (getBoolean(IGNITE_DATA_STORAGE_FOLDER_BY_CONSISTENT_ID, false))
+            return compatibleResolve(pstStoreBasePath, consistentId);
+
+        // compatible mode from configuration is used fot this case
+        if (cfg.getConsistentId() != null) {
+            // compatible mode from configuration is used fot this case, no locking, no consistent id change
+            return new PdsFolderSettings(pstStoreBasePath, cfg.getConsistentId());
+        }
+        // The node scans the work directory and checks if there is a folder matching the consistent ID.
+        // If such a folder exists, we start up with this ID (compatibility mode)
+        final String subFolder = U.maskForFileName(consistentId.toString());
+
+        final GridCacheDatabaseSharedManager.FileLockHolder oldStyleFolderLockHolder = tryLock(new File(pstStoreBasePath, subFolder));
+
+        if (oldStyleFolderLockHolder != null)
+            return new PdsFolderSettings(pstStoreBasePath,
+                subFolder,
+                consistentId,
+                oldStyleFolderLockHolder,
+                true);
+
+        final File[] oldStyleFolders = pstStoreBasePath.listFiles(DB_SUBFOLDERS_OLD_STYLE_FILTER);
+
+        if (oldStyleFolders != null && oldStyleFolders.length != 0) {
+            for (File folder : oldStyleFolders) {
+                final String path = getPathDisplayableInfo(folder);
+
+                U.warn(log, "There is other non-empty storage folder under storage base directory [" + path + "]");
+            }
+        }
+
+        for (FolderCandidate next : getNodeIndexSortedCandidates(pstStoreBasePath)) {
+            final GridCacheDatabaseSharedManager.FileLockHolder fileLockHolder = tryLock(next.subFolderFile());
+
+            if (fileLockHolder != null) {
+                if (log.isInfoEnabled())
+                    log.info("Successfully locked persistence storage folder [" + next.subFolderFile() + "]");
+
+                return new PdsFolderSettings(pstStoreBasePath,
+                    next.subFolderFile().getName(),
+                    next.uuid(),
+                    fileLockHolder,
+                    false);
+            }
+        }
+
+        // was not able to find free slot, allocating new
+        final GridCacheDatabaseSharedManager.FileLockHolder rootDirLock = lockRootDirectory(pstStoreBasePath);
+
+        try {
+            final List<FolderCandidate> sortedCandidates = getNodeIndexSortedCandidates(pstStoreBasePath);
+            final int nodeIdx = sortedCandidates.isEmpty() ? 0 : (sortedCandidates.get(sortedCandidates.size() - 1).nodeIndex() + 1);
+
+            return generateAndLockNewDbStorage(pstStoreBasePath, nodeIdx);
+        }
+        finally {
+            rootDirLock.release();
+            rootDirLock.close();
+        }
+    }
+
+    /**
+     * Calculate overall folder size.
+     *
+     * @param dir directory to scan.
+     * @return total size in bytes.
+     */
+    private static FolderParams folderSize(File dir) {
+        final FolderParams params = new FolderParams();
+
+        visitFolder(dir, params);
+
+        return params;
+    }
+
+    /**
+     * Scans provided directory and its sub dirs, collects found metrics.
+     *
+     * @param dir directory to start scan from.
+     * @param params input/output.
+     */
+    private static void visitFolder(final File dir, final FolderParams params) {
+        for (File file : dir.listFiles()) {
+            if (file.isDirectory())
+                visitFolder(file, params);
+            else {
+                params.size += file.length();
+                params.lastModified = Math.max(params.lastModified, dir.lastModified());
+            }
+        }
+    }
+
+    /**
+     * @param folder folder to scan.
+     * @return folder displayable information.
+     */
+    @NotNull private String getPathDisplayableInfo(final File folder) {
+        final SB res = new SB();
+
+        res.a(getCanonicalPath(folder));
+        res.a(", ");
+        final FolderParams params = folderSize(folder);
+
+        res.a(params.size);
+        res.a(" bytes, modified ");
+        final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
+
+        res.a(simpleDateFormat.format(params.lastModified));
+        res.a(" ");
+
+        return res.toString();
+    }
+
+    /**
+     * Returns the canonical pathname string of this abstract pathname.
+     *
+     * @param file path to convert.
+     * @return canonical pathname or at leas absolute if convert to canonical failed.
+     */
+    @NotNull private String getCanonicalPath(final File file) {
+        try {
+            return file.getCanonicalPath();
+        }
+        catch (IOException ignored) {
+            return file.getAbsolutePath();
+        }
+    }
+
+    /**
+     * Pad start of string with provided character.
+     *
+     * @param str sting to pad.
+     * @param minLength expected length.
+     * @param padChar padding character.
+     * @return padded string.
+     */
+    private static String padStart(String str, int minLength, char padChar) {
+        A.notNull(str, "String should not be empty");
+        if (str.length() >= minLength)
+            return str;
+
+        final SB sb = new SB(minLength);
+
+        for (int i = str.length(); i < minLength; ++i)
+            sb.a(padChar);
+
+        sb.a(str);
+
+        return sb.toString();
+
+    }
+
+    /**
+     * Creates new DB storage folder.
+     *
+     * @param pstStoreBasePath DB root path.
+     * @param nodeIdx next node index to use in folder name.
+     * @return new settings to be used in this node.
+     * @throws IgniteCheckedException if failed.
+     */
+    @NotNull private PdsFolderSettings generateAndLockNewDbStorage(final File pstStoreBasePath,
+        final int nodeIdx) throws IgniteCheckedException {
+
+        final UUID uuid = UUID.randomUUID();
+        final String consIdBasedFolder = genNewStyleSubfolderName(nodeIdx, uuid);
+        final File newRandomFolder = U.resolveWorkDirectory(pstStoreBasePath.getAbsolutePath(), consIdBasedFolder, false); //mkdir here
+        final GridCacheDatabaseSharedManager.FileLockHolder fileLockHolder = tryLock(newRandomFolder);
+
+        if (fileLockHolder != null) {
+            if (log.isInfoEnabled())
+                log.info("Successfully created new persistent storage folder [" + newRandomFolder + "]");
+
+            return new PdsFolderSettings(pstStoreBasePath, consIdBasedFolder, uuid, fileLockHolder, false);
+        }
+        throw new IgniteCheckedException("Unable to lock file generated randomly [" + newRandomFolder + "]");
+    }
+
+    /**
+     * Generates DB subfolder name for provided node index (local) and UUID (consistent ID)
+     *
+     * @param nodeIdx node index.
+     * @param uuid consistent ID.
+     * @return folder file name
+     */
+    @NotNull public static String genNewStyleSubfolderName(final int nodeIdx, final UUID uuid) {
+        final String uuidAsStr = uuid.toString();
+
+        assert uuidAsStr.matches(UUID_STR_PATTERN);
+
+        final String nodeIdxPadded = padStart(Integer.toString(nodeIdx), 2, '0');
+
+        return DB_FOLDER_PREFIX + nodeIdxPadded + NODEIDX_UID_SEPARATOR + uuidAsStr;
+    }
+
+    /**
+     * Acquires lock to root storage directory, used to lock root directory in case creating new files is required.
+     *
+     * @param pstStoreBasePath rood DB dir to lock
+     * @return locked directory, should be released and closed later
+     * @throws IgniteCheckedException if failed
+     */
+    @NotNull private GridCacheDatabaseSharedManager.FileLockHolder lockRootDirectory(File pstStoreBasePath)
+        throws IgniteCheckedException {
+
+        GridCacheDatabaseSharedManager.FileLockHolder rootDirLock;
+        int retry = 0;
+
+        while ((rootDirLock = tryLock(pstStoreBasePath)) == null) {
+            if (retry > 600)
+                throw new IgniteCheckedException("Unable to start under DB storage path [" + pstStoreBasePath + "]" +
+                    ". Lock is being held to root directory");
+            retry++;
+        }
+
+        return rootDirLock;
+    }
+
+    /**
+     * @param pstStoreBasePath root storage folder to scan.
+     * @return empty list if there is no files in folder to test. Non null value is returned for folder having
+     * applicable new style files. Collection is sorted ascending according to node ID, 0 node index is coming first.
+     */
+    @Nullable private List<FolderCandidate> getNodeIndexSortedCandidates(File pstStoreBasePath) {
+        final File[] files = pstStoreBasePath.listFiles(DB_SUBFOLDERS_NEW_STYLE_FILTER);
+
+        if (files == null)
+            return Collections.emptyList();
+
+        final List<FolderCandidate> res = new ArrayList<>();
+
+        for (File file : files) {
+            final FolderCandidate candidate = parseFileName(file);
+
+            if (candidate != null)
+                res.add(candidate);
+        }
+        Collections.sort(res, new Comparator<FolderCandidate>() {
+            @Override public int compare(FolderCandidate c1, FolderCandidate c2) {
+                return Integer.compare(c1.nodeIndex(), c2.nodeIndex());
+            }
+        });
+
+        return res;
+    }
+
+    /**
+     * Tries to lock subfolder within storage root folder.
+     *
+     * @param dbStoreDirWithSubdirectory DB store directory, is to be absolute and should include consistent ID based
+     * sub folder.
+     * @return non null holder if lock was successful, null in case lock failed. If directory does not exist method will
+     * always fail to lock.
+     */
+    private GridCacheDatabaseSharedManager.FileLockHolder tryLock(File dbStoreDirWithSubdirectory) {
+        if (!dbStoreDirWithSubdirectory.exists())
+            return null;
+
+        final String path = dbStoreDirWithSubdirectory.getAbsolutePath();
+        final GridCacheDatabaseSharedManager.FileLockHolder fileLockHolder
+            = new GridCacheDatabaseSharedManager.FileLockHolder(path, ctx, log);
+
+        try {
+            fileLockHolder.tryLock(1000);
+
+            return fileLockHolder;
+        }
+        catch (IgniteCheckedException e) {
+            U.closeQuiet(fileLockHolder);
+
+            if (log.isInfoEnabled())
+                log.info("Unable to acquire lock to file [" + path + "], reason: " + e.getMessage());
+
+            return null;
+        }
+    }
+
+    /**
+     * @return DB storage absolute root path resolved as 'db' folder in Ignite work dir (by default) or using persistent
+     * store configuration. Null if persistence is not enabled. Returned folder is created automatically.
+     * @throws IgniteCheckedException if I/O failed.
+     */
+    @Nullable private File resolvePersistentStoreBasePath() throws IgniteCheckedException {
+        final PersistentStoreConfiguration pstCfg = cfg.getPersistentStoreConfiguration();
+
+        if (pstCfg == null)
+            return null;
+
+        final String pstPath = pstCfg.getPersistentStorePath();
+
+        return U.resolveWorkDirectory(
+            cfg.getWorkDirectory(),
+            pstPath != null ? pstPath : DB_DEFAULT_FOLDER,
+            false
+        );
+
+    }
+
+    /**
+     * @param subFolderFile new style folder name to parse
+     * @return Pair of UUID and node index
+     */
+    private FolderCandidate parseFileName(@NotNull final File subFolderFile) {
+        return parseSubFolderName(subFolderFile, log);
+    }
+
+    /**
+     * @param subFolderFile new style file to parse.
+     * @param log Logger.
+     * @return Pair of UUID and node index.
+     */
+    @Nullable public static FolderCandidate parseSubFolderName(
+        @NotNull final File subFolderFile,
+        @NotNull final IgniteLogger log) {
+
+        final String fileName = subFolderFile.getName();
+        final Matcher matcher = Pattern.compile(NODE_PATTERN).matcher(fileName);
+        if (!matcher.find())
+            return null;
+
+        int uidStart = matcher.end();
+
+        try {
+            final String uid = fileName.substring(uidStart);
+            final UUID uuid = UUID.fromString(uid);
+            final String substring = fileName.substring(DB_FOLDER_PREFIX.length(), uidStart - NODEIDX_UID_SEPARATOR.length());
+            final int idx = Integer.parseInt(substring);
+
+            return new FolderCandidate(subFolderFile, idx, uuid);
+        }
+        catch (Exception e) {
+            U.warn(log, "Unable to parse new style file format from [" + subFolderFile.getAbsolutePath() + "]: " + e);
+
+            return null;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void stop(boolean cancel) throws IgniteCheckedException {
+        if (settings != null) {
+            final GridCacheDatabaseSharedManager.FileLockHolder fileLockHolder = settings.getLockedFileLockHolder();
+
+            if (fileLockHolder != null) {
+                fileLockHolder.release();
+                fileLockHolder.close();
+            }
+        }
+        super.stop(cancel);
+    }
+
+    /** Path metrics */
+    private static class FolderParams {
+        /** Overall size in bytes. */
+        private long size;
+
+        /** Last modified. */
+        private long lastModified;
+    }
+
+    /**
+     * Represents parsed new style file and encoded parameters in this file name
+     */
+    public static class FolderCandidate {
+        /** Absolute file path pointing to DB subfolder within DB storage root folder. */
+        private final File subFolderFile;
+
+        /** Node index (local, usually 0 if multiple nodes are not started at local PC). */
+        private final int nodeIdx;
+
+        /** Uuid contained in file name, is to be set as consistent ID. */
+        private final UUID uuid;
+
+        /**
+         * @param subFolderFile Absolute file path pointing to DB subfolder.
+         * @param nodeIdx Node index.
+         * @param uuid Uuid.
+         */
+        public FolderCandidate(File subFolderFile, int nodeIdx, UUID uuid) {
+            this.subFolderFile = subFolderFile;
+            this.nodeIdx = nodeIdx;
+            this.uuid = uuid;
+        }
+
+        /**
+         * @return Node index (local, usually 0 if multiple nodes are not started at local PC).
+         */
+        public int nodeIndex() {
+            return nodeIdx;
+        }
+
+        /**
+         * @return Uuid contained in file name, is to be set as consistent ID.
+         */
+        public Serializable uuid() {
+            return uuid;
+        }
+
+        /**
+         * @return Absolute file path pointing to DB subfolder within DB storage root folder.
+         */
+        public File subFolderFile() {
+            return subFolderFile;
+        }
+    }
+}
+
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/PdsFolderSettings.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/PdsFolderSettings.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/PdsFolderSettings.java
new file mode 100644
index 0000000..20fb5ca
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/PdsFolderSettings.java
@@ -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.
+ */
+
+package org.apache.ignite.internal.processors.cache.persistence.filename;
+
+import java.io.File;
+import java.io.Serializable;
+import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Class holds information required for folder generation for ignite persistent store
+ */
+public class PdsFolderSettings {
+    /**
+     * DB storage absolute root path resolved as 'db' folder in Ignite work dir (by default) or using persistent store
+     * configuration. <br>
+     * Note WAL storage may be configured outside this path.<br>
+     * This value may be null if persistence is not enabled.
+     */
+    @Nullable private final File persistentStoreRootPath;
+
+    /** Sub folder name containing consistent ID and optionally node index. */
+    private final String folderName;
+
+    /** Consistent id to be set to local node. */
+    private final Serializable consistentId;
+
+    /**
+     * File lock holder with prelocked db directory. For non compatible mode this holder contains prelocked work
+     * directory. This value is to be used at activate instead of locking. <br> May be null in case preconfigured
+     * consistent ID is used or in case lock holder was already taken by other processor.
+     */
+    @Nullable private final GridCacheDatabaseSharedManager.FileLockHolder fileLockHolder;
+
+    /**
+     * Indicates if compatible mode is enabled, in that case all sub folders are generated from consistent ID without
+     * 'node' and node index prefix. In compatible mode there is no overriding for consistent ID is done.
+     */
+    private final boolean compatible;
+
+    /**
+     * Creates settings in for new PST(DB) folder mode.
+     *
+     * @param persistentStoreRootPath Persistent store root path or null if non PDS mode.
+     * @param folderName Sub folder name containing consistent ID and optionally node index.
+     * @param consistentId Consistent id.
+     * @param fileLockHolder File lock holder with prelocked db directory.
+     * @param compatible Compatible mode flag.
+     */
+    public PdsFolderSettings(@Nullable final File persistentStoreRootPath,
+        final String folderName,
+        final Serializable consistentId,
+        @Nullable final GridCacheDatabaseSharedManager.FileLockHolder fileLockHolder,
+        final boolean compatible) {
+
+        this.consistentId = consistentId;
+        this.folderName = folderName;
+        this.fileLockHolder = fileLockHolder;
+        this.compatible = compatible;
+        this.persistentStoreRootPath = persistentStoreRootPath;
+    }
+
+    /**
+     * Creates settings for compatible mode. Folder name is consistent ID (masked), no node prefix is added.
+     *
+     * @param persistentStoreRootPath root DB path.
+     * @param consistentId node consistent ID.
+     */
+    public PdsFolderSettings(
+        @Nullable final File persistentStoreRootPath,
+        @NotNull final Serializable consistentId) {
+
+        this.consistentId = consistentId;
+        this.compatible = true;
+        this.folderName = U.maskForFileName(consistentId.toString());
+        this.persistentStoreRootPath = persistentStoreRootPath;
+        this.fileLockHolder = null;
+    }
+
+    /**
+     * @return sub folders name based on consistent ID. In compatible mode this is escaped consistent ID, in new mode
+     * this is UUID based folder name.
+     */
+    public String folderName() {
+        return folderName;
+    }
+
+    /**
+     * @return Consistent id to be set to local node.
+     */
+    public Serializable consistentId() {
+        return consistentId;
+    }
+
+    /**
+     * @return flag indicating if compatible mode is enabled for folder generation. In that case all sub folders names are
+     * generated from consistent ID without 'node' and node index prefix. In compatible mode there is no overriding for
+     * consistent ID is done for cluster node. Locking files is independent to compatibility mode.
+     */
+    public boolean isCompatible() {
+        return compatible;
+    }
+
+    /**
+     * Returns already locked file lock holder to lock file in {@link #persistentStoreRootPath}. Unlock and close this
+     * lock is not required.
+     *
+     * @return File lock holder with prelocked db directory.
+     */
+    @Nullable public GridCacheDatabaseSharedManager.FileLockHolder getLockedFileLockHolder() {
+        return fileLockHolder;
+    }
+
+    /**
+     * @return DB storage absolute root path resolved as 'db' folder in Ignite work dir (by default) or using persistent
+     * store configuration. Note WAL storage may be configured outside this path. May return null for non pds mode.
+     */
+    @Nullable public File persistentStoreRootPath() {
+        return persistentStoreRootPath;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/PdsFoldersResolver.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/PdsFoldersResolver.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/PdsFoldersResolver.java
new file mode 100644
index 0000000..cefaa04
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/PdsFoldersResolver.java
@@ -0,0 +1,33 @@
+/*
+ * 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.persistence.filename;
+
+import org.apache.ignite.IgniteCheckedException;
+
+/**
+ * Resolves folders for PDS mode, may have side effect as setting random UUID as local node consistent ID.
+ */
+public interface PdsFoldersResolver {
+    /**
+     * Prepares and caches PDS folder settings. Subsequent call to this method will provide same settings.
+     *
+     * @return PDS folder settings, consistentID and prelocked DB file lock.
+     * @throws IgniteCheckedException if failed.
+     */
+    public PdsFolderSettings resolveFolders() throws IgniteCheckedException;
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
index c8715aa..6a75dd2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
@@ -64,6 +64,7 @@ import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabase
 import org.apache.ignite.internal.processors.cache.persistence.PersistenceMetricsImpl;
 import org.apache.ignite.internal.processors.cache.persistence.file.FileIO;
 import org.apache.ignite.internal.processors.cache.persistence.file.FileIOFactory;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsFolderSettings;
 import org.apache.ignite.internal.processors.cache.persistence.wal.crc.PureJavaCrc32;
 import org.apache.ignite.internal.processors.cache.persistence.wal.record.HeaderRecord;
 import org.apache.ignite.internal.processors.cache.persistence.wal.serializer.RecordDataV1Serializer;
@@ -162,7 +163,7 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
     /** WAL archive directory (including consistent ID as subfolder) */
     private File walArchiveDir;
 
-    /** Serializer of latest version. */
+    /** Serializer of latest version, used to read header record and for write records */
     private RecordSerializer serializer;
 
     /** Serializer latest version to use. */
@@ -258,25 +259,21 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
     /** {@inheritDoc} */
     @Override public void start0() throws IgniteCheckedException {
         if (!cctx.kernalContext().clientNode()) {
-            String consId = consistentId();
-
-            A.notNullOrEmpty(consId, "consistentId");
-
-            consId = U.maskForFileName(consId);
+            final PdsFolderSettings resolveFolders = cctx.kernalContext().pdsFolderResolver().resolveFolders();
 
             checkWalConfiguration();
 
             walWorkDir = initDirectory(
                 psCfg.getWalStorePath(),
                 PersistentStoreConfiguration.DFLT_WAL_STORE_PATH,
-                consId,
+                resolveFolders.folderName(),
                 "write ahead log work directory"
             );
 
             walArchiveDir = initDirectory(
                 psCfg.getWalArchivePath(),
                 PersistentStoreConfiguration.DFLT_WAL_ARCHIVE_PATH,
-                consId,
+                resolveFolders.folderName(),
                 "write ahead log archive directory"
             );
 
@@ -317,13 +314,6 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
         }
     }
 
-    /**
-     * @return Consistent ID.
-     */
-    protected String consistentId() {
-        return cctx.discovery().consistentId().toString();
-    }
-
     /** {@inheritDoc} */
     @Override protected void stop0(boolean cancel) {
         final GridTimeoutProcessor.CancelableTask schedule = backgroundFlushSchedule;

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
index 07be8b4..e234766 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.processors.cache.persistence.wal.reader;
 
 import java.io.File;
+import java.io.Serializable;
 import java.lang.reflect.Field;
 import java.util.Iterator;
 import java.util.List;
@@ -47,6 +48,8 @@ import org.apache.ignite.internal.managers.loadbalancer.GridLoadBalancerManager;
 import org.apache.ignite.internal.processors.affinity.GridAffinityProcessor;
 import org.apache.ignite.internal.processors.cache.GridCacheProcessor;
 import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsFoldersResolver;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsFolderSettings;
 import org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor;
 import org.apache.ignite.internal.processors.closure.GridClosureProcessor;
 import org.apache.ignite.internal.processors.cluster.ClusterProcessor;
@@ -79,6 +82,7 @@ import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor;
 import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions;
 import org.apache.ignite.internal.util.IgniteExceptionRegistry;
 import org.apache.ignite.internal.util.StripedExecutor;
+import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.marshaller.Marshaller;
 import org.apache.ignite.plugin.PluginNotFoundException;
 import org.apache.ignite.plugin.PluginProvider;
@@ -106,7 +110,7 @@ public class StandaloneGridKernalContext implements GridKernalContext {
     @Nullable private IgniteCacheObjectProcessor cacheObjProcessor;
 
     /** Marshaller context implementation. */
-    private MarshallerContextImpl marshallerContext;
+    private MarshallerContextImpl marshallerCtx;
 
     /**
      * @param log Logger.
@@ -130,13 +134,13 @@ public class StandaloneGridKernalContext implements GridKernalContext {
             throw new IllegalStateException("Must not fail on empty providers list.", e);
         }
 
-        this.marshallerContext = new MarshallerContextImpl(null);
+        this.marshallerCtx = new MarshallerContextImpl(null);
         this.cfg = prepareIgniteConfiguration();
         this.cacheObjProcessor = binaryMetadataFileStoreDir != null ? binaryProcessor(this, binaryMetadataFileStoreDir) : null;
 
         if (marshallerMappingFileStoreDir != null) {
-            marshallerContext.setMarshallerMappingFileStoreDir(marshallerMappingFileStoreDir);
-            marshallerContext.onMarshallerProcessorStarted(this, null);
+            marshallerCtx.setMarshallerMappingFileStoreDir(marshallerMappingFileStoreDir);
+            marshallerCtx.onMarshallerProcessorStarted(this, null);
         }
     }
 
@@ -176,7 +180,7 @@ public class StandaloneGridKernalContext implements GridKernalContext {
         PersistentStoreConfiguration pstCfg = new PersistentStoreConfiguration();
         cfg.setPersistentStoreConfiguration(pstCfg);
 
-        marshaller.setContext(marshallerContext);
+        marshaller.setContext(marshallerCtx);
 
         return cfg;
     }
@@ -392,11 +396,7 @@ public class StandaloneGridKernalContext implements GridKernalContext {
 
     /** {@inheritDoc} */
     @Override public GridDiscoveryManager discovery() {
-        return new GridDiscoveryManager(StandaloneGridKernalContext.this) {
-            @Override public Object consistentId() {
-                return ""; // some non null value is required
-            }
-        };
+        return new GridDiscoveryManager(this);
     }
 
     /** {@inheritDoc} */
@@ -579,7 +579,7 @@ public class StandaloneGridKernalContext implements GridKernalContext {
 
     /** {@inheritDoc} */
     @Override public MarshallerContextImpl marshallerContext() {
-        return marshallerContext;
+        return marshallerCtx;
     }
 
     /** {@inheritDoc} */
@@ -598,6 +598,16 @@ public class StandaloneGridKernalContext implements GridKernalContext {
     }
 
     /** {@inheritDoc} */
+    @Override public PdsFoldersResolver pdsFolderResolver() {
+        return new PdsFoldersResolver() {
+            /** {@inheritDoc} */
+            @Override public PdsFolderSettings resolveFolders() {
+                return new PdsFolderSettings(new File("."), U.maskForFileName(""));
+            }
+        };
+    }
+
+    /** {@inheritDoc} */
     @NotNull @Override public Iterator<GridComponent> iterator() {
         return null;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
index e6eaa8e..eb8ee30 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
@@ -966,10 +966,10 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter implements DiscoverySpi {
 
             initAddresses();
 
-            Serializable cfgId = ignite.configuration().getConsistentId();
+            final Serializable cfgId = ignite.configuration().getConsistentId();
 
             if (cfgId == null) {
-                List<String> sortedAddrs = new ArrayList<>(addrs.get1());
+                final List<String> sortedAddrs = new ArrayList<>(addrs.get1());
 
                 Collections.sort(sortedAddrs);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java
index 20fb6c5..38c2a1b 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNode.java
@@ -225,6 +225,21 @@ public class TcpDiscoveryNode extends GridMetadataAwareAdapter implements Cluste
         return consistentId;
     }
 
+    /**
+     * Sets consistent globally unique node ID which survives node restarts.
+     *
+     * @param consistentId Consistent globally unique node ID.
+     */
+    public void setConsistentId(Serializable consistentId) {
+        this.consistentId = consistentId;
+
+        final Map<String, Object> map = new HashMap<>(attrs);
+
+        map.put(ATTR_NODE_CONSISTENT_ID, consistentId);
+
+        attrs = Collections.unmodifiableMap(map);
+    }
+
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
     @Override public <T> T attribute(String name) {


[09/50] [abbrv] ignite git commit: IGNITE-5915 - Added warning for WAL NONE mode

Posted by ag...@apache.org.
IGNITE-5915 - Added warning for WAL NONE mode


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

Branch: refs/heads/ignite-6305
Commit: f57b6776775308753a1fa579c0e7599df241be61
Parents: 252eedc
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Mon Oct 2 15:05:42 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Mon Oct 2 15:06:12 2017 +0300

----------------------------------------------------------------------
 .../java/org/apache/ignite/configuration/WALMode.java | 14 ++++++++++----
 .../persistence/wal/FileWriteAheadLogManager.java     |  5 ++++-
 2 files changed, 14 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/f57b6776/modules/core/src/main/java/org/apache/ignite/configuration/WALMode.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/WALMode.java b/modules/core/src/main/java/org/apache/ignite/configuration/WALMode.java
index 9d4520e..bea0cba 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/WALMode.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/WALMode.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.configuration;
 
+import org.apache.ignite.Ignite;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -24,22 +25,27 @@ import org.jetbrains.annotations.Nullable;
  */
 public enum WALMode {
     /**
-     * Default mode: full-sync disk writes. These writes survive power loss scenarios.
+     * Default mode: full-sync disk writes. These writes survive power loss scenarios. When a control is returned
+     * from the trnasaction commit operation, the changes are guaranteed to be forced on disk according to the
+     * transaction write synchronization mode.
      */
     DEFAULT,
 
     /**
-     * Log only mode: flushes application buffers. These writes survive process crash.
+     * Log only mode: flushes application buffers. These writes survive process crash. When a control is returned
+     * from the transaction commit operation, the changes are guaranteed to be forced to the OS buffer cache.
      */
     LOG_ONLY,
 
     /**
-     * Background mode. Does not force application buffer flush. Data may be lost in case of process crash.
+     * Background mode. Does not force application buffer flush. Last updates may be lost in case of a process crash.
      */
     BACKGROUND,
 
     /**
-     * WAL disabled.
+     * WAL is disabled. Data is guaranteed to be persisted on disk only in case of graceful cluster shutdown using
+     * {@link Ignite#active(boolean)} method. If an Ignite node is forefully terminated in NONE mode, it is likely
+     * that data stored on disk is corrupted and work directory will need to be cleared for a successfull node restart.
      */
     NONE;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f57b6776/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
index 76edcea..c8715aa 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
@@ -294,10 +294,13 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
 
             archiver = new FileArchiver(tup == null ? -1 : tup.get2());
 
-            if (mode != WALMode.DEFAULT) {
+            if (mode != WALMode.NONE) {
                 if (log.isInfoEnabled())
                     log.info("Started write-ahead log manager [mode=" + mode + ']');
             }
+            else
+                U.quietAndWarn(log, "Started write-ahead log manager in NONE mode, persisted data may be lost in " +
+                    "a case of unexpected node failure. Make sure to deactivate the cluster before shutdown.");
         }
     }
 


[33/50] [abbrv] ignite git commit: IGNITE-5739 Fixed Ignite node crash on deactivation

Posted by ag...@apache.org.
IGNITE-5739 Fixed Ignite node crash on deactivation


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

Branch: refs/heads/ignite-6305
Commit: 3b1cad2156e6230760fface6c7cd00d3f3526255
Parents: 3c355e9
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Thu Oct 5 17:37:04 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Oct 5 17:37:04 2017 +0300

----------------------------------------------------------------------
 .../GridCacheDatabaseSharedManager.java           |  2 ++
 .../cache/persistence/pagemem/PageMemoryImpl.java | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/3b1cad21/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
index 33f065e..9a2e028 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
@@ -540,6 +540,8 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
 
         try {
             cctx.kernalContext().config().getMBeanServer().unregisterMBean(persistenceMetricsMbeanName);
+
+            persistenceMetricsMbeanName = null;
         }
         catch (Throwable e) {
             U.error(log, "Failed to unregister " + MBEAN_NAME + " MBean.", e);

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b1cad21/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java
index 1da17b5..95b81ad 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java
@@ -237,6 +237,9 @@ public class PageMemoryImpl implements PageMemoryEx {
     /** */
     private MemoryMetricsImpl memMetrics;
 
+    /** */
+    private volatile boolean closed;
+
     /**
      * @param directMemoryProvider Memory allocator to use.
      * @param sharedCtx Cache shared context.
@@ -358,6 +361,15 @@ public class PageMemoryImpl implements PageMemoryEx {
 
         U.shutdownNow(getClass(), asyncRunner, log);
 
+        closed = true;
+
+        for (Segment seg : segments) {
+            // Make sure all threads have left the lock.
+            seg.writeLock().lock();
+
+            seg.writeLock().unlock();
+        }
+
         directMemoryProvider.shutdown();
     }
 
@@ -1093,6 +1105,9 @@ public class PageMemoryImpl implements PageMemoryEx {
                 seg.readLock().lock();
 
                 try {
+                    if (closed)
+                        continue;
+
                     total += seg.loadedPages.size();
                 }
                 finally {
@@ -1114,6 +1129,9 @@ public class PageMemoryImpl implements PageMemoryEx {
             seg.readLock().lock();
 
             try {
+                if (closed)
+                    continue;
+
                 total += seg.acquiredPages();
             }
             finally {


[08/50] [abbrv] ignite git commit: ignite-5733 Add ability to activate/deactivate/checkstate through HTTP REST API

Posted by ag...@apache.org.
ignite-5733 Add ability to activate/deactivate/checkstate through HTTP REST API

Signed-off-by: Andrey Gura <ag...@apache.org>


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

Branch: refs/heads/ignite-6305
Commit: 252eedcccf33c81f1a4007627eb1a29b48b72f7f
Parents: d7fbbd5
Author: Alexander Belyak <al...@xored.com>
Authored: Mon Oct 2 12:58:18 2017 +0300
Committer: Andrey Gura <ag...@apache.org>
Committed: Mon Oct 2 12:58:18 2017 +0300

----------------------------------------------------------------------
 .../JettyRestProcessorAbstractSelfTest.java     | 46 ++++++++++++++++++++
 .../processors/rest/GridRestCommand.java        |  2 +-
 .../processors/rest/GridRestProcessor.java      |  5 ++-
 .../http/jetty/GridJettyRestHandler.java        | 18 ++++++++
 4 files changed, 68 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/252eedcc/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 5f83f6f..b2725b8 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
@@ -710,6 +710,18 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     /**
      * @throws Exception If failed.
      */
+    public void testDeactivateActivate() throws Exception {
+
+        assertClusterState(true);
+
+        changeClusterState(false);
+
+        changeClusterState(true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testPut() throws Exception {
         String ret = content(F.asMap("cacheName", DEFAULT_CACHE_NAME, "cmd", GridRestCommand.CACHE_PUT.key(),
             "key", "putKey", "val", "putVal"));
@@ -2375,4 +2387,38 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         return cfg;
     }
+
+    /**
+     * Test if current cluster state equals expected.
+     *
+     * @param exp Expected state.
+     * @throws Exception If failed.
+     */
+    private void assertClusterState(boolean exp) throws Exception {
+        String ret = content(F.asMap("cmd", GridRestCommand.CLUSTER_CURRENT_STATE.key()));
+
+        info("Cluster state: " + ret);
+        JsonNode res = jsonResponse(ret);
+
+        assertEquals(exp, res.asBoolean());
+        assertEquals(exp, grid(0).active());
+    }
+
+    /**
+     * Change cluster state and test new state.
+     *
+     * @param state Desired state.
+     * @throws Exception If failed.
+     */
+    private void changeClusterState(boolean state) throws Exception {
+        String cmd = (state ? GridRestCommand.CLUSTER_ACTIVE : GridRestCommand.CLUSTER_INACTIVE).key();
+
+        String ret = content(F.asMap("cmd", cmd));
+
+        JsonNode res = jsonResponse(ret);
+
+        assertTrue(res.isNull());
+
+        assertClusterState(state);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/252eedcc/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
index 24b4bda..2b53b54 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
@@ -166,7 +166,7 @@ public enum GridRestCommand {
     CLUSTER_INACTIVE("inactive"),
 
     /** */
-    CLUSTER_CURRENT_STATE("currentState");
+    CLUSTER_CURRENT_STATE("currentstate");
 
     /** Enum values. */
     private static final GridRestCommand[] VALS = values();

http://git-wip-us.apache.org/repos/asf/ignite/blob/252eedcc/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
index 9842883..64ab173 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
@@ -67,8 +67,6 @@ import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.internal.util.worker.GridWorker;
 import org.apache.ignite.internal.util.worker.GridWorkerFuture;
-import org.apache.ignite.internal.visor.compute.VisorGatewayTask;
-import org.apache.ignite.internal.visor.misc.VisorChangeGridActiveStateTask;
 import org.apache.ignite.internal.visor.util.VisorClusterGroupEmptyException;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgniteInClosure;
@@ -811,6 +809,9 @@ public class GridRestProcessor extends GridProcessorAdapter {
             case ATOMIC_DECREMENT:
             case NAME:
             case LOG:
+            case CLUSTER_CURRENT_STATE:
+            case CLUSTER_ACTIVE:
+            case CLUSTER_INACTIVE:
                 break;
 
             default:

http://git-wip-us.apache.org/repos/asf/ignite/blob/252eedcc/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 327c13a..b8a42f3 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
@@ -45,6 +45,7 @@ import org.apache.ignite.internal.processors.rest.GridRestProtocolHandler;
 import org.apache.ignite.internal.processors.rest.GridRestResponse;
 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.GridRestChangeStateRequest;
 import org.apache.ignite.internal.processors.rest.request.GridRestLogRequest;
 import org.apache.ignite.internal.processors.rest.request.GridRestRequest;
 import org.apache.ignite.internal.processors.rest.request.GridRestTaskRequest;
@@ -63,6 +64,8 @@ import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_G
 import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_PUT_ALL;
 import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_REMOVE_ALL;
 import static org.apache.ignite.internal.processors.rest.GridRestCommand.EXECUTE_SQL_QUERY;
+import static org.apache.ignite.internal.processors.rest.GridRestCommand.CLUSTER_ACTIVE;
+import static org.apache.ignite.internal.processors.rest.GridRestCommand.CLUSTER_CURRENT_STATE;
 import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_FAILED;
 
 /**
@@ -540,6 +543,21 @@ public class GridJettyRestHandler extends AbstractHandler {
                 break;
             }
 
+            case CLUSTER_ACTIVE:
+            case CLUSTER_INACTIVE:
+            case CLUSTER_CURRENT_STATE: {
+                GridRestChangeStateRequest restReq0 = new GridRestChangeStateRequest();
+
+                if (cmd == CLUSTER_CURRENT_STATE)
+                    restReq0.reqCurrentState();
+                else
+                    restReq0.active(cmd == CLUSTER_ACTIVE);
+
+                restReq = restReq0;
+
+                break;
+            }
+
             case EXECUTE_SQL_QUERY:
             case EXECUTE_SQL_FIELDS_QUERY: {
                 RestQueryRequest restReq0 = new RestQueryRequest();


[16/50] [abbrv] ignite git commit: IGNITE-6382 .NET: Set up NDepend project

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/b21f750f/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 4ee4310..b133b1e 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -882,6 +882,7 @@
                                         <exclude>**/*.FxCop</exclude>
                                         <exclude>**/*.ruleset</exclude>
                                         <exclude>**/*.csproj</exclude>
+                                        <exclude>**/*.ndproj</exclude>
                                         <exclude>**/*.csprojrel</exclude>
                                         <exclude>**/*.vcxproj</exclude>
                                         <exclude>**/*.vcxprojrel</exclude>


[21/50] [abbrv] ignite git commit: IGNITE-6285 Enhance persistent store paths handling - Fixes #2775.

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/filename/IgniteUidAsConsistentIdMigrationTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/filename/IgniteUidAsConsistentIdMigrationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/filename/IgniteUidAsConsistentIdMigrationTest.java
new file mode 100644
index 0000000..fe7e4df
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/filename/IgniteUidAsConsistentIdMigrationTest.java
@@ -0,0 +1,712 @@
+/*
+ * 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.persistence.db.filename;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.UUID;
+import java.util.regex.Pattern;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.MemoryConfiguration;
+import org.apache.ignite.configuration.MemoryPolicyConfiguration;
+import org.apache.ignite.configuration.PersistentStoreConfiguration;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.testframework.GridStringLogger;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.jetbrains.annotations.NotNull;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_CONSISTENT_ID_BY_HOST_WITHOUT_PORT;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_DATA_STORAGE_FOLDER_BY_CONSISTENT_ID;
+import static org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor.parseSubFolderName;
+
+/**
+ * Test for new and old style persistent storage folders generation
+ */
+public class IgniteUidAsConsistentIdMigrationTest extends GridCommonAbstractTest {
+    /** Cache name for test. */
+    public static final String CACHE_NAME = "dummy";
+
+    /** Clear DB folder after each test. May be set to false for local debug */
+    private static final boolean deleteAfter = true;
+
+    /** Clear DB folder before each test. */
+    private static final boolean deleteBefore = true;
+
+    /** Fail test if delete of DB folder was not completed. */
+    private static final boolean failIfDeleteNotCompleted = true;
+
+    /** Configured consistent id. */
+    private String configuredConsistentId;
+
+    /** Logger to accumulate messages, null will cause logger won't be customized */
+    private GridStringLogger strLog;
+
+    /** Clear properties after this test run. Flag protects from failed test */
+    private boolean clearPropsAfterTest = false;
+
+    /** Place storage in temp folder for current test run. */
+    private boolean placeStorageInTemp;
+
+    /** A path to persistent store custom path for current test run. */
+    private File pstStoreCustomPath;
+
+    /** A path to persistent store WAL work custom path. */
+    private File pstWalStoreCustomPath;
+
+    /** A path to persistent store WAL archive custom path. */
+    private File pstWalArchCustomPath;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        stopAllGrids();
+
+        if (deleteBefore)
+            deleteWorkFiles();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        if (deleteAfter)
+            deleteWorkFiles();
+
+        if (clearPropsAfterTest) {
+            System.clearProperty(IGNITE_DATA_STORAGE_FOLDER_BY_CONSISTENT_ID);
+            System.clearProperty(IGNITE_CONSISTENT_ID_BY_HOST_WITHOUT_PORT);
+        }
+    }
+
+    /**
+     * @throws IgniteCheckedException If failed.
+     */
+    private void deleteWorkFiles() throws IgniteCheckedException {
+        boolean ok = true;
+
+        if (pstStoreCustomPath != null)
+            ok &= deleteRecursively(pstStoreCustomPath);
+        else
+            ok &= deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", false));
+
+        if (pstWalArchCustomPath != null)
+            ok &= deleteRecursively(pstWalArchCustomPath);
+
+        if (pstWalStoreCustomPath != null)
+            ok &= deleteRecursively(pstWalStoreCustomPath);
+
+        ok &= deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), "binary_meta", false));
+
+        if (failIfDeleteNotCompleted)
+            assertTrue(ok);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        final IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        if (configuredConsistentId != null)
+            cfg.setConsistentId(configuredConsistentId);
+
+        final PersistentStoreConfiguration psCfg = new PersistentStoreConfiguration();
+
+        if (placeStorageInTemp) {
+            final File tempDir = new File(System.getProperty("java.io.tmpdir"));
+
+            pstStoreCustomPath = new File(tempDir, "Store");
+            pstWalStoreCustomPath = new File(tempDir, "WalStore");
+            pstWalArchCustomPath = new File(tempDir, "WalArchive");
+
+            psCfg.setPersistentStorePath(pstStoreCustomPath.getAbsolutePath());
+            psCfg.setWalStorePath(pstWalStoreCustomPath.getAbsolutePath());
+            psCfg.setWalArchivePath(pstWalArchCustomPath.getAbsolutePath());
+        }
+
+        cfg.setPersistentStoreConfiguration(psCfg);
+
+        final MemoryConfiguration memCfg = new MemoryConfiguration();
+        final MemoryPolicyConfiguration memPolCfg = new MemoryPolicyConfiguration();
+
+        memPolCfg.setMaxSize(32 * 1024 * 1024); // we don't need much memory for this test
+        memCfg.setMemoryPolicies(memPolCfg);
+        cfg.setMemoryConfiguration(memCfg);
+
+        if (strLog != null)
+            cfg.setGridLogger(strLog);
+
+        return cfg;
+    }
+
+    /**
+     * Checks start on empty PDS folder, in that case node 0 should start with random UUID.
+     *
+     * @throws Exception if failed.
+     */
+    public void testNewStyleIdIsGenerated() throws Exception {
+        final Ignite ignite = startActivateFillDataGrid(0);
+
+        //test UUID is parsable from consistent ID test
+        UUID.fromString(ignite.cluster().localNode().consistentId().toString());
+        assertPdsDirsDefaultExist(genNewStyleSubfolderName(0, ignite));
+        stopGrid(0);
+    }
+
+    /**
+     * Checks start on empty PDS folder, in that case node 0 should start with random UUID.
+     *
+     * @throws Exception if failed.
+     */
+    public void testNewStyleIdIsGeneratedInCustomStorePath() throws Exception {
+        placeStorageInTemp = true;
+        final Ignite ignite = startActivateFillDataGrid(0);
+
+        //test UUID is parsable from consistent ID test
+        UUID.fromString(ignite.cluster().localNode().consistentId().toString());
+        final String subfolderName = genNewStyleSubfolderName(0, ignite);
+
+        assertDirectoryExist("binary_meta", subfolderName);
+
+        assertDirectoryExist(pstWalArchCustomPath, subfolderName);
+        assertDirectoryExist(pstWalArchCustomPath, subfolderName);
+        assertDirectoryExist(pstStoreCustomPath, subfolderName);
+
+        stopGrid(0);
+    }
+
+    /**
+     * Checks start on empty PDS folder using configured ConsistentId. We should start using this ID in compatible mode.
+     *
+     * @throws Exception if failed.
+     */
+    public void testPreconfiguredConsitentIdIsApplied() throws Exception {
+        this.configuredConsistentId = "someConfiguredConsistentId";
+        Ignite ignite = startActivateFillDataGrid(0);
+
+        assertPdsDirsDefaultExist(configuredConsistentId);
+        stopGrid(0);
+    }
+
+    /**
+     * Checks start on configured ConsistentId with same value as default, this emulate old style folder is already
+     * available. We should restart using this folder.
+     *
+     * @throws Exception if failed
+     */
+    public void testRestartOnExistingOldStyleId() throws Exception {
+        final String expDfltConsistentId = "127.0.0.1:47500";
+
+        this.configuredConsistentId = expDfltConsistentId; //this is for create old node folder
+
+        final Ignite igniteEx = startActivateGrid(0);
+
+        final String expVal = "there is compatible mode with old style folders!";
+
+        igniteEx.getOrCreateCache(CACHE_NAME).put("hi", expVal);
+
+        assertPdsDirsDefaultExist(U.maskForFileName(configuredConsistentId));
+        stopGrid(0);
+
+        this.configuredConsistentId = null; //now set up grid on existing folder
+
+        final Ignite igniteRestart = startActivateGrid(0);
+
+        assertEquals(expDfltConsistentId, igniteRestart.cluster().localNode().consistentId());
+        final IgniteCache<Object, Object> cache = igniteRestart.cache(CACHE_NAME);
+
+        assertNotNull("Expected to have cache [" + CACHE_NAME + "] using [" + expDfltConsistentId + "] as PDS folder", cache);
+        final Object valFromCache = cache.get("hi");
+
+        assertNotNull("Expected to load data from cache using [" + expDfltConsistentId + "] as PDS folder", valFromCache);
+        assertTrue(expVal.equals(valFromCache));
+        stopGrid(0);
+    }
+
+    /**
+     * Start stop grid without activation should cause lock to be released and restarted node should have index 0
+     *
+     * @throws Exception if failed
+     */
+    public void testStartWithoutActivate() throws Exception {
+        //start stop grid without activate
+        startGrid(0);
+        stopGrid(0);
+
+        Ignite igniteRestart = startActivateFillDataGrid(0);
+        assertPdsDirsDefaultExist(genNewStyleSubfolderName(0, igniteRestart));
+        stopGrid(0);
+    }
+
+    /**
+     * Checks start on empty PDS folder, in that case node 0 should start with random UUID
+     *
+     * @throws Exception if failed
+     */
+    public void testRestartOnSameFolderWillCauseSameUuidGeneration() throws Exception {
+        final UUID uuid;
+        {
+            final Ignite ignite = startActivateFillDataGrid(0);
+
+            assertPdsDirsDefaultExist(genNewStyleSubfolderName(0, ignite));
+
+            uuid = (UUID)ignite.cluster().localNode().consistentId();
+            stopGrid(0);
+        }
+
+        {
+            final Ignite igniteRestart = startActivateGrid(0);
+
+            assertTrue("there!".equals(igniteRestart.cache(CACHE_NAME).get("hi")));
+
+            final Object consIdRestart = igniteRestart.cluster().localNode().consistentId();
+
+            assertPdsDirsDefaultExist(genNewStyleSubfolderName(0, igniteRestart));
+            stopGrid(0);
+
+            assertEquals(uuid, consIdRestart);
+        }
+    }
+
+    /**
+     * This test starts node, activates, deactivates node, and then start second node.
+     * Expected behaviour is following: second node will join topology with separate node folder
+     *
+     * @throws Exception if failed
+     */
+    public void testStartNodeAfterDeactivate() throws Exception {
+        final UUID uuid;
+        {
+            final Ignite ignite = startActivateFillDataGrid(0);
+
+            assertPdsDirsDefaultExist(genNewStyleSubfolderName(0, ignite));
+
+            uuid = (UUID)ignite.cluster().localNode().consistentId();
+            ignite.active(false);
+        }
+        {
+            final Ignite igniteRestart = startActivateGrid(1);
+
+            grid(0).active(true);
+            final Object consIdRestart = igniteRestart.cluster().localNode().consistentId();
+
+            assertPdsDirsDefaultExist(genNewStyleSubfolderName(1, igniteRestart));
+
+            stopGrid(1);
+            assertFalse(consIdRestart.equals(uuid));
+        }
+        stopGrid(0);
+        assertNodeIndexesInFolder(0, 1);
+    }
+
+    /**
+     * @param idx Index of the grid to start.
+     * @return Started and activated grid.
+     * @throws Exception If failed.
+     */
+    @NotNull private Ignite startActivateFillDataGrid(int idx) throws Exception {
+        final Ignite ignite = startActivateGrid(idx);
+
+        ignite.getOrCreateCache(CACHE_NAME).put("hi", "there!");
+
+        return ignite;
+    }
+
+    /**
+     * Starts and activates new grid with given index.
+     *
+     * @param idx Index of the grid to start.
+     * @return Started and activated grid.
+     * @throws Exception If anything failed.
+     */
+    @NotNull private Ignite startActivateGrid(int idx) throws Exception {
+        final Ignite ignite = startGrid(idx);
+
+        ignite.active(true);
+
+        return ignite;
+    }
+
+    /**
+     * Generates folder name in new style using constant prefix and UUID
+     *
+     * @param nodeIdx expected node index to check
+     * @param ignite ignite instance
+     * @return name of storage related subfolders
+     */
+    @NotNull private String genNewStyleSubfolderName(final int nodeIdx, final Ignite ignite) {
+        final Object consistentId = ignite.cluster().localNode().consistentId();
+
+        assertTrue("For new style folders consistent ID should be UUID," +
+                " but actual class is " + (consistentId == null ? null : consistentId.getClass()),
+            consistentId instanceof UUID);
+
+        return PdsConsistentIdProcessor.genNewStyleSubfolderName(nodeIdx, (UUID)consistentId);
+    }
+
+    /**
+     * test two nodes started at the same db root folder, second node should get index 1
+     *
+     * @throws Exception if failed
+     */
+    public void testNodeIndexIncremented() throws Exception {
+        final Ignite ignite0 = startGrid(0);
+        final Ignite ignite1 = startGrid(1);
+
+        ignite0.active(true);
+
+        ignite0.getOrCreateCache(CACHE_NAME).put("hi", "there!");
+        ignite1.getOrCreateCache(CACHE_NAME).put("hi1", "there!");
+
+        assertPdsDirsDefaultExist(genNewStyleSubfolderName(0, ignite0));
+        assertPdsDirsDefaultExist(genNewStyleSubfolderName(1, ignite1));
+
+        stopGrid(0);
+        stopGrid(1);
+        assertNodeIndexesInFolder(0, 1);
+    }
+
+    /**
+     * Test verified that new style folder is taken always with lowest index
+     *
+     * @throws Exception if failed
+     */
+    public void testNewStyleAlwaysSmallestNodeIndexIsCreated() throws Exception {
+        final Ignite ignite0 = startGrid(0);
+        final Ignite ignite1 = startGrid(1);
+        final Ignite ignite2 = startGrid(2);
+        final Ignite ignite3 = startGrid(3);
+
+        ignite0.active(true);
+
+        ignite0.getOrCreateCache(CACHE_NAME).put("hi", "there!");
+        ignite3.getOrCreateCache(CACHE_NAME).put("hi1", "there!");
+
+        assertPdsDirsDefaultExist(genNewStyleSubfolderName(0, ignite0));
+        assertPdsDirsDefaultExist(genNewStyleSubfolderName(1, ignite1));
+        assertPdsDirsDefaultExist(genNewStyleSubfolderName(2, ignite2));
+        assertPdsDirsDefaultExist(genNewStyleSubfolderName(3, ignite3));
+
+        assertNodeIndexesInFolder(0, 1, 2, 3);
+        stopAllGrids();
+
+        //this grid should take folder with index 0 as unlocked
+        final Ignite ignite4Restart = startActivateGrid(3);
+        assertPdsDirsDefaultExist(genNewStyleSubfolderName(0, ignite4Restart));
+
+        assertNodeIndexesInFolder(0, 1, 2, 3);
+        stopAllGrids();
+    }
+
+    /**
+     * Test verified that new style folder is taken always with lowest index
+     *
+     * @throws Exception if failed
+     */
+    public void testNewStyleAlwaysSmallestNodeIndexIsCreatedMultithreaded() throws Exception {
+        final Ignite ignite0 = startGridsMultiThreaded(11);
+
+        ignite0.active(true);
+
+        ignite0.getOrCreateCache(CACHE_NAME).put("hi", "there!");
+        ignite0.getOrCreateCache(CACHE_NAME).put("hi1", "there!");
+
+        assertPdsDirsDefaultExist(genNewStyleSubfolderName(0, ignite0));
+
+        assertNodeIndexesInFolder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+        stopAllGrids();
+
+        //this grid should take folder with index 0 as unlocked
+        final Ignite ignite4Restart = startActivateGrid(4);
+        assertPdsDirsDefaultExist(genNewStyleSubfolderName(0, ignite4Restart));
+        stopAllGrids();
+
+        assertNodeIndexesInFolder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+    }
+
+    /**
+     * Test start two nodes with predefined conistent ID (emulate old fashion node). Then restart two nodes. Expected
+     * both nodes will get its own old folders
+     *
+     * @throws Exception if failed.
+     */
+    public void testStartTwoOldStyleNodes() throws Exception {
+        final String expDfltConsistentId1 = "127.0.0.1:47500";
+
+        this.configuredConsistentId = expDfltConsistentId1; //this is for create old node folder
+        final Ignite ignite = startGrid(0);
+
+        final String expDfltConsistentId2 = "127.0.0.1:47501";
+
+        this.configuredConsistentId = expDfltConsistentId2; //this is for create old node folder
+        final Ignite ignite2 = startGrid(1);
+
+        ignite.active(true);
+
+        final String expVal = "there is compatible mode with old style folders!";
+
+        ignite2.getOrCreateCache(CACHE_NAME).put("hi", expVal);
+
+        assertPdsDirsDefaultExist(U.maskForFileName(expDfltConsistentId1));
+        assertPdsDirsDefaultExist(U.maskForFileName(expDfltConsistentId2));
+        stopAllGrids();
+
+        this.configuredConsistentId = null; //now set up grid on existing folder
+
+        final Ignite igniteRestart = startGrid(0);
+        final Ignite igniteRestart2 = startGrid(1);
+
+        igniteRestart2.active(true);
+
+        assertEquals(expDfltConsistentId1, igniteRestart.cluster().localNode().consistentId());
+        assertEquals(expDfltConsistentId2, igniteRestart2.cluster().localNode().consistentId());
+
+        final IgniteCache<Object, Object> cache = igniteRestart.cache(CACHE_NAME);
+
+        assertNotNull("Expected to have cache [" + CACHE_NAME + "] using [" + expDfltConsistentId1 + "] as PDS folder", cache);
+        final Object valFromCache = cache.get("hi");
+
+        assertNotNull("Expected to load data from cache using [" + expDfltConsistentId1 + "] as PDS folder", valFromCache);
+        assertTrue(expVal.equals(valFromCache));
+
+        assertNodeIndexesInFolder(); //no new style nodes should be found
+        stopGrid(0);
+    }
+
+    /**
+     * Tests compatible mode enabled by this test to start.
+     * Expected to be 2 folders and no new style folders in this case.
+     *
+     * @throws Exception if failed.
+     */
+    public void testStartOldStyleNodesByCompatibleProperty() throws Exception {
+        clearPropsAfterTest = true;
+        System.setProperty(IGNITE_DATA_STORAGE_FOLDER_BY_CONSISTENT_ID, "true");
+
+        final Ignite ignite1 = startGrid(0);
+        final Ignite ignite2 = startGrid(1);
+
+        ignite1.active(true);
+
+        final String expVal = "there is compatible mode with old style folders!";
+
+        ignite2.getOrCreateCache(CACHE_NAME).put("hi", expVal);
+
+        assertNodeIndexesInFolder(); // expected to have no new style folders
+
+        final Object consistentId1 = ignite1.cluster().localNode().consistentId();
+
+        assertPdsDirsDefaultExist(U.maskForFileName(consistentId1.toString()));
+        final Object consistentId2 = ignite2.cluster().localNode().consistentId();
+
+        assertPdsDirsDefaultExist(U.maskForFileName(consistentId2.toString()));
+        stopAllGrids();
+
+        System.clearProperty(IGNITE_DATA_STORAGE_FOLDER_BY_CONSISTENT_ID);
+        final Ignite igniteRestart = startGrid(0);
+        final Ignite igniteRestart2 = startGrid(1);
+
+        igniteRestart2.active(true);
+
+        assertEquals(consistentId1, igniteRestart.cluster().localNode().consistentId());
+        assertEquals(consistentId2, igniteRestart2.cluster().localNode().consistentId());
+
+        assertNodeIndexesInFolder(); //new style nodes should not be found
+        stopGrid(0);
+    }
+
+    /**
+     * Tests compatible mode enabled by this test to start, also no port is enabled.
+     * Expected to be 1 folder and no new style folders in this case.
+     *
+     * @throws Exception if failed.
+     */
+    public void testStartOldStyleNoPortsNodesByCompatibleProperty() throws Exception {
+        clearPropsAfterTest = true;
+        System.setProperty(IGNITE_DATA_STORAGE_FOLDER_BY_CONSISTENT_ID, "true");
+        System.setProperty(IGNITE_CONSISTENT_ID_BY_HOST_WITHOUT_PORT, "true");
+
+        final Ignite ignite1 = startGrid(0);
+
+        ignite1.active(true);
+
+        final String expVal = "there is compatible mode with old style folders!";
+
+        ignite1.getOrCreateCache(CACHE_NAME).put("hi", expVal);
+
+        assertNodeIndexesInFolder(); // expected to have no new style folders
+
+        final Object consistentId1 = ignite1.cluster().localNode().consistentId();
+
+        assertPdsDirsDefaultExist(U.maskForFileName(consistentId1.toString()));
+        stopAllGrids();
+
+        System.clearProperty(IGNITE_DATA_STORAGE_FOLDER_BY_CONSISTENT_ID);
+
+        final Ignite igniteRestart = startGrid(0);
+
+        igniteRestart.active(true);
+
+        assertEquals(consistentId1, igniteRestart.cluster().localNode().consistentId());
+
+        assertNodeIndexesInFolder(); //new style nodes should not be found
+        stopGrid(0);
+        System.clearProperty(IGNITE_CONSISTENT_ID_BY_HOST_WITHOUT_PORT);
+    }
+
+    /**
+     * Test case If there are no matching folders,
+     * but the directory contains old-style consistent IDs.
+     * Ignite should print out a warning.
+     *
+     * @throws Exception if failed.
+     */
+    public void testOldStyleNodeWithUnexpectedPort() throws Exception {
+        this.configuredConsistentId = "127.0.0.1:49999"; //emulated old-style node with not appropriate consistent ID
+        final Ignite ignite = startActivateFillDataGrid(0);
+        final IgniteCache<Object, Object> second = ignite.getOrCreateCache("second");
+
+        final int entries = 100;
+
+        for (int i = 0; i < entries; i++)
+            second.put((int)(Math.random() * entries), getClass().getName());
+
+        final String prevVerFolder = U.maskForFileName(ignite.cluster().localNode().consistentId().toString());
+        final String path = new File(new File(U.defaultWorkDirectory(), "db"), prevVerFolder).getCanonicalPath();
+
+        assertPdsDirsDefaultExist(prevVerFolder);
+        stopAllGrids();
+
+        this.configuredConsistentId = null;
+        this.strLog = new GridStringLogger();
+        startActivateGrid(0);
+        assertNodeIndexesInFolder(0); //one 0 index folder is created
+
+        final String wholeNodeLog = strLog.toString();
+        stopAllGrids();
+
+        String foundWarning = null;
+        for (String line : wholeNodeLog.split("\n")) {
+            if (line.contains("There is other non-empty storage folder under storage base directory")) {
+                foundWarning = line;
+                break;
+            }
+        }
+
+        if (foundWarning != null)
+            log.info("\nWARNING generated successfully [\n" + foundWarning + "\n]");
+
+        assertTrue("Expected to warn user on existence of old style path",
+            foundWarning != null);
+
+        assertTrue("Expected to warn user on existence of old style path [" + path + "]",
+            foundWarning.contains(path));
+
+        assertTrue("Expected to print some size for [" + path + "]",
+            Pattern.compile(" [0-9]* bytes").matcher(foundWarning).find());
+
+        strLog = null;
+        startActivateGrid(0);
+        assertNodeIndexesInFolder(0); //one 0 index folder is created
+        stopAllGrids();
+    }
+
+    /**
+     * @param indexes expected new style node indexes in folders
+     * @throws IgniteCheckedException if failed
+     */
+    private void assertNodeIndexesInFolder(Integer... indexes) throws IgniteCheckedException {
+        assertEquals(new TreeSet<>(Arrays.asList(indexes)), getAllNodeIndexesInFolder());
+    }
+
+    /**
+     * @return set of all indexes of nodes found in work folder
+     * @throws IgniteCheckedException if failed.
+     */
+    @NotNull private Set<Integer> getAllNodeIndexesInFolder() throws IgniteCheckedException {
+        final File curFolder = new File(U.defaultWorkDirectory(), PdsConsistentIdProcessor.DB_DEFAULT_FOLDER);
+        final Set<Integer> indexes = new TreeSet<>();
+        final File[] files = curFolder.listFiles(PdsConsistentIdProcessor.DB_SUBFOLDERS_NEW_STYLE_FILTER);
+
+        for (File file : files) {
+            final PdsConsistentIdProcessor.FolderCandidate uid = parseSubFolderName(file, log);
+
+            if (uid != null)
+                indexes.add(uid.nodeIndex());
+        }
+
+        return indexes;
+    }
+
+    /**
+     * Checks existence of all storage-related directories
+     *
+     * @param subDirName sub directories name expected
+     * @throws IgniteCheckedException if IO error occur
+     */
+    private void assertPdsDirsDefaultExist(String subDirName) throws IgniteCheckedException {
+        assertDirectoryExist("binary_meta", subDirName);
+        assertDirectoryExist(PersistentStoreConfiguration.DFLT_WAL_STORE_PATH, subDirName);
+        assertDirectoryExist(PersistentStoreConfiguration.DFLT_WAL_ARCHIVE_PATH, subDirName);
+        assertDirectoryExist(PdsConsistentIdProcessor.DB_DEFAULT_FOLDER, subDirName);
+    }
+
+    /**
+     * Checks one folder existence.
+     *
+     * @param subFolderNames sub folders chain array to touch.
+     * @throws IgniteCheckedException if IO error occur.
+     */
+    private void assertDirectoryExist(String... subFolderNames) throws IgniteCheckedException {
+        final File curFolder = new File(U.defaultWorkDirectory());
+
+        assertDirectoryExist(curFolder, subFolderNames);
+    }
+
+
+    /**
+     * Checks one folder existence.
+     *
+     * @param workFolder current work folder.
+     * @param subFolderNames sub folders chain array to touch.
+     * @throws IgniteCheckedException if IO error occur.
+     */
+    private void assertDirectoryExist(final File workFolder, String... subFolderNames) throws IgniteCheckedException {
+        File curFolder = workFolder;
+
+        for (String name : subFolderNames) {
+            curFolder = new File(curFolder, name);
+        }
+
+        final String path;
+
+        try {
+            path = curFolder.getCanonicalPath();
+        }
+        catch (IOException e) {
+            throw new IgniteCheckedException("Failed to convert path: [" + curFolder.getAbsolutePath() + "]", e);
+        }
+        assertTrue("Directory " + Arrays.asList(subFolderNames).toString()
+            + " is expected to exist [" + path + "]", curFolder.exists() && curFolder.isDirectory());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/IgniteWalRecoveryTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/IgniteWalRecoveryTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/IgniteWalRecoveryTest.java
index c160f60..bf8cd85 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/IgniteWalRecoveryTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/IgniteWalRecoveryTest.java
@@ -28,6 +28,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Random;
 import java.util.Set;
+import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
@@ -68,6 +69,7 @@ import org.apache.ignite.internal.pagemem.wal.record.WALRecord;
 import org.apache.ignite.internal.pagemem.wal.record.delta.PageDeltaRecord;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor;
 import org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryEx;
 import org.apache.ignite.internal.processors.cache.persistence.tree.io.TrackingPageIO;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
@@ -575,9 +577,11 @@ public class IgniteWalRecoveryTest extends GridCommonAbstractTest {
             for (int i = 0; i < 100; i++)
                 cache.put(i, new IndexedObject(i));
 
+            final Object consistentId = ignite.cluster().localNode().consistentId();
+
             stopGrid(1);
 
-            final File cacheDir = cacheDir("partitioned", ignite.context().discovery().consistentId().toString());
+            final File cacheDir = cacheDir("partitioned", consistentId.toString());
 
             final boolean renamed = cacheDir.renameTo(new File(cacheDir.getParent(), "cache-partitioned0"));
 
@@ -605,14 +609,15 @@ public class IgniteWalRecoveryTest extends GridCommonAbstractTest {
      * @return Cache dir.
      * @throws IgniteCheckedException If fail.
      */
-    private File cacheDir(final String cacheName, String consId) throws IgniteCheckedException {
-        consId = consId.replaceAll("[\\.:]", "_");
+    private File cacheDir(final String cacheName, final String consId) throws IgniteCheckedException {
+        final String subfolderName
+            = PdsConsistentIdProcessor.genNewStyleSubfolderName(0, UUID.fromString(consId));
 
         final File dbDir = U.resolveWorkDirectory(U.defaultWorkDirectory(), DFLT_STORE_DIR, false);
 
         assert dbDir.exists();
 
-        final File consIdDir = new File(dbDir.getAbsolutePath(), consId);
+        final File consIdDir = new File(dbDir.getAbsolutePath(), subfolderName);
 
         assert consIdDir.exists();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
index e2f58bd..b9c60b2 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
@@ -30,6 +30,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -64,14 +65,17 @@ import org.apache.ignite.internal.processors.cache.KeyCacheObject;
 import org.apache.ignite.internal.processors.cache.persistence.wal.FileWriteAheadLogManager;
 import org.apache.ignite.internal.processors.cache.persistence.wal.reader.IgniteWalIteratorFactory;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.transactions.Transaction;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.events.EventType.EVT_WAL_SEGMENT_ARCHIVED;
+import static org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor.genNewStyleSubfolderName;
 import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.DFLT_STORE_DIR;
 
 /**
@@ -87,9 +91,6 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
     /** additional cache for testing different combinations of types in WAL */
     private static final String CACHE_ADDL_NAME = "cache1";
 
-    /** Fill wal with some data before iterating. Should be true for non local run */
-    private static final boolean fillWalBeforeTest = true;
-
     /** Delete DB dir before test. */
     private static final boolean deleteBefore = true;
 
@@ -152,7 +153,7 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
     }
 
     /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
+    @Override protected void beforeTest() throws Exception {
         stopAllGrids();
 
         if (deleteBefore)
@@ -171,8 +172,7 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
      * @throws IgniteCheckedException If failed.
      */
     private void deleteWorkFiles() throws IgniteCheckedException {
-        if (fillWalBeforeTest)
-            deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), DFLT_STORE_DIR, false));
+        deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), DFLT_STORE_DIR, false));
     }
 
     /**
@@ -181,27 +181,23 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
     public void testFillWalAndReadRecords() throws Exception {
         final int cacheObjectsToWrite = 10000;
 
-        final String consistentId;
-        if (fillWalBeforeTest) {
-            final Ignite ignite0 = startGrid("node0");
+        final Ignite ignite0 = startGrid("node0");
 
-            ignite0.active(true);
+        ignite0.active(true);
 
-            consistentId = U.maskForFileName(ignite0.cluster().localNode().consistentId().toString());
+        final Serializable consistentId = (Serializable)ignite0.cluster().localNode().consistentId();
+        final String subfolderName = genNewStyleSubfolderName(0, (UUID)consistentId);
 
-            putDummyRecords(ignite0, cacheObjectsToWrite);
+        putDummyRecords(ignite0, cacheObjectsToWrite);
 
-            stopGrid("node0");
-        }
-        else
-            consistentId = "127_0_0_1_47500";
+        stopGrid("node0");
 
         final String workDir = U.defaultWorkDirectory();
         final File db = U.resolveWorkDirectory(workDir, DFLT_STORE_DIR, false);
         final File wal = new File(db, "wal");
         final File walArchive = new File(wal, "archive");
 
-        final MockWalIteratorFactory mockItFactory = new MockWalIteratorFactory(log, PAGE_SIZE, consistentId, WAL_SEGMENTS);
+        final MockWalIteratorFactory mockItFactory = new MockWalIteratorFactory(log, PAGE_SIZE, consistentId, subfolderName, WAL_SEGMENTS);
         final WALIterator it = mockItFactory.iterator(wal, walArchive);
         final int cntUsingMockIter = iterateAndCount(it, false);
 
@@ -209,11 +205,11 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
         assert cntUsingMockIter > 0;
         assert cntUsingMockIter > cacheObjectsToWrite;
 
-        final File walArchiveDirWithConsistentId = new File(walArchive, consistentId);
-        final File walWorkDirWithConsistentId = new File(wal, consistentId);
+        final File walArchiveDirWithConsistentId = new File(walArchive, subfolderName);
+        final File walWorkDirWithConsistentId = new File(wal, subfolderName);
 
         final File binaryMeta = U.resolveWorkDirectory(workDir, "binary_meta", false);
-        final File binaryMetaWithConsId = new File(binaryMeta, consistentId);
+        final File binaryMetaWithConsId = new File(binaryMeta, subfolderName);
         final File marshaller = U.resolveWorkDirectory(workDir, "marshaller", false);
 
         final IgniteWalIteratorFactory factory = new IgniteWalIteratorFactory(log, PAGE_SIZE, binaryMetaWithConsId, marshaller);
@@ -304,7 +300,7 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
         final IgniteEvents evts = ignite.events();
 
         if (!evts.isEnabled(EVT_WAL_SEGMENT_ARCHIVED))
-            return; //nothing to test
+            assertTrue("nothing to test", false);
 
         evts.localListen(new IgnitePredicate<Event>() {
             @Override public boolean apply(Event e) {
@@ -428,29 +424,23 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
         final int cntEntries = 1000;
         final int txCnt = 100;
 
-        final Map<Object, Object> ctrlMap = new HashMap<>();
-        final String consistentId;
-        if (fillWalBeforeTest) {
-            final Ignite ignite0 = startGrid("node0");
-
-            ignite0.active(true);
-
-            final IgniteCache<Object, Object> entries = txPutDummyRecords(ignite0, cntEntries, txCnt);
+        final Ignite ignite0 = startGrid("node0");
 
-            for (Cache.Entry<Object, Object> next : entries) {
-                ctrlMap.put(next.getKey(), next.getValue());
-            }
+        ignite0.active(true);
 
-            consistentId = U.maskForFileName(ignite0.cluster().localNode().consistentId().toString());
+        final IgniteCache<Object, Object> entries = txPutDummyRecords(ignite0, cntEntries, txCnt);
 
-            stopGrid("node0");
+        final Map<Object, Object> ctrlMap = new HashMap<>();
+        for (Cache.Entry<Object, Object> next : entries) {
+            ctrlMap.put(next.getKey(), next.getValue());
         }
-        else
-            consistentId = "127_0_0_1_47500";
+
+        final String subfolderName = genDbSubfolderName(ignite0, 0);
+        stopGrid("node0");
 
         final String workDir = U.defaultWorkDirectory();
         final File binaryMeta = U.resolveWorkDirectory(workDir, "binary_meta", false);
-        final File binaryMetaWithConsId = new File(binaryMeta, consistentId);
+        final File binaryMetaWithConsId = new File(binaryMeta, subfolderName);
         final File marshallerMapping = U.resolveWorkDirectory(workDir, "marshaller", false);
 
         final IgniteWalIteratorFactory factory = new IgniteWalIteratorFactory(log,
@@ -474,17 +464,28 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
                 }
             }
         };
-        scanIterateAndCount(factory, workDir, consistentId, cntEntries, txCnt, objConsumer, null);
+        scanIterateAndCount(factory, workDir, subfolderName, cntEntries, txCnt, objConsumer, null);
 
         assert ctrlMap.isEmpty() : " Control Map is not empty after reading entries " + ctrlMap;
     }
 
     /**
+     * Generates DB subfolder name for provided node index (local) and UUID (consistent ID)
+     *
+     * @param ignite ignite instance.
+     * @param nodeIdx node index.
+     * @return folder file name
+     */
+    @NotNull private String genDbSubfolderName(Ignite ignite, int nodeIdx) {
+        return genNewStyleSubfolderName(nodeIdx, (UUID)ignite.cluster().localNode().consistentId());
+    }
+
+    /**
      * Scan WAL and WAL archive for logical records and its entries.
      *
      * @param factory WAL iterator factory.
      * @param workDir Ignite work directory.
-     * @param consistentId consistent ID.
+     * @param subfolderName DB subfolder name based on consistent ID.
      * @param expCntEntries minimum expected entries count to find.
      * @param expTxCnt minimum expected transaction count to find.
      * @param objConsumer object handler, called for each object found in logical data records.
@@ -494,7 +495,7 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
     private void scanIterateAndCount(
         final IgniteWalIteratorFactory factory,
         final String workDir,
-        final String consistentId,
+        final String subfolderName,
         final int expCntEntries,
         final int expTxCnt,
         @Nullable final BiConsumer<Object, Object> objConsumer,
@@ -504,11 +505,10 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
         final File wal = new File(db, "wal");
         final File walArchive = new File(wal, "archive");
 
-        final File walArchiveDirWithConsistentId = new File(walArchive, consistentId);
+        final File walArchiveDirWithConsistentId = new File(walArchive, subfolderName);
 
         final File[] files = walArchiveDirWithConsistentId.listFiles(FileWriteAheadLogManager.WAL_SEGMENT_FILE_FILTER);
-
-        assert files != null : "Can't iterate over files [" + walArchiveDirWithConsistentId + "] Directory is N/A";
+        A.notNull(files, "Can't iterate over files [" + walArchiveDirWithConsistentId + "] Directory is N/A");
         final WALIterator iter = factory.iteratorArchiveFiles(files);
 
         final Map<GridCacheVersion, Integer> cntArch = iterateAndCountDataRecord(iter, objConsumer, dataRecordHnd);
@@ -520,8 +520,8 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
 
         log.info("Total tx found loaded using archive directory (file-by-file): " + txCntObservedArch);
 
-        final File walWorkDirWithConsistentId = new File(wal, consistentId);
-        final File[] workFiles = walWorkDirWithConsistentId.listFiles(FileWriteAheadLogManager.WAL_SEGMENT_FILE_FILTER);
+        final File walWorkDirWithNodeSubDir = new File(wal, subfolderName);
+        final File[] workFiles = walWorkDirWithNodeSubDir.listFiles(FileWriteAheadLogManager.WAL_SEGMENT_FILE_FILTER);
 
         final WALIterator tuples = factory.iteratorWorkFiles(workFiles);
         final Map<GridCacheVersion, Integer> cntWork = iterateAndCountDataRecord(tuples, objConsumer, dataRecordHnd);
@@ -541,71 +541,66 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
      */
     public void testFillWalWithDifferentTypes() throws Exception {
         int cntEntries = 0;
-        final String consistentId;
 
         final Map<Object, Object> ctrlMap = new HashMap<>();
         final Map<Object, Object> ctrlMapForBinaryObjects = new HashMap<>();
         final Collection<String> ctrlStringsToSearch = new HashSet<>();
         final Collection<String> ctrlStringsForBinaryObjSearch = new HashSet<>();
-        if (fillWalBeforeTest) {
-            final Ignite ignite0 = startGrid("node0");
-            ignite0.active(true);
-
-            final IgniteCache<Object, Object> addlCache = ignite0.getOrCreateCache(CACHE_ADDL_NAME);
-            addlCache.put("1", "2");
-            addlCache.put(1, 2);
-            addlCache.put(1L, 2L);
-            addlCache.put(TestEnum.A, "Enum_As_Key");
-            addlCache.put("Enum_As_Value", TestEnum.B);
-            addlCache.put(TestEnum.C, TestEnum.C);
-
-            addlCache.put("Serializable", new TestSerializable(42));
-            addlCache.put(new TestSerializable(42), "Serializable_As_Key");
-            addlCache.put("Externalizable", new TestExternalizable(42));
-            addlCache.put(new TestExternalizable(42), "Externalizable_As_Key");
-            addlCache.put(292, new IndexedObject(292));
-
-            final String search1 = "SomeUnexpectedStringValueAsKeyToSearch";
-            ctrlStringsToSearch.add(search1);
-            ctrlStringsForBinaryObjSearch.add(search1);
-            addlCache.put(search1, "SearchKey");
-
-            String search2 = "SomeTestStringContainerToBePrintedLongLine";
-            final TestStringContainerToBePrinted val = new TestStringContainerToBePrinted(search2);
-            ctrlStringsToSearch.add(val.toString()); //will validate original toString() was called
-            ctrlStringsForBinaryObjSearch.add(search2);
-            addlCache.put("SearchValue", val);
-
-            String search3 = "SomeTestStringContainerToBePrintedLongLine2";
-            final TestStringContainerToBePrinted key = new TestStringContainerToBePrinted(search3);
-            ctrlStringsToSearch.add(key.toString()); //will validate original toString() was called
-            ctrlStringsForBinaryObjSearch.add(search3); //validate only string itself
-            addlCache.put(key, "SearchKey");
-
-            cntEntries = addlCache.size();
-            for (Cache.Entry<Object, Object> next : addlCache) {
-                ctrlMap.put(next.getKey(), next.getValue());
-            }
+        final Ignite ignite0 = startGrid("node0");
+        ignite0.active(true);
+
+        final IgniteCache<Object, Object> addlCache = ignite0.getOrCreateCache(CACHE_ADDL_NAME);
+        addlCache.put("1", "2");
+        addlCache.put(1, 2);
+        addlCache.put(1L, 2L);
+        addlCache.put(TestEnum.A, "Enum_As_Key");
+        addlCache.put("Enum_As_Value", TestEnum.B);
+        addlCache.put(TestEnum.C, TestEnum.C);
+
+        addlCache.put("Serializable", new TestSerializable(42));
+        addlCache.put(new TestSerializable(42), "Serializable_As_Key");
+        addlCache.put("Externalizable", new TestExternalizable(42));
+        addlCache.put(new TestExternalizable(42), "Externalizable_As_Key");
+        addlCache.put(292, new IndexedObject(292));
+
+        final String search1 = "SomeUnexpectedStringValueAsKeyToSearch";
+        ctrlStringsToSearch.add(search1);
+        ctrlStringsForBinaryObjSearch.add(search1);
+        addlCache.put(search1, "SearchKey");
+
+        String search2 = "SomeTestStringContainerToBePrintedLongLine";
+        final TestStringContainerToBePrinted val = new TestStringContainerToBePrinted(search2);
+        ctrlStringsToSearch.add(val.toString()); //will validate original toString() was called
+        ctrlStringsForBinaryObjSearch.add(search2);
+        addlCache.put("SearchValue", val);
+
+        String search3 = "SomeTestStringContainerToBePrintedLongLine2";
+        final TestStringContainerToBePrinted key = new TestStringContainerToBePrinted(search3);
+        ctrlStringsToSearch.add(key.toString()); //will validate original toString() was called
+        ctrlStringsForBinaryObjSearch.add(search3); //validate only string itself
+        addlCache.put(key, "SearchKey");
+
+        cntEntries = addlCache.size();
+        for (Cache.Entry<Object, Object> next : addlCache) {
+            ctrlMap.put(next.getKey(), next.getValue());
+        }
 
             for (Cache.Entry<Object, Object> next : addlCache) {
                 ctrlMapForBinaryObjects.put(next.getKey(), next.getValue());
             }
 
-            consistentId = U.maskForFileName(ignite0.cluster().localNode().consistentId().toString());
+        final String subfolderName = genDbSubfolderName(ignite0, 0);
 
-            stopGrid("node0");
-        }
-        else
-            consistentId = "127_0_0_1_47500";
+        stopGrid("node0");
 
         final String workDir = U.defaultWorkDirectory();
 
         final File binaryMeta = U.resolveWorkDirectory(workDir, "binary_meta", false);
-        final File binaryMetaWithConsId = new File(binaryMeta, consistentId);
+        final File binaryMetaWithNodeSubfolder = new File(binaryMeta, subfolderName);
         final File marshallerMapping = U.resolveWorkDirectory(workDir, "marshaller", false);
 
         final IgniteWalIteratorFactory factory = new IgniteWalIteratorFactory(log, PAGE_SIZE,
-            binaryMetaWithConsId,
+            binaryMetaWithNodeSubfolder,
             marshallerMapping);
         final BiConsumer<Object, Object> objConsumer = new BiConsumer<Object, Object>() {
             @Override public void accept(Object key, Object val) {
@@ -634,7 +629,7 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
                 }
             }
         };
-        scanIterateAndCount(factory, workDir, consistentId, cntEntries, 0, objConsumer, toStrChecker);
+        scanIterateAndCount(factory, workDir, subfolderName, cntEntries, 0, objConsumer, toStrChecker);
 
         assert ctrlMap.isEmpty() : " Control Map is not empty after reading entries: " + ctrlMap;
         assert ctrlStringsToSearch.isEmpty() : " Control Map for strings in entries is not empty after" +
@@ -642,7 +637,7 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
 
         //Validate same WAL log with flag binary objects only
         final IgniteWalIteratorFactory keepBinFactory = new IgniteWalIteratorFactory(log, PAGE_SIZE,
-            binaryMetaWithConsId,
+            binaryMetaWithNodeSubfolder,
             marshallerMapping,
             true);
         final BiConsumer<Object, Object> binObjConsumer = new BiConsumer<Object, Object>() {
@@ -693,7 +688,7 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
             }
         };
 
-        final Consumer<DataRecord> binObjToStringChecker = new Consumer<DataRecord>() {
+        final Consumer<DataRecord> binObjToStrChecker = new Consumer<DataRecord>() {
             @Override public void accept(DataRecord record) {
                 String strRepresentation = record.toString();
                 for (Iterator<String> iter = ctrlStringsForBinaryObjSearch.iterator(); iter.hasNext(); ) {
@@ -705,7 +700,7 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
                 }
             }
         };
-        scanIterateAndCount(keepBinFactory, workDir, consistentId, cntEntries, 0, binObjConsumer, binObjToStringChecker);
+        scanIterateAndCount(keepBinFactory, workDir, subfolderName, cntEntries, 0, binObjConsumer, binObjToStrChecker);
 
         assert ctrlMapForBinaryObjects.isEmpty() : " Control Map is not empty after reading entries: " + ctrlMapForBinaryObjects;
         assert ctrlStringsForBinaryObjSearch.isEmpty() : " Control Map for strings in entries is not empty after" +

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/MockWalIteratorFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/MockWalIteratorFactory.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/MockWalIteratorFactory.java
index 4030e53..05636eb 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/MockWalIteratorFactory.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/MockWalIteratorFactory.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.processors.cache.persistence.db.wal.reader;
 
 import java.io.File;
+import java.io.Serializable;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.configuration.IgniteConfiguration;
@@ -29,6 +30,8 @@ import org.apache.ignite.internal.pagemem.wal.WALIterator;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
 import org.apache.ignite.internal.processors.cache.persistence.file.FileIOFactory;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsFoldersResolver;
+import org.apache.ignite.internal.processors.cache.persistence.filename.PdsFolderSettings;
 import org.apache.ignite.internal.processors.cache.persistence.wal.FileWriteAheadLogManager;
 import org.jetbrains.annotations.Nullable;
 import org.mockito.Mockito;
@@ -47,25 +50,34 @@ public class MockWalIteratorFactory {
     private final int pageSize;
 
     /** Consistent node id. */
-    private final String consistentId;
+    private final Serializable consistentId;
+
+    /** DB storage subfolder based node index and consistent node ID. */
+    private String subfolderName;
 
     /** Segments count in work dir. */
     private int segments;
 
+
     /**
      * Creates factory
      * @param log Logger.
      * @param pageSize Page size.
      * @param consistentId Consistent id.
+     * @param subfolderName
      * @param segments Segments.
      */
-    public MockWalIteratorFactory(@Nullable IgniteLogger log, int pageSize, String consistentId, int segments) {
+    public MockWalIteratorFactory(@Nullable IgniteLogger log,
+        int pageSize,
+        Serializable consistentId,
+        String subfolderName,
+        int segments) {
         this.log = log == null ? Mockito.mock(IgniteLogger.class) : log;
         this.pageSize = pageSize;
         this.consistentId = consistentId;
+        this.subfolderName = subfolderName;
         this.segments = segments;
     }
-
     /**
      * Creates iterator
      * @param wal WAL directory without node consistent id
@@ -93,10 +105,13 @@ public class MockWalIteratorFactory {
 
         when(ctx.config()).thenReturn(cfg);
         when(ctx.clientNode()).thenReturn(false);
+        when(ctx.pdsFolderResolver()).thenReturn(new PdsFoldersResolver() {
+            @Override public PdsFolderSettings resolveFolders() {
+                return new PdsFolderSettings(new File("."), subfolderName, consistentId, null, false);
+            }
+        });
 
         final GridDiscoveryManager disco = Mockito.mock(GridDiscoveryManager.class);
-
-        when(disco.consistentId()).thenReturn(consistentId);
         when(ctx.discovery()).thenReturn(disco);
 
         final IgniteWriteAheadLogManager mgr = new FileWriteAheadLogManager(ctx);

http://git-wip-us.apache.org/repos/asf/ignite/blob/62f3c4c5/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite2.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite2.java
index 29f7255..d92d848 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite2.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite2.java
@@ -29,6 +29,7 @@ import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsPageE
 import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsRebalancingOnNotStableTopologyTest;
 import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsTransactionsHangTest;
 import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsWholeClusterRestartTest;
+import org.apache.ignite.internal.processors.cache.persistence.db.filename.IgniteUidAsConsistentIdMigrationTest;
 import org.apache.ignite.internal.processors.cache.persistence.db.wal.IgniteWalFlushFailoverTest;
 import org.apache.ignite.internal.processors.cache.persistence.db.wal.IgniteWalHistoryReservationsTest;
 import org.apache.ignite.internal.processors.cache.persistence.db.wal.IgniteWalSerializerVersionTest;
@@ -78,6 +79,9 @@ public class IgnitePdsTestSuite2 extends TestSuite {
 
         suite.addTestSuite(IgnitePdsExchangeDuringCheckpointTest.class);
 
+        // new style folders with generated consistent ID test
+        suite.addTestSuite(IgniteUidAsConsistentIdMigrationTest.class);
+
         suite.addTestSuite(IgniteWalSerializerVersionTest.class);
 
         return suite;


[29/50] [abbrv] ignite git commit: IGNITE-6550 Added serializer version getter

Posted by ag...@apache.org.
IGNITE-6550 Added serializer version getter


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

Branch: refs/heads/ignite-6305
Commit: e98e392e28d5a3209e97bc4ff27e4883d8332899
Parents: 8bd51d8
Author: Dmitriy Govorukhin <dm...@gmail.com>
Authored: Thu Oct 5 10:56:46 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Oct 5 10:56:46 2017 +0300

----------------------------------------------------------------------
 .../cache/persistence/wal/FileWriteAheadLogManager.java       | 7 +++++++
 1 file changed, 7 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e98e392e/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
index 6a75dd2..383c605 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
@@ -451,6 +451,13 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
     }
 
     /**
+     * @return Latest serializer version.
+     */
+    public int serializerVersion() {
+        return serializerVersion;
+    }
+
+    /**
      * Checks if there was elapsed significant period of inactivity.
      * If WAL auto-archive is enabled using {@link #walAutoArchiveAfterInactivity} > 0 this method will activate
      * roll over by timeout<br>


[40/50] [abbrv] ignite git commit: IGNITE-6054: SQL: implemented "WRAP_KEY" and "WRAP_VALUE" modes for CREATE TABLE. This closes #2784.

Posted by ag...@apache.org.
IGNITE-6054: SQL: implemented "WRAP_KEY" and "WRAP_VALUE" modes for CREATE TABLE. This closes #2784.


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

Branch: refs/heads/ignite-6305
Commit: 79d94cf4bbc906449a4c6995801fa61daaf80faa
Parents: 74f0400
Author: Alexander Paschenko <al...@gmail.com>
Authored: Fri Oct 6 18:04:44 2017 +0300
Committer: devozerov <pp...@gmail.com>
Committed: Fri Oct 6 18:04:44 2017 +0300

----------------------------------------------------------------------
 .../jdbc/thin/JdbcThinMetadataSelfTest.java     |   2 +-
 .../cache/query/IgniteQueryErrorCode.java       |   2 +-
 .../processors/query/GridQueryIndexing.java     |  22 +-
 .../processors/query/GridQueryProcessor.java    |   8 +-
 .../query/QueryTypeDescriptorImpl.java          |  42 ++-
 .../query/property/QueryBinaryProperty.java     |   1 -
 ...IgniteClientCacheInitializationFailTest.java |  18 +-
 .../query/h2/DmlStatementsProcessor.java        |  26 +-
 .../internal/processors/query/h2/H2Schema.java  |  17 +-
 .../internal/processors/query/h2/H2TypeKey.java |  64 ++++
 .../processors/query/h2/IgniteH2Indexing.java   |  33 +-
 .../query/h2/ddl/DdlStatementsProcessor.java    |  36 ++-
 .../query/h2/sql/GridSqlCreateTable.java        |  34 +++
 .../query/h2/sql/GridSqlQueryParser.java        |  58 +++-
 ...ynamicColumnsAbstractConcurrentSelfTest.java |  57 ++--
 ...umnsConcurrentAtomicPartitionedSelfTest.java |   2 +-
 ...lumnsConcurrentAtomicReplicatedSelfTest.java |   2 +-
 ...currentTransactionalPartitionedSelfTest.java |   2 +-
 ...ncurrentTransactionalReplicatedSelfTest.java |   5 +-
 .../H2DynamicColumnsAbstractBasicSelfTest.java  |  44 +++
 .../cache/index/H2DynamicTableSelfTest.java     | 301 +++++++++++++++++--
 .../query/IgniteSqlNotNullConstraintTest.java   |   2 +-
 .../h2/GridIndexingSpiAbstractSelfTest.java     |  47 +--
 .../Cache/Query/CacheDmlQueriesTest.cs          |   4 +-
 24 files changed, 673 insertions(+), 156 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
index 6c20de0..4e1ae4d 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
@@ -139,7 +139,7 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest {
             Statement stmt = conn.createStatement();
 
             stmt.execute("CREATE TABLE TEST (ID INT, NAME VARCHAR(50), VAL VARCHAR(50), PRIMARY KEY (ID, NAME))");
-            stmt.execute("CREATE TABLE \"Quoted\" (\"Id\" INT primary key, \"Name\" VARCHAR(50))");
+            stmt.execute("CREATE TABLE \"Quoted\" (\"Id\" INT primary key, \"Name\" VARCHAR(50)) WITH WRAP_KEY");
             stmt.execute("CREATE INDEX \"MyTestIndex quoted\" on \"Quoted\" (\"Id\" DESC)");
             stmt.execute("CREATE INDEX IDX ON TEST (ID ASC)");
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java
index 8e5af31..e0ff9a4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java
@@ -91,7 +91,7 @@ public final class IgniteQueryErrorCode {
     /** Attempt to INSERT or MERGE {@code null} key. */
     public final static int NULL_KEY = 4003;
 
-    /** Attempt to INSERT or MERGE {@code null} value. */
+    /** Attempt to INSERT or MERGE {@code null} value, or to to set {@code null} to a {@code NOT NULL} column. */
     public final static int NULL_VALUE = 4004;
 
     /** {@link EntryProcessor} has thrown an exception during {@link IgniteCache#invokeAll}. */

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
index b8445ca..93d541d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java
@@ -66,13 +66,13 @@ public interface GridQueryIndexing {
      * Parses SQL query into two step query and executes it.
      *
      * @param schemaName Schema name.
+     * @param cacheName Cache name.
      * @param qry Query.
      * @param keepBinary Keep binary flag.
-     * @param mainCacheId Main cache ID.
-     * @return Cursor.
+     * @param mainCacheId Main cache ID.    @return Cursor.
      * @throws IgniteCheckedException If failed.
      */
-    public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, SqlQuery qry,
+    public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, String cacheName, SqlQuery qry,
         boolean keepBinary, int mainCacheId) throws IgniteCheckedException;
 
     /**
@@ -109,12 +109,12 @@ public interface GridQueryIndexing {
      * Executes regular query.
      *
      * @param schemaName Schema name.
-     * @param qry Query.
+     * @param cacheName Cache name.
+     *@param qry Query.
      * @param filter Cache name and key filter.
-     * @param keepBinary Keep binary flag.
-     * @return Cursor.
+     * @param keepBinary Keep binary flag.    @return Cursor.
      */
-    public <K, V> QueryCursor<Cache.Entry<K,V>> queryLocalSql(String schemaName, SqlQuery qry,
+    public <K, V> QueryCursor<Cache.Entry<K,V>> queryLocalSql(String schemaName, String cacheName, SqlQuery qry,
         IndexingQueryFilter filter, boolean keepBinary) throws IgniteCheckedException;
 
     /**
@@ -134,14 +134,14 @@ public interface GridQueryIndexing {
      * Executes text query.
      *
      * @param schemaName Schema name.
+     * @param cacheName Cache name.
      * @param qry Text query.
      * @param typeName Type name.
-     * @param filter Cache name and key filter.
-     * @return Queried rows.
+     * @param filter Cache name and key filter.    @return Queried rows.
      * @throws IgniteCheckedException If failed.
      */
-    public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String schemaName, String qry,
-        String typeName, IndexingQueryFilter filter) throws IgniteCheckedException;
+    public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String schemaName, String cacheName,
+        String qry, String typeName, IndexingQueryFilter filter) throws IgniteCheckedException;
 
     /**
      * Create new index locally.

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index 56e8a42..f044c1d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -2044,7 +2044,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             return executeQuery(GridCacheQueryType.SQL, qry.getSql(), cctx,
                 new IgniteOutClosureX<QueryCursor<Cache.Entry<K, V>>>() {
                     @Override public QueryCursor<Cache.Entry<K, V>> applyx() throws IgniteCheckedException {
-                        return idx.queryDistributedSql(schemaName, qry, keepBinary, mainCacheId);
+                        return idx.queryDistributedSql(schemaName, cctx.name(), qry, keepBinary, mainCacheId);
                     }
                 }, true);
         }
@@ -2088,10 +2088,10 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                         if (cctx.config().getQueryParallelism() > 1) {
                             qry.setDistributedJoins(true);
 
-                            return idx.queryDistributedSql(schemaName, qry, keepBinary, mainCacheId);
+                            return idx.queryDistributedSql(schemaName, cctx.name(), qry, keepBinary, mainCacheId);
                         }
                         else
-                            return idx.queryLocalSql(schemaName, qry, idx.backupFilter(requestTopVer.get(),
+                            return idx.queryLocalSql(schemaName, cctx.name(), qry, idx.backupFilter(requestTopVer.get(),
                                 qry.getPartitions()), keepBinary);
                     }
                 }, true);
@@ -2344,7 +2344,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                         String typeName = typeName(cacheName, resType);
                         String schemaName = idx.schema(cacheName);
 
-                        return idx.queryLocalText(schemaName, clause, typeName, filters);
+                        return idx.queryLocalText(schemaName, cacheName, clause, typeName, filters);
                     }
                 }, true);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
index e12476a..72adefd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
@@ -24,12 +24,12 @@ import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cache.QueryIndexType;
 import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
@@ -453,7 +453,7 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
      * Sets key field name.
      * @param keyFieldName Key field name.
      */
-    public void keyFieldName(String keyFieldName) {
+    void keyFieldName(String keyFieldName) {
         this.keyFieldName = keyFieldName;
     }
 
@@ -464,10 +464,10 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
 
     /**
      * Sets value field name.
-     * @param valueFieldName value field name.
+     * @param valFieldName value field name.
      */
-    public void valueFieldName(String valueFieldName) {
-        this.valFieldName = valueFieldName;
+    void valueFieldName(String valFieldName) {
+        this.valFieldName = valFieldName;
     }
 
     /** {@inheritDoc} */
@@ -480,6 +480,7 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
         return keyFieldName != null ? aliases.get(keyFieldName) : null;
     }
 
+    /** {@inheritDoc} */
     @Nullable @Override public String valueFieldAlias() {
         return valFieldName != null ? aliases.get(valFieldName) : null;
     }
@@ -487,17 +488,34 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
     /** {@inheritDoc} */
     @SuppressWarnings("ForLoopReplaceableByForEach")
     @Override public void validateKeyAndValue(Object key, Object val) throws IgniteCheckedException {
-        if (validateProps == null)
+        if (F.isEmpty(validateProps))
             return;
 
-        final int size = validateProps.size();
+        for (int i = 0; i < validateProps.size(); ++i) {
+            GridQueryProperty prop = validateProps.get(i);
+
+            Object propVal;
+
+            int errCode;
+
+            if (F.eq(prop.name(), keyFieldName)) {
+                propVal = key;
+
+                errCode = IgniteQueryErrorCode.NULL_KEY;
+            }
+            else if (F.eq(prop.name(), valFieldName)) {
+                propVal = val;
+
+                errCode = IgniteQueryErrorCode.NULL_VALUE;
+            }
+            else {
+                propVal = prop.value(key, val);
 
-        for (int idx = 0; idx < size; ++idx) {
-            GridQueryProperty prop = validateProps.get(idx);
+                errCode = IgniteQueryErrorCode.NULL_VALUE;
+            }
 
-            if (prop.value(key, val) == null)
-                throw new IgniteSQLException("Null value is not allowed for field '" + prop.name() + "'",
-                    IgniteQueryErrorCode.NULL_VALUE);
+            if (propVal == null)
+                throw new IgniteSQLException("Null value is not allowed for column '" + prop.name() + "'", errCode);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java
index 5d90a43..18508a8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java
@@ -81,7 +81,6 @@ public class QueryBinaryProperty implements GridQueryProperty {
      */
     public QueryBinaryProperty(GridKernalContext ctx, String propName, QueryBinaryProperty parent,
         Class<?> type, @Nullable Boolean key, String alias, boolean notNull) {
-
         this.ctx = ctx;
 
         log = ctx.log(QueryBinaryProperty.class);

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java
index 1ebf556..83dd9c9 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteClientCacheInitializationFailTest.java
@@ -193,7 +193,7 @@ public class IgniteClientCacheInitializationFailTest extends GridCommonAbstractT
     /**
      * @param client Client.
      */
-    @SuppressWarnings("ThrowableNotThrown")
+    @SuppressWarnings({"ThrowableNotThrown", "ThrowableResultOfMethodCallIgnored"})
     private void checkFailedCache(final Ignite client, final String cacheName) {
         GridTestUtils.assertThrows(log, new Callable<Object>() {
             @Override public Object call() throws Exception {
@@ -236,14 +236,14 @@ public class IgniteClientCacheInitializationFailTest extends GridCommonAbstractT
         }
 
         /** {@inheritDoc} */
-        @Override public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, SqlQuery qry,
-            boolean keepBinary, int mainCacheId) throws IgniteCheckedException {
+        @Override public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, String cacheName,
+            SqlQuery qry, boolean keepBinary, int mainCacheId) throws IgniteCheckedException {
             return null;
         }
 
         /** {@inheritDoc} */
-        @Override public List<FieldsQueryCursor<List<?>>> queryDistributedSqlFields(String schemaName, SqlFieldsQuery qry,
-            boolean keepBinary, GridQueryCancel cancel,
+        @Override public List<FieldsQueryCursor<List<?>>> queryDistributedSqlFields(String schemaName,
+            SqlFieldsQuery qry, boolean keepBinary, GridQueryCancel cancel,
             @Nullable Integer mainCacheId, boolean failOnMultipleStmts) throws IgniteCheckedException {
             return null;
         }
@@ -255,8 +255,8 @@ public class IgniteClientCacheInitializationFailTest extends GridCommonAbstractT
         }
 
         /** {@inheritDoc} */
-        @Override public <K, V> QueryCursor<Cache.Entry<K, V>> queryLocalSql(String schemaName, SqlQuery qry,
-            IndexingQueryFilter filter, boolean keepBinary) throws IgniteCheckedException {
+        @Override public <K, V> QueryCursor<Cache.Entry<K, V>> queryLocalSql(String schemaName, String cacheName,
+            SqlQuery qry, IndexingQueryFilter filter, boolean keepBinary) throws IgniteCheckedException {
             return null;
         }
 
@@ -267,8 +267,8 @@ public class IgniteClientCacheInitializationFailTest extends GridCommonAbstractT
         }
 
         /** {@inheritDoc} */
-        @Override public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String spaceName, String qry,
-            String typeName, IndexingQueryFilter filter) throws IgniteCheckedException {
+        @Override public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String spaceName,
+            String cacheName, String qry, String typeName, IndexingQueryFilter filter) throws IgniteCheckedException {
             return null;
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
index ee1875f..98117b2 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
@@ -49,13 +49,13 @@ import org.apache.ignite.binary.BinaryObjectBuilder;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.internal.GridKernalContext;
-import org.apache.ignite.internal.processors.odbc.SqlStateCode;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.CacheOperationContext;
 import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
 import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
+import org.apache.ignite.internal.processors.odbc.SqlStateCode;
 import org.apache.ignite.internal.processors.query.GridQueryCacheObjectsIterator;
 import org.apache.ignite.internal.processors.query.GridQueryCancel;
 import org.apache.ignite.internal.processors.query.GridQueryFieldsResult;
@@ -255,13 +255,12 @@ public class DmlStatementsProcessor {
     }
 
     /**
-     * Perform given statement against given data streamer. Only rows based INSERT and MERGE are supported
-     * as well as key bound UPDATE and DELETE (ones with filter {@code WHERE _key = ?}).
+     * Perform given statement against given data streamer. Only rows based INSERT is supported.
      *
      * @param streamer Streamer to feed data to.
      * @param stmt Statement.
      * @param args Statement arguments.
-     * @return Number of rows in given statement for INSERT and MERGE, {@code 1} otherwise.
+     * @return Number of rows in given INSERT statement.
      * @throws IgniteCheckedException if failed.
      */
     @SuppressWarnings({"unchecked", "ConstantConditions"})
@@ -916,11 +915,22 @@ public class DmlStatementsProcessor {
             val = convert(val, rowDesc, desc.valueClass(), plan.colTypes[plan.valColIdx]);
         }
 
-        if (key == null)
-            throw new IgniteSQLException("Key for INSERT or MERGE must not be null",  IgniteQueryErrorCode.NULL_KEY);
+        if (key == null) {
+            if (F.isEmpty(desc.keyFieldName()))
+                throw new IgniteSQLException("Key for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_KEY);
+            else
+                throw new IgniteSQLException("Null value is not allowed for column '" + desc.keyFieldName() + "'",
+                    IgniteQueryErrorCode.NULL_KEY);
+        }
 
-        if (val == null)
-            throw new IgniteSQLException("Value for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_VALUE);
+        if (val == null) {
+            if (F.isEmpty(desc.valueFieldName()))
+                throw new IgniteSQLException("Value for INSERT, MERGE, or UPDATE must not be null",
+                    IgniteQueryErrorCode.NULL_VALUE);
+            else
+                throw new IgniteSQLException("Null value is not allowed for column '" + desc.valueFieldName() + "'",
+                    IgniteQueryErrorCode.NULL_VALUE);
+        }
 
         Map<String, Object> newColVals = new HashMap<>();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java
index 3f39e6a..f5cf0f2 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java
@@ -17,9 +17,8 @@
 
 package org.apache.ignite.internal.processors.query.h2;
 
-import org.jsr166.ConcurrentHashMap8;
-
 import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 /**
@@ -30,10 +29,10 @@ public class H2Schema {
     private final String schemaName;
 
     /** */
-    private final ConcurrentMap<String, H2TableDescriptor> tbls = new ConcurrentHashMap8<>();
+    private final ConcurrentMap<String, H2TableDescriptor> tbls = new ConcurrentHashMap<>();
 
     /** */
-    private final ConcurrentMap<String, H2TableDescriptor> typeToTbl = new ConcurrentHashMap8<>();
+    private final ConcurrentMap<H2TypeKey, H2TableDescriptor> typeToTbl = new ConcurrentHashMap<>();
 
     /**
      * Constructor.
@@ -70,8 +69,8 @@ public class H2Schema {
      * @param typeName Type name.
      * @return Table.
      */
-    public H2TableDescriptor tableByTypeName(String typeName) {
-        return typeToTbl.get(typeName);
+    public H2TableDescriptor tableByTypeName(String cacheName, String typeName) {
+        return typeToTbl.get(new H2TypeKey(cacheName, typeName));
     }
 
     /**
@@ -81,7 +80,7 @@ public class H2Schema {
         if (tbls.putIfAbsent(tbl.tableName(), tbl) != null)
             throw new IllegalStateException("Table already registered: " + tbl.fullTableName());
 
-        if (typeToTbl.putIfAbsent(tbl.typeName(), tbl) != null)
+        if (typeToTbl.putIfAbsent(new H2TypeKey(tbl.cache().name(), tbl.typeName()), tbl) != null)
             throw new IllegalStateException("Table already registered: " + tbl.fullTableName());
     }
 
@@ -91,7 +90,7 @@ public class H2Schema {
     public void remove(H2TableDescriptor tbl) {
         tbls.remove(tbl.tableName());
 
-        typeToTbl.remove(tbl.typeName());
+        typeToTbl.remove(new H2TypeKey(tbl.cache().name(), tbl.typeName()));
     }
 
     /**
@@ -104,7 +103,7 @@ public class H2Schema {
 
         tbls.remove(tbl.tableName());
 
-        typeToTbl.remove(tbl.typeName());
+        typeToTbl.remove(new H2TypeKey(tbl.cache().name(), tbl.typeName()));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TypeKey.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TypeKey.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TypeKey.java
new file mode 100644
index 0000000..d39918c
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TypeKey.java
@@ -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.
+ */
+
+package org.apache.ignite.internal.processors.query.h2;
+
+import org.apache.ignite.internal.util.typedef.F;
+
+/**
+ * Key for types lookup.
+ */
+public class H2TypeKey {
+    /** Cache name. */
+    private final String cacheName;
+
+    /** Type name. */
+    private final String typeName;
+
+    /**
+     * Constructor.
+     *
+     * @param cacheName Cache name.
+     * @param typeName Type name.
+     */
+    H2TypeKey(String cacheName, String typeName) {
+        this.cacheName = cacheName;
+        this.typeName = typeName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        H2TypeKey other = (H2TypeKey)o;
+
+        return F.eq(typeName, other.typeName) && F.eq(cacheName, other.cacheName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = cacheName.hashCode();
+
+        res = 31 * res + typeName.hashCode();
+
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
----------------------------------------------------------------------
diff --git 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
index fd7b9a8..22ed592 100644
--- 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
@@ -548,7 +548,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
         GridCacheVersion ver,
         long expirationTime,
         long link) throws IgniteCheckedException {
-        H2TableDescriptor tbl = tableDescriptor(schema(cacheName), type.name());
+        H2TableDescriptor tbl = tableDescriptor(schema(cacheName), cacheName, type.name());
 
         if (tbl == null)
             return; // Type was rejected.
@@ -572,7 +572,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
         if (log.isDebugEnabled())
             log.debug("Removing key from cache query index [locId=" + nodeId + ", key=" + key + ", val=" + val + ']');
 
-        H2TableDescriptor tbl = tableDescriptor(schema(cacheName), type.name());
+        H2TableDescriptor tbl = tableDescriptor(schema(cacheName), cacheName, type.name());
 
         if (tbl == null)
             return;
@@ -777,10 +777,11 @@ public class IgniteH2Indexing implements GridQueryIndexing {
         }
     }
 
+    /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
-    @Override public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String schemaName, String qry,
-        String typeName, IndexingQueryFilter filters) throws IgniteCheckedException {
-        H2TableDescriptor tbl = tableDescriptor(schemaName, typeName);
+    @Override public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalText(String schemaName,
+        String cacheName, String qry, String typeName, IndexingQueryFilter filters) throws IgniteCheckedException {
+        H2TableDescriptor tbl = tableDescriptor(schemaName, cacheName, typeName);
 
         if (tbl != null && tbl.luceneIndex() != null) {
             GridRunningQueryInfo run = new GridRunningQueryInfo(qryIdGen.incrementAndGet(), qry, TEXT, schemaName,
@@ -1098,7 +1099,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
 
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
-    @Override public <K, V> QueryCursor<Cache.Entry<K,V>> queryLocalSql(String schemaName,
+    @Override public <K, V> QueryCursor<Cache.Entry<K,V>> queryLocalSql(String schemaName, String cacheName,
         final SqlQuery qry, final IndexingQueryFilter filter, final boolean keepBinary) throws IgniteCheckedException {
         String type = qry.getType();
         String sqlQry = qry.getSql();
@@ -1107,7 +1108,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
 
         GridQueryCancel cancel = new GridQueryCancel();
 
-        final GridCloseableIterator<IgniteBiTuple<K, V>> i = queryLocalSql(schemaName, sqlQry, alias,
+        final GridCloseableIterator<IgniteBiTuple<K, V>> i = queryLocalSql(schemaName, cacheName, sqlQry, alias,
             F.asList(params), type, filter, cancel);
 
         return new QueryCursorImpl<>(new Iterable<Cache.Entry<K, V>>() {
@@ -1142,19 +1143,19 @@ public class IgniteH2Indexing implements GridQueryIndexing {
      * Executes regular query.
      *
      * @param schemaName Schema name.
+     * @param cacheName Cache name.
      * @param qry Query.
      * @param alias Table alias.
      * @param params Query parameters.
      * @param type Query return type.
-     * @param filter Cache name and key filter.
-     * @return Queried rows.
+     * @param filter Cache name and key filter.      @return Queried rows.
      * @throws IgniteCheckedException If failed.
      */
     @SuppressWarnings("unchecked")
-    public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalSql(String schemaName,
+    public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalSql(String schemaName, String cacheName,
         final String qry, String alias, @Nullable final Collection<Object> params, String type,
         final IndexingQueryFilter filter, GridQueryCancel cancel) throws IgniteCheckedException {
-        final H2TableDescriptor tbl = tableDescriptor(schemaName, type);
+        final H2TableDescriptor tbl = tableDescriptor(schemaName, cacheName, type);
 
         if (tbl == null)
             throw new IgniteSQLException("Failed to find SQL table for type: " + type,
@@ -1216,11 +1217,11 @@ public class IgniteH2Indexing implements GridQueryIndexing {
 
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
-    @Override public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, SqlQuery qry,
-        boolean keepBinary, int mainCacheId) {
+    @Override public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, String cacheName,
+        SqlQuery qry, boolean keepBinary, int mainCacheId) {
         String type = qry.getType();
 
-        H2TableDescriptor tblDesc = tableDescriptor(schemaName, type);
+        H2TableDescriptor tblDesc = tableDescriptor(schemaName, cacheName, type);
 
         if (tblDesc == null)
             throw new IgniteSQLException("Failed to find SQL table for type: " + type,
@@ -1829,13 +1830,13 @@ public class IgniteH2Indexing implements GridQueryIndexing {
      * @param type Type name.
      * @return Descriptor.
      */
-    @Nullable private H2TableDescriptor tableDescriptor(String schemaName, String type) {
+    @Nullable private H2TableDescriptor tableDescriptor(String schemaName, String cacheName, String type) {
         H2Schema schema = schemas.get(schemaName);
 
         if (schema == null)
             return null;
 
-        return schema.tableByTypeName(type);
+        return schema.tableByTypeName(cacheName, type);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
index affd903..f39e587 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
@@ -62,6 +62,7 @@ import org.h2.table.Column;
 import org.h2.value.DataType;
 
 import static org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.UPDATE_RESULT_META;
+import static org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser.PARAM_WRAP_VALUE;
 
 /**
  * DDL statements processor.<p>
@@ -227,6 +228,10 @@ public class DdlStatementsProcessor {
                             cmd.tableName());
                 }
                 else {
+                    if (QueryUtils.isSqlType(tbl.rowDescriptor().type().valueClass()))
+                        throw new SchemaOperationException("Cannot add column(s) because table was created " +
+                            "with " + PARAM_WRAP_VALUE + "=false option.");
+
                     List<QueryField> cols = new ArrayList<>(cmd.columns().length);
 
                     boolean allFieldsNullable = true;
@@ -373,11 +378,38 @@ public class DdlStatementsProcessor {
         if (!F.isEmpty(createTbl.valueTypeName()))
             valTypeName = createTbl.valueTypeName();
 
+        assert createTbl.wrapKey() != null;
+        assert createTbl.wrapValue() != null;
+
+        if (!createTbl.wrapKey()) {
+            GridSqlColumn pkCol = createTbl.columns().get(createTbl.primaryKeyColumns().iterator().next());
+
+            keyTypeName = DataType.getTypeClassName(pkCol.column().getType());
+
+            res.setKeyFieldName(pkCol.columnName());
+        }
+        else
+            res.setKeyFields(createTbl.primaryKeyColumns());
+
+        if (!createTbl.wrapValue()) {
+            GridSqlColumn valCol = null;
+
+            for (Map.Entry<String, GridSqlColumn> e : createTbl.columns().entrySet()) {
+                if (!createTbl.primaryKeyColumns().contains(e.getKey())) {
+                    valCol = e.getValue();
+
+                    break;
+                }
+            }
+
+            valTypeName = DataType.getTypeClassName(valCol.column().getType());
+
+            res.setValueFieldName(valCol.columnName());
+        }
+
         res.setValueType(valTypeName);
         res.setKeyType(keyTypeName);
 
-        res.setKeyFields(createTbl.primaryKeyColumns());
-
         if (!F.isEmpty(notNullFields)) {
             QueryEntityEx res0 = new QueryEntityEx(res);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java
index b73214f..de10826 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlCreateTable.java
@@ -71,6 +71,12 @@ public class GridSqlCreateTable extends GridSqlStatement {
     /** Name of the column that represents affinity key. */
     private String affinityKey;
 
+    /** Forcefully turn single column PK into an Object. */
+    private Boolean wrapKey;
+
+    /** Forcefully turn single column value into an Object. */
+    private Boolean wrapVal;
+
     /** Extra WITH-params. */
     private List<String> params;
 
@@ -271,6 +277,34 @@ public class GridSqlCreateTable extends GridSqlStatement {
     }
 
     /**
+     * @return Forcefully turn single column PK into an Object.
+     */
+    public Boolean wrapKey() {
+        return wrapKey;
+    }
+
+    /**
+     * @param wrapKey Forcefully turn single column PK into an Object.
+     */
+    public void wrapKey(boolean wrapKey) {
+        this.wrapKey = wrapKey;
+    }
+
+    /**
+     * @return Forcefully turn single column value into an Object.
+     */
+    public Boolean wrapValue() {
+        return wrapVal;
+    }
+
+    /**
+     * @param wrapVal Forcefully turn single column value into an Object..
+     */
+    public void wrapValue(boolean wrapVal) {
+        this.wrapVal = wrapVal;
+    }
+
+    /**
      * @return Extra WITH-params.
      */
     public List<String> params() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
index 3d7a1a0..bf72200 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
@@ -475,6 +475,12 @@ public class GridSqlQueryParser {
     private static final String PARAM_VAL_TYPE = "VALUE_TYPE";
 
     /** */
+    private static final String PARAM_WRAP_KEY = "WRAP_KEY";
+
+    /** */
+    public static final String PARAM_WRAP_VALUE = "WRAP_VALUE";
+
+    /** */
     private final IdentityHashMap<Object, Object> h2ObjToGridObj = new IdentityHashMap<>();
 
     /** */
@@ -1007,7 +1013,8 @@ public class GridSqlQueryParser {
             pkCols.add(gridCol.columnName());
         }
 
-        int valColsNum = cols.size() - pkCols.size();
+        int keyColsNum = pkCols.size();
+        int valColsNum = cols.size() - keyColsNum;
 
         if (valColsNum == 0)
             throw new IgniteSQLException("Table must have at least one non PRIMARY KEY column.",
@@ -1052,6 +1059,44 @@ public class GridSqlQueryParser {
                 processExtraParam(e.getKey(), e.getValue(), res);
         }
 
+        // Process key wrapping.
+        Boolean wrapKey = res.wrapKey();
+
+        if (wrapKey != null && !wrapKey) {
+            if (keyColsNum > 1) {
+                throw new IgniteSQLException(PARAM_WRAP_KEY + " cannot be false when composite primary key exists.",
+                    IgniteQueryErrorCode.PARSING);
+            }
+
+            if (!F.isEmpty(res.keyTypeName())) {
+                throw new IgniteSQLException(PARAM_WRAP_KEY + " cannot be false when " + PARAM_KEY_TYPE + " is set.",
+                    IgniteQueryErrorCode.PARSING);
+            }
+        }
+
+        boolean wrapKey0 = (res.wrapKey() != null && res.wrapKey()) || !F.isEmpty(res.keyTypeName()) || keyColsNum > 1;
+
+        res.wrapKey(wrapKey0);
+
+        // Process value wrapping.
+        Boolean wrapVal = res.wrapValue();
+
+        if (wrapVal != null && !wrapVal) {
+            if (valColsNum > 1) {
+                throw new IgniteSQLException(PARAM_WRAP_VALUE + " cannot be false when multiple non-primary key " +
+                    "columns exist.", IgniteQueryErrorCode.PARSING);
+            }
+
+            if (!F.isEmpty(res.valueTypeName())) {
+                throw new IgniteSQLException(PARAM_WRAP_VALUE + " cannot be false when " + PARAM_VAL_TYPE + " is set.",
+                    IgniteQueryErrorCode.PARSING);
+            }
+
+            res.wrapValue(false);
+        }
+        else
+            res.wrapValue(true); // By default value is always wrapped to allow for ALTER TABLE ADD COLUMN commands.
+
         if (!F.isEmpty(res.valueTypeName()) && F.eq(res.keyTypeName(), res.valueTypeName()))
             throw new IgniteSQLException("Key and value type names " +
                 "should be different for CREATE TABLE: " + res.valueTypeName(), IgniteQueryErrorCode.PARSING);
@@ -1336,6 +1381,17 @@ public class GridSqlQueryParser {
 
                 break;
 
+            case PARAM_WRAP_KEY: {
+                res.wrapKey(F.isEmpty(val) || Boolean.parseBoolean(val));
+
+                break;
+            }
+
+            case PARAM_WRAP_VALUE:
+                res.wrapValue(F.isEmpty(val) || Boolean.parseBoolean(val));
+
+                break;
+
             default:
                 throw new IgniteSQLException("Unsupported parameter: " + name, IgniteQueryErrorCode.PARSING);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java
index 969c985..3d4b2a3 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java
@@ -82,7 +82,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
     private static final String ATTR_FILTERED = "FILTERED";
 
     /** SQL statement to create test table accompanied by template specification. */
-    private static final String CREATE_SQL_WITH_TEMPLATE = CREATE_SQL + " WITH \"template=TPL\"";
+    private final String createSql;
 
     /** Latches to block certain index operations. */
     private static final ConcurrentHashMap<UUID, T3<CountDownLatch, AtomicBoolean, CountDownLatch>> BLOCKS =
@@ -103,6 +103,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
     DynamicColumnsAbstractConcurrentSelfTest(CacheMode cacheMode, CacheAtomicityMode atomicityMode) {
         this.cacheMode = cacheMode;
         this.atomicityMode = atomicityMode;
+        createSql =  CREATE_SQL + " WITH \"template=TPL\"";
     }
 
     /** {@inheritDoc} */
@@ -158,7 +159,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
 
         createSqlCache(cli);
 
-        run(cli, CREATE_SQL_WITH_TEMPLATE);
+        run(cli, createSql);
 
         // Test migration between normal servers.
         CountDownLatch idxLatch = blockIndexing(srv1Id);
@@ -210,7 +211,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
 
         createSqlCache(srv1);
 
-        run(srv1, CREATE_SQL_WITH_TEMPLATE);
+        run(srv1, createSql);
 
         CountDownLatch idxLatch = blockIndexing(srv1);
 
@@ -253,7 +254,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
 
         createSqlCache(srv1);
 
-        run(srv1, CREATE_SQL_WITH_TEMPLATE);
+        run(srv1, createSql);
 
         CountDownLatch idxLatch = blockIndexing(srv1);
 
@@ -296,7 +297,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
 
         createSqlCache(srv1);
 
-        run(srv1, CREATE_SQL_WITH_TEMPLATE);
+        run(srv1, createSql);
 
         // Start data change operations from several threads.
         final AtomicBoolean stopped = new AtomicBoolean();
@@ -309,7 +310,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
                     int key = ThreadLocalRandom.current().nextInt(0, LARGE_CACHE_SIZE);
                     int val = ThreadLocalRandom.current().nextInt();
 
-                    IgniteCache<BinaryObject, BinaryObject> cache = node.cache(CACHE_NAME);
+                    IgniteCache<Object, BinaryObject> cache = node.cache(CACHE_NAME);
 
                     if (ThreadLocalRandom.current().nextBoolean())
                         cache.put(key(node, key), val(node, val));
@@ -342,15 +343,15 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
         // Get expected values.
         Set<Integer> expKeys = new HashSet<>();
 
-        IgniteCache<BinaryObject, BinaryObject> cache = srv1.cache(CACHE_NAME).withKeepBinary();
+        IgniteCache<Object, BinaryObject> cache = srv1.cache(CACHE_NAME).withKeepBinary();
 
         for (int i = 0; i < LARGE_CACHE_SIZE; i++) {
-            BinaryObject key = key(srv1, i);
+            Object key = key(srv1, i);
 
             BinaryObject val = cache.get(key);
 
             if (val != null) {
-                int id = key.field("ID");
+                int id = (Integer)key;
 
                 assertEquals(i, id);
 
@@ -363,17 +364,17 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
 
         // Validate query result.
         for (Ignite node : Ignition.allGrids()) {
-            IgniteCache<BinaryObject, BinaryObject> nodeCache = node.cache(CACHE_NAME).withKeepBinary();
+            IgniteCache<Object, BinaryObject> nodeCache = node.cache(CACHE_NAME).withKeepBinary();
 
             SqlQuery qry = new SqlQuery(valTypeName, "from " + TBL_NAME + " where mod(id, 2) <> 0");
 
-            List<Cache.Entry<BinaryObject, BinaryObject>> res = nodeCache.query(qry).getAll();
+            List<Cache.Entry<Object, BinaryObject>> res = nodeCache.query(qry).getAll();
 
             assertEquals("Cache size mismatch [exp=" + expKeys.size() + ", actual=" + res.size() + ']',
                 expKeys.size(), res.size());
 
-            for (Cache.Entry<BinaryObject, BinaryObject> entry : res) {
-                int key = entry.getKey().field("ID");
+            for (Cache.Entry<Object, BinaryObject> entry : res) {
+                int key = (Integer)entry.getKey();
                 int v = entry.getValue().field("v");
 
                 String name = entry.getValue().field("NAME");
@@ -399,13 +400,11 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
 
     /**
      * @param node Node.
-     * @param key Value for ID field.
-     * @return PERSON cache key.
+     * @param id Key.
+     * @return PERSON cache key (int or {@link BinaryObject}).
      */
-    private BinaryObject key(Ignite node, int key) {
-        String keyTypeName = ((IgniteEx)node).context().query().types(CACHE_NAME).iterator().next().keyTypeName();
-
-        return node.binary().builder(keyTypeName).setField("ID", key).build();
+    private Object key(Ignite node, int id) {
+        return id;
     }
 
     /**
@@ -420,7 +419,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
 
         createSqlCache(srv1);
 
-        run(srv1, CREATE_SQL_WITH_TEMPLATE);
+        run(srv1, createSql);
 
         awaitPartitionMapExchange();
 
@@ -481,7 +480,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
         // Start cache and populate it with data.
         createSqlCache(cli);
 
-        run(cli, CREATE_SQL_WITH_TEMPLATE);
+        run(cli, createSql);
 
         put(cli, 0, LARGE_CACHE_SIZE);
 
@@ -526,7 +525,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
 
         createSqlCache(cli);
 
-        run(cli, CREATE_SQL_WITH_TEMPLATE);
+        run(cli, createSql);
 
         put(cli, 0, 5000);
 
@@ -539,8 +538,8 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
                 while (!stopped.get()) {
                     Ignite node = grid(ThreadLocalRandom.current().nextInt(1, 5));
 
-                    IgniteInternalFuture fut = addCols(node, QueryUtils.DFLT_SCHEMA, c("newCol" + dynColCnt.getAndIncrement(),
-                        Integer.class.getName()));
+                    IgniteInternalFuture fut = addCols(node, QueryUtils.DFLT_SCHEMA, c("newCol" +
+                        dynColCnt.getAndIncrement(), Integer.class.getName()));
 
                     try {
                         fut.get();
@@ -641,7 +640,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
         if (dynamicCache) {
             createSqlCache(cli);
 
-            run(cli, CREATE_SQL_WITH_TEMPLATE);
+            run(cli, createSql);
         }
 
         final String schemaName = dynamicCache ? QueryUtils.DFLT_SCHEMA : "idx";
@@ -677,7 +676,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
                     if (dynamicCache) {
                         DynamicColumnsAbstractConcurrentSelfTest.this.run(srvNode, DROP_SQL);
 
-                        DynamicColumnsAbstractConcurrentSelfTest.this.run(srvNode, CREATE_SQL_WITH_TEMPLATE);
+                        DynamicColumnsAbstractConcurrentSelfTest.this.run(srvNode, createSql);
                     }
                     else {
                         srvNode.destroyCache("idx");
@@ -724,7 +723,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
 
         createSqlCache(cli);
 
-        run(cli, CREATE_SQL_WITH_TEMPLATE);
+        run(cli, createSql);
 
         final AtomicBoolean stopped = new AtomicBoolean();
 
@@ -783,8 +782,8 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo
                 while (!stopped.get()) {
                     Ignite node = grid(ThreadLocalRandom.current().nextInt(1, 5));
 
-                    IgniteInternalFuture fut = addCols(node, QueryUtils.DFLT_SCHEMA, c("newCol" + dynColCnt.getAndIncrement(),
-                        Integer.class.getName()));
+                    IgniteInternalFuture fut = addCols(node, QueryUtils.DFLT_SCHEMA, c("newCol" +
+                        dynColCnt.getAndIncrement(), Integer.class.getName()));
 
                     try {
                         fut.get();

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicPartitionedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicPartitionedSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicPartitionedSelfTest.java
index ca68903..3f65fca 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicPartitionedSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicPartitionedSelfTest.java
@@ -21,7 +21,7 @@ import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
 
 /**
- * Test to check concurrent operations on dynamic columns on ATOMIC PARTITIONED cache.
+ * Test to check concurrent operations on dynamic columns on ATOMIC PARTITIONED cache with flat key.
  */
 public class DynamicColumnsConcurrentAtomicPartitionedSelfTest extends DynamicColumnsAbstractConcurrentSelfTest {
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicReplicatedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicReplicatedSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicReplicatedSelfTest.java
index 9a3a32c..289a01e 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicReplicatedSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentAtomicReplicatedSelfTest.java
@@ -21,7 +21,7 @@ import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
 
 /**
- * Test to check concurrent operations on dynamic columns on ATOMIC REPLICATED cache.
+ * Test to check concurrent operations on dynamic columns on ATOMIC REPLICATED cache with flat key.
  */
 public class DynamicColumnsConcurrentAtomicReplicatedSelfTest extends DynamicColumnsAbstractConcurrentSelfTest {
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalPartitionedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalPartitionedSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalPartitionedSelfTest.java
index f42a447..371313e 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalPartitionedSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalPartitionedSelfTest.java
@@ -21,7 +21,7 @@ import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
 
 /**
- * Test to check concurrent operations on dynamic columns on TRANSACTIONAL PARTITIONED cache.
+ * Test to check concurrent operations on dynamic columns on TRANSACTIONAL PARTITIONED cache with flat key.
  */
 public class DynamicColumnsConcurrentTransactionalPartitionedSelfTest extends DynamicColumnsAbstractConcurrentSelfTest {
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalReplicatedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalReplicatedSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalReplicatedSelfTest.java
index 2b53e42..f004b89 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalReplicatedSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsConcurrentTransactionalReplicatedSelfTest.java
@@ -21,9 +21,10 @@ import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
 
 /**
- * Test to check concurrent operations on dynamic columns on TRANSACTIONAL REPLICATED cache.
+ * Test to check concurrent operations on dynamic columns on TRANSACTIONAL REPLICATED cache with flat key.
  */
-public class DynamicColumnsConcurrentTransactionalReplicatedSelfTest extends DynamicColumnsAbstractConcurrentSelfTest {
+public class DynamicColumnsConcurrentTransactionalReplicatedSelfTest
+    extends DynamicColumnsAbstractConcurrentSelfTest {
     /**
      * Constructor.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
index 5e64959..34be34d 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
@@ -302,6 +302,50 @@ public abstract class H2DynamicColumnsAbstractBasicSelfTest extends DynamicColum
     }
 
     /**
+     * Test that {@code ADD COLUMN} fails for non dynamic table that has flat value.
+     */
+    @SuppressWarnings({"unchecked", "ThrowFromFinallyBlock"})
+    public void testTestAlterTableOnFlatValueNonDynamicTable() {
+        CacheConfiguration c =
+            new CacheConfiguration("ints").setIndexedTypes(Integer.class, Integer.class)
+                .setSqlSchema(QueryUtils.DFLT_SCHEMA);
+
+        try {
+            grid(nodeIndex()).getOrCreateCache(c);
+
+            doTestAlterTableOnFlatValue("INTEGER");
+        }
+        finally {
+            grid(nodeIndex()).destroyCache("ints");
+        }
+    }
+
+    /**
+     * Test that {@code ADD COLUMN} fails for dynamic table that has flat value.
+     */
+    @SuppressWarnings({"unchecked", "ThrowFromFinallyBlock"})
+    public void testTestAlterTableOnFlatValueDynamicTable() {
+        try {
+            run("CREATE TABLE TEST (id int primary key, x varchar) with \"wrap_value=false\"");
+
+            doTestAlterTableOnFlatValue("TEST");
+        }
+        finally {
+            run("DROP TABLE TEST");
+        }
+    }
+
+    /**
+     * Test that {@code ADD COLUMN} fails for tables that have flat value.
+     * @param tblName table name.
+     */
+    private void doTestAlterTableOnFlatValue(String tblName) {
+        assertThrows("ALTER TABLE " + tblName + " ADD COLUMN y varchar",
+            "ADD COLUMN is not supported for tables created with wrap_value=false param. " +
+                "(To enable ADD COLUMN, create table with wrap_value=true param).");
+    }
+
+    /**
      * @return Node index to run queries on.
      */
     protected abstract int nodeIndex();

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java
index 773e7e0..e0ab6c5 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicTableSelfTest.java
@@ -17,6 +17,11 @@
 
 package org.apache.ignite.internal.processors.cache.index;
 
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -59,6 +64,7 @@ import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.h2.jdbc.JdbcSQLException;
+import org.h2.value.DataType;
 
 /**
  * Tests for CREATE/DROP TABLE.
@@ -285,6 +291,14 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
     }
 
     /**
+     * Test that {@code CREATE TABLE} with given write sync mode actually creates new cache as needed.
+     * @throws Exception if failed.
+     */
+    public void testPlainKey() throws Exception {
+        doTestCreateTable(null, null, null, CacheWriteSynchronizationMode.FULL_SYNC);
+    }
+
+    /**
      * Test that appending supplied arguments to {@code CREATE TABLE} results in creating new cache that has settings
      * as expected
      * @param cacheName Cache name, or {@code null} if the name generated by default should be used.
@@ -292,18 +306,19 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
      * @param valTypeName Value type name, or {@code null} if the name generated by default should be used.
      */
     private void doTestCustomNames(String cacheName, String keyTypeName, String valTypeName) {
-        GridStringBuilder b = new GridStringBuilder("CREATE TABLE \"NameTest\" (id int primary key, x varchar) WITH ");
+        GridStringBuilder b = new GridStringBuilder("CREATE TABLE \"NameTest\" (id int primary key, x varchar) WITH " +
+            "wrap_key,wrap_value");
 
         assert !F.isEmpty(cacheName) || !F.isEmpty(keyTypeName) || !F.isEmpty(valTypeName);
 
         if (!F.isEmpty(cacheName))
-            b.a("\"cache_name=").a(cacheName).a('"').a(',');
+            b.a(",\"cache_name=").a(cacheName).a('"');
 
         if (!F.isEmpty(keyTypeName))
-            b.a("\"key_type=").a(keyTypeName).a('"').a(',');
+            b.a(",\"key_type=").a(keyTypeName).a('"');
 
         if (!F.isEmpty(valTypeName))
-            b.a("\"value_type=").a(valTypeName).a('"');
+            b.a(",\"value_type=").a(valTypeName).a('"');
 
         String res = b.toString();
 
@@ -312,8 +327,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
 
         execute(client(), res);
 
-        String resCacheName = U.firstNotNull(cacheName, QueryUtils.createTableCacheName(QueryUtils.DFLT_SCHEMA,
-            "NameTest"));
+        String resCacheName = U.firstNotNull(cacheName, cacheName("NameTest"));
 
         IgniteInternalCache<BinaryObject, BinaryObject> cache = client().cachex(resCacheName);
 
@@ -770,7 +784,8 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
      * @throws Exception if failed.
      */
     public void testAffinityKey() throws Exception {
-        execute("CREATE TABLE \"City\" (\"name\" varchar primary key, \"code\" int) WITH \"affinityKey='name'\"");
+        execute("CREATE TABLE \"City\" (\"name\" varchar primary key, \"code\" int) WITH wrap_key,wrap_value," +
+            "\"affinityKey='name'\"");
 
         assertAffinityCacheConfiguration("City", "name");
 
@@ -783,7 +798,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
         // We need unique name for this table to avoid conflicts with existing binary metadata.
         execute("CREATE TABLE \"Person2\" (\"id\" int, \"city\" varchar," +
             " \"name\" varchar, \"surname\" varchar, \"age\" int, PRIMARY KEY (\"id\", \"city\")) WITH " +
-            "\"template=cache,affinityKey='city'\"");
+            "wrap_key,wrap_value,\"template=cache,affinityKey='city'\"");
 
         assertAffinityCacheConfiguration("Person2", "city");
 
@@ -828,26 +843,31 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
      */
     @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
     public void testAffinityKeyCaseSensitivity() {
-        execute("CREATE TABLE \"A\" (\"name\" varchar primary key, \"code\" int) WITH \"affinityKey='name'\"");
+        execute("CREATE TABLE \"A\" (\"name\" varchar primary key, \"code\" int) WITH wrap_key,wrap_value," +
+            "\"affinityKey='name'\"");
 
         assertAffinityCacheConfiguration("A", "name");
 
-        execute("CREATE TABLE \"B\" (name varchar primary key, \"code\" int) WITH \"affinityKey=name\"");
+        execute("CREATE TABLE \"B\" (name varchar primary key, \"code\" int) WITH wrap_key,wrap_value," +
+            "\"affinityKey=name\"");
 
         assertAffinityCacheConfiguration("B", "NAME");
 
-        execute("CREATE TABLE \"C\" (name varchar primary key, \"code\" int) WITH \"affinityKey=NamE\"");
+        execute("CREATE TABLE \"C\" (name varchar primary key, \"code\" int) WITH wrap_key,wrap_value," +
+            "\"affinityKey=NamE\"");
 
         assertAffinityCacheConfiguration("C", "NAME");
 
-        execute("CREATE TABLE \"D\" (\"name\" varchar primary key, \"code\" int) WITH \"affinityKey=NAME\"");
+        execute("CREATE TABLE \"D\" (\"name\" varchar primary key, \"code\" int) WITH wrap_key,wrap_value," +
+            "\"affinityKey=NAME\"");
 
         assertAffinityCacheConfiguration("D", "name");
 
         // Error arises because user has specified case sensitive affinity column name
         GridTestUtils.assertThrows(null, new Callable<Object>() {
             @Override public Object call() throws Exception {
-                execute("CREATE TABLE \"E\" (name varchar primary key, \"code\" int) WITH \"affinityKey='Name'\"");
+                execute("CREATE TABLE \"E\" (name varchar primary key, \"code\" int) WITH wrap_key,wrap_value," +
+                    "\"affinityKey='Name'\"");
 
                 return null;
             }
@@ -865,9 +885,19 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
         }, IgniteSQLException.class, "Ambiguous affinity column name, use single quotes for case sensitivity: name");
 
         execute("CREATE TABLE \"E\" (\"name\" varchar, \"Name\" int, val int, primary key(\"name\", " +
-            "\"Name\")) WITH \"affinityKey='Name'\"");
+            "\"Name\")) WITH wrap_key,wrap_value,\"affinityKey='Name'\"");
 
         assertAffinityCacheConfiguration("E", "Name");
+
+        execute("drop table a");
+
+        execute("drop table b");
+
+        execute("drop table c");
+
+        execute("drop table d");
+
+        execute("drop table e");
     }
 
     /**
@@ -914,7 +944,7 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
         execute("create index on \"PUBLIC\".t (b desc)");
         execute("drop table \"PUBLIC\".t");
 
-        assertNull(client().cache("t"));
+        assertNull(client().cache(cacheName("t")));
 
         execute("create table \"PUBLIC\".t (a int primary key, b varchar(30))");
 
@@ -944,6 +974,224 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
     }
 
     /**
+     * Test that it's impossible to create tables with same name regardless of key/value wrapping settings.
+     */
+    public void testWrappedAndUnwrappedKeyTablesInteroperability() {
+        {
+            execute("create table a (id int primary key, x varchar)");
+
+            assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_key",
+                "Table already exists: A");
+
+            assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_value",
+                "Table already exists: A");
+
+            assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_key,wrap_value",
+                "Table already exists: A");
+
+            execute("drop table a");
+        }
+
+        {
+            execute("create table a (id int primary key, x varchar) with wrap_key");
+
+            assertDdlCommandThrows("create table a (id int primary key, x varchar)",
+                "Table already exists: A");
+
+            assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_value",
+                "Table already exists: A");
+
+            assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_key,wrap_value",
+                "Table already exists: A");
+
+            execute("drop table a");
+        }
+
+        {
+            execute("create table a (id int primary key, x varchar) with wrap_value");
+
+            assertDdlCommandThrows("create table a (id int primary key, x varchar)",
+                "Table already exists: A");
+
+            assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_key",
+                "Table already exists: A");
+
+            assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_key,wrap_value",
+                "Table already exists: A");
+
+            execute("drop table a");
+        }
+
+        {
+            execute("create table a (id int primary key, x varchar) with wrap_key,wrap_value");
+
+            assertDdlCommandThrows("create table a (id int primary key, x varchar)",
+                "Table already exists: A");
+
+            assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_value",
+                "Table already exists: A");
+
+            assertDdlCommandThrows("create table a (id int primary key, x varchar) with wrap_key",
+                "Table already exists: A");
+
+            execute("drop table a");
+        }
+    }
+
+    /**
+     * Test that it's possible to create tables with matching key and/or value primitive types.
+     */
+    public void testDynamicTablesInteroperability() {
+        execute("create table a (id int primary key, x varchar) with \"wrap_value=false\"");
+
+        execute("create table b (id long primary key, y varchar) with \"wrap_value=false\"");
+
+        execute("create table c (id int primary key, z long) with \"wrap_value=false\"");
+
+        execute("create table d (id int primary key, w varchar) with \"wrap_value=false\"");
+
+        execute("drop table a");
+
+        execute("drop table b");
+
+        execute("drop table c");
+
+        execute("drop table d");
+    }
+
+    /**
+     * Test that when key or value has more than one column, wrap=false is forbidden.
+     */
+    public void testWrappingAlwaysOnWithComplexObjects() {
+        assertDdlCommandThrows("create table a (id int, x varchar, c long, primary key(id, c)) with \"wrap_key=false\"",
+            "WRAP_KEY cannot be false when composite primary key exists.");
+
+        assertDdlCommandThrows("create table a (id int, x varchar, c long, primary key(id)) with \"wrap_value=false\"",
+            "WRAP_VALUE cannot be false when multiple non-primary key columns exist.");
+    }
+
+    /**
+     * Test behavior when neither key nor value should be wrapped.
+     * @throws SQLException if failed.
+     */
+    public void testNoWrap() throws SQLException {
+        doTestKeyValueWrap(false, false);
+    }
+
+    /**
+     * Test behavior when only key is wrapped.
+     * @throws SQLException if failed.
+     */
+    public void testKeyWrap() throws SQLException {
+        doTestKeyValueWrap(true, false);
+    }
+
+    /**
+     * Test behavior when only value is wrapped.
+     * @throws SQLException if failed.
+     */
+    public void testValueWrap() throws SQLException {
+        doTestKeyValueWrap(false, true);
+    }
+
+    /**
+     * Test behavior when both key and value is wrapped.
+     * @throws SQLException if failed.
+     */
+    public void testKeyAndValueWrap() throws SQLException {
+        doTestKeyValueWrap(true, true);
+    }
+
+    /**
+     * Test behavior for given combination of wrap flags.
+     * @param wrapKey Whether key wrap should be enforced.
+     * @param wrapVal Whether value wrap should be enforced.
+     * @throws SQLException if failed.
+     */
+    private void doTestKeyValueWrap(boolean wrapKey, boolean wrapVal) throws SQLException {
+        try {
+            String sql = String.format("CREATE TABLE T (\"id\" int primary key, \"x\" varchar) WITH " +
+                "\"wrap_key=%b,wrap_value=%b\"", wrapKey, wrapVal);
+
+            if (wrapKey)
+                sql += ",\"key_type=tkey\"";
+
+            if (wrapVal)
+                sql += ",\"value_type=tval\"";
+
+            execute(sql);
+
+            execute("INSERT INTO T(\"id\", \"x\") values(1, 'a')");
+
+            LinkedHashMap<String, String> resCols = new LinkedHashMap<>();
+
+            List<Object> resData = new ArrayList<>();
+
+            try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1")) {
+                try (ResultSet colsRs = conn.getMetaData().getColumns(null, QueryUtils.DFLT_SCHEMA, "T", ".*")) {
+                    while (colsRs.next())
+                        resCols.put(colsRs.getString("COLUMN_NAME"),
+                            DataType.getTypeClassName(DataType.convertSQLTypeToValueType(colsRs
+                                .getShort("DATA_TYPE"))));
+                }
+
+                try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM T")) {
+                    try (ResultSet dataRs = ps.executeQuery()) {
+                        assertTrue(dataRs.next());
+
+                        for (int i = 0; i < dataRs.getMetaData().getColumnCount(); i++)
+                            resData.add(dataRs.getObject(i + 1));
+                    }
+                }
+            }
+
+            LinkedHashMap<String, String> expCols = new LinkedHashMap<>();
+
+            expCols.put("id", Integer.class.getName());
+            expCols.put("x", String.class.getName());
+
+            assertEquals(expCols, resCols);
+
+            assertEqualsCollections(Arrays.asList(1, "a"), resData);
+
+            Object key = createKeyForWrapTest(1, wrapKey);
+
+            Object val = client().cache(cacheName("T")).withKeepBinary().get(key);
+
+            assertNotNull(val);
+
+            assertEquals(createValueForWrapTest("a", wrapVal), val);
+        }
+        finally {
+            execute("DROP TABLE IF EXISTS T");
+        }
+    }
+
+    /**
+     * @param key Key to wrap.
+     * @param wrap Whether key should be wrapped.
+     * @return (optionally wrapped) key.
+     */
+    private Object createKeyForWrapTest(int key, boolean wrap) {
+        if (!wrap)
+            return key;
+
+        return client().binary().builder("tkey").setField("id", key).build();
+    }
+
+    /**
+     * @param val Value to wrap.
+     * @param wrap Whether value should be wrapped.
+     * @return (optionally wrapped) value.
+     */
+    private Object createValueForWrapTest(String val, boolean wrap) {
+        if (!wrap)
+            return val;
+
+        return client().binary().builder("tval").setField("x", val).build();
+    }
+
+    /**
      * Fill re-created table with data.
      */
     private void fillRecreatedTable() {
@@ -1025,19 +1273,30 @@ public class H2DynamicTableSelfTest extends AbstractSchemaSelfTest {
     }
 
     /**
-     * Test that {@code DROP TABLE} on non-public schema causes an exception.
-     *
-     * @throws Exception if failed.
+     * Test that arbitrary command yields specific error.
+     * @param cmd Command.
+     * @param expErrMsg Expected error message.
      */
     @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
-    public void testDropTableNotPublicSchema() throws Exception {
+    private void assertDdlCommandThrows(final String cmd, String expErrMsg) {
         GridTestUtils.assertThrows(null, new Callable<Object>() {
             @Override public Object call() throws Exception {
-                execute("DROP TABLE \"cache_idx\".\"Person\"");
+                execute(cmd);
 
                 return null;
             }
-        }, IgniteSQLException.class, "DROP TABLE can only be executed on PUBLIC schema.");
+        }, IgniteSQLException.class, expErrMsg);
+    }
+
+    /**
+     * Test that {@code DROP TABLE} on non-public schema causes an exception.
+     *
+     * @throws Exception if failed.
+     */
+    @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+    public void testDropTableNotPublicSchema() throws Exception {
+       assertDdlCommandThrows("DROP TABLE \"cache_idx\".\"Person\"",
+           "DROP TABLE can only be executed on PUBLIC schema.");
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java
index b372eb3..8deb61f 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlNotNullConstraintTest.java
@@ -86,7 +86,7 @@ public class IgniteSqlNotNullConstraintTest extends GridCommonAbstractTest {
     private static String CACHE_INTERCEPTOR = "cacheInterceptor";
 
     /** Expected error message. */
-    private static String ERR_MSG = "Null value is not allowed for field 'NAME'";
+    private static String ERR_MSG = "Null value is not allowed for column 'NAME'";
 
     /** Expected error message for read-through restriction. */
     private static String READ_THROUGH_ERR_MSG = "NOT NULL constraint is not supported when " +

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
index 1ee8a84..62860c0 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
@@ -251,20 +251,21 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
 
         IgniteCache<Integer, BinaryObject> cacheB = ignite0.createCache(cacheBCfg());
 
-        assertFalse(spi.queryLocalSql(spi.schema(typeAA.cacheName()), "select * from A.A", null, Collections.emptySet(),
-            typeAA.name(), null, null).hasNext());
+        assertFalse(spi.queryLocalSql(spi.schema(typeAA.cacheName()), typeAA.cacheName(), "select * from A.A", null,
+            Collections.emptySet(), typeAA.name(), null, null).hasNext());
 
-        assertFalse(spi.queryLocalSql(spi.schema(typeAB.cacheName()), "select * from A.B", null, Collections.emptySet(),
-            typeAB.name(), null, null).hasNext());
-
-        assertFalse(spi.queryLocalSql(spi.schema(typeBA.cacheName()), "select * from B.A", null, Collections.emptySet(),
-            typeBA.name(), null, null).hasNext());
+        assertFalse(spi.queryLocalSql(spi.schema(typeAB.cacheName()), typeAB.cacheName(), "select * from A.B", null,
+            Collections.emptySet(), typeAB.name(), null, null).hasNext());
 
-        assertFalse(spi.queryLocalSql(spi.schema(typeBA.cacheName()), "select * from B.A, A.B, A.A", null,
+        assertFalse(spi.queryLocalSql(spi.schema(typeBA.cacheName()), typeBA.cacheName(), "select * from B.A", null,
             Collections.emptySet(), typeBA.name(), null, null).hasNext());
 
+        assertFalse(spi.queryLocalSql(spi.schema(typeBA.cacheName()), typeBA.cacheName(),
+            "select * from B.A, A.B, A.A", null, Collections.emptySet(), typeBA.name(), null, null).hasNext());
+
         try {
-            spi.queryLocalSql(spi.schema(typeBA.cacheName()), "select aa.*, ab.*, ba.* from A.A aa, A.B ab, B.A ba",
+            spi.queryLocalSql(spi.schema(typeBA.cacheName()), typeBA.cacheName(),
+                "select aa.*, ab.*, ba.* from A.A aa, A.B ab, B.A ba",
                 null, Collections.emptySet(), typeBA.name(), null, null).hasNext();
 
             fail("Enumerations of aliases in select block must be prohibited");
@@ -273,11 +274,11 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
             // all fine
         }
 
-        assertFalse(spi.queryLocalSql(spi.schema(typeAB.cacheName()), "select ab.* from A.B ab", null,
-            Collections.emptySet(), typeAB.name(), null, null).hasNext());
+        assertFalse(spi.queryLocalSql(spi.schema(typeAB.cacheName()), typeAB.cacheName(), "select ab.* from A.B ab",
+            null, Collections.emptySet(), typeAB.name(), null, null).hasNext());
 
-        assertFalse(spi.queryLocalSql(spi.schema(typeBA.cacheName()), "select   ba.*   from B.A  as ba", null,
-            Collections.emptySet(), typeBA.name(), null, null).hasNext());
+        assertFalse(spi.queryLocalSql(spi.schema(typeBA.cacheName()), typeBA.cacheName(),
+            "select   ba.*   from B.A  as ba", null, Collections.emptySet(), typeBA.name(), null, null).hasNext());
 
         cacheA.put(1, aa("A", 1, "Vasya", 10).build());
         cacheA.put(1, ab(1, "Vasya", 20, "Some text about Vasya goes here.").build());
@@ -289,7 +290,7 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
 
         // Query data.
         Iterator<IgniteBiTuple<Integer, BinaryObjectImpl>> res = spi.queryLocalSql(spi.schema(typeAA.cacheName()),
-            "from a order by age", null, Collections.emptySet(), typeAA.name(), null, null);
+            typeAA.cacheName(), "from a order by age", null, Collections.emptySet(), typeAA.name(), null, null);
 
         assertTrue(res.hasNext());
         assertEquals(aa("A", 3, "Borya", 18).build(), value(res.next()));
@@ -297,8 +298,8 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
         assertEquals(aa("A", 2, "Valera", 19).build(), value(res.next()));
         assertFalse(res.hasNext());
 
-        res = spi.queryLocalSql(spi.schema(typeAA.cacheName()), "select aa.* from a aa order by aa.age", null,
-            Collections.emptySet(), typeAA.name(), null, null);
+        res = spi.queryLocalSql(spi.schema(typeAA.cacheName()), typeAA.cacheName(),
+            "select aa.* from a aa order by aa.age", null, Collections.emptySet(), typeAA.name(), null, null);
 
         assertTrue(res.hasNext());
         assertEquals(aa("A", 3, "Borya", 18).build(), value(res.next()));
@@ -306,8 +307,8 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
         assertEquals(aa("A", 2, "Valera", 19).build(), value(res.next()));
         assertFalse(res.hasNext());
 
-        res = spi.queryLocalSql(spi.schema(typeAB.cacheName()), "from b order by name", null, Collections.emptySet(),
-            typeAB.name(), null, null);
+        res = spi.queryLocalSql(spi.schema(typeAB.cacheName()), typeAB.cacheName(), "from b order by name", null,
+            Collections.emptySet(), typeAB.name(), null, null);
 
         assertTrue(res.hasNext());
         assertEquals(ab(1, "Vasya", 20, "Some text about Vasya goes here.").build(), value(res.next()));
@@ -315,8 +316,8 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
         assertEquals(ab(4, "Vitalya", 20, "Very Good guy").build(), value(res.next()));
         assertFalse(res.hasNext());
 
-        res = spi.queryLocalSql(spi.schema(typeAB.cacheName()), "select bb.* from b as bb order by bb.name", null,
-            Collections.emptySet(), typeAB.name(), null, null);
+        res = spi.queryLocalSql(spi.schema(typeAB.cacheName()), typeAB.cacheName(),
+            "select bb.* from b as bb order by bb.name", null, Collections.emptySet(), typeAB.name(), null, null);
 
         assertTrue(res.hasNext());
         assertEquals(ab(1, "Vasya", 20, "Some text about Vasya goes here.").build(), value(res.next()));
@@ -324,8 +325,8 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
         assertEquals(ab(4, "Vitalya", 20, "Very Good guy").build(), value(res.next()));
         assertFalse(res.hasNext());
 
-        res = spi.queryLocalSql(spi.schema(typeBA.cacheName()), "from a", null, Collections.emptySet(), typeBA.name(),
-            null, null);
+        res = spi.queryLocalSql(spi.schema(typeBA.cacheName()), typeBA.cacheName(), "from a", null,
+            Collections.emptySet(), typeBA.name(), null, null);
 
         assertTrue(res.hasNext());
         assertEquals(ba(2, "Kolya", 25, true).build(), value(res.next()));
@@ -333,7 +334,7 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
 
         // Text queries
         Iterator<IgniteBiTuple<Integer, BinaryObjectImpl>> txtRes = spi.queryLocalText(spi.schema(typeAB.cacheName()),
-            "good", typeAB.name(), null);
+            typeAB.cacheName(), "good", typeAB.name(), null);
 
         assertTrue(txtRes.hasNext());
         assertEquals(ab(4, "Vitalya", 20, "Very Good guy").build(), value(txtRes.next()));

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d94cf4/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
index a6ddc8c..172cb90 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs
@@ -122,7 +122,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             var ex = Assert.Throws<IgniteException>(() => cache.QueryFields(new SqlFieldsQuery(
                 "insert into foo(_key, name) values (?, ?)", 1, "bar")).GetAll());
 
-            Assert.AreEqual("Null value is not allowed for field 'ID'", ex.Message);
+            Assert.AreEqual("Null value is not allowed for column 'ID'", ex.Message);
         }
 
         /// <summary>
@@ -137,7 +137,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             var ex = Assert.Throws<IgniteException>(() => cache.QueryFields(new SqlFieldsQuery(
                 "insert into foo(_key, id) values (?, ?)", 1, 2)).GetAll());
 
-            Assert.AreEqual("Null value is not allowed for field 'NAME'", ex.Message);
+            Assert.AreEqual("Null value is not allowed for column 'NAME'", ex.Message);
         }
 
         /// <summary>


[46/50] [abbrv] ignite git commit: IGNITE-5767 Web console: Use byte array type instead of java.lang.Object for binary JDBC types.

Posted by ag...@apache.org.
IGNITE-5767 Web console: Use byte array type instead of java.lang.Object for binary JDBC types.


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

Branch: refs/heads/ignite-6305
Commit: 31844374d516aea57364f716474c4a46b0098898
Parents: 90624c6
Author: Vasiliy Sisko <vs...@gridgain.com>
Authored: Mon Oct 9 17:55:23 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Oct 9 17:55:23 2017 +0700

----------------------------------------------------------------------
 .../frontend/app/helpers/jade/mixins.pug            |  9 +++------
 .../generator/ConfigurationGenerator.js             |  6 +++---
 .../modules/states/configuration/caches/store.pug   |  4 ++--
 .../states/configuration/clusters/attributes.pug    |  4 ++--
 .../clusters/collision/job-stealing.pug             |  4 ++--
 .../states/configuration/domains/general.pug        |  2 +-
 .../modules/states/configuration/domains/query.pug  |  8 ++++----
 .../frontend/app/services/JavaTypes.service.js      | 15 +++++++++++++++
 .../frontend/app/services/LegacyUtils.service.js    | 16 ++++++++++++----
 .../frontend/controllers/domains-controller.js      |  7 +++++--
 10 files changed, 49 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/31844374/modules/web-console/frontend/app/helpers/jade/mixins.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/mixins.pug b/modules/web-console/frontend/app/helpers/jade/mixins.pug
index 9ccbde2..3e39077 100644
--- a/modules/web-console/frontend/app/helpers/jade/mixins.pug
+++ b/modules/web-console/frontend/app/helpers/jade/mixins.pug
@@ -572,7 +572,7 @@ mixin btn-remove-cond(cond, click, tip)
     i.tipField.fa.fa-remove(ng-show=cond ng-click=click bs-tooltip=tip data-trigger='hover')
 
 //- LEGACY mixin for LEGACY pair values tables.
-mixin table-pair-edit(tbl, prefix, keyPlaceholder, valPlaceholder, keyJavaBuiltInTypes, valueJavaBuiltInTypes, focusId, index, divider)
+mixin table-pair-edit(tbl, prefix, keyPlaceholder, valPlaceholder, valueJavaBuiltInClasses, focusId, index, divider)
     -var keyModel = `${tbl}.${prefix}Key`
     -var valModel = `${tbl}.${prefix}Value`
 
@@ -582,10 +582,7 @@ mixin table-pair-edit(tbl, prefix, keyPlaceholder, valPlaceholder, keyJavaBuiltI
     .col-xs-6.col-sm-6.col-md-6
         .fieldSep !{divider}
         .input-tip
-            if keyJavaBuiltInTypes
-                input.form-control(id=keyFocusId ignite-on-enter-focus-move=valFocusId type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead container='body' ignite-retain-selection data-min-length='1' bs-options='javaClass for javaClass in javaBuiltInClasses' ignite-on-escape='tableReset(false)')
-            else
-                input.form-control(id=keyFocusId ignite-on-enter-focus-move=valFocusId type='text' ng-model=keyModel placeholder=keyPlaceholder ignite-on-escape='tableReset(false)')
+            input.form-control(id=keyFocusId ignite-on-enter-focus-move=valFocusId type='text' ng-model=keyModel placeholder=keyPlaceholder ignite-on-escape='tableReset(false)')
     .col-xs-6.col-sm-6.col-md-6
         -var btnVisible = 'tablePairSaveVisible(' + tbl + ', ' + index + ')'
         -var btnSave = 'tablePairSave(tablePairValid, backupItem, ' + tbl + ', ' + index + ')'
@@ -593,7 +590,7 @@ mixin table-pair-edit(tbl, prefix, keyPlaceholder, valPlaceholder, keyJavaBuiltI
 
         +btn-save(btnVisible, btnSave)
         .input-tip
-            if valueJavaBuiltInTypes
+            if valueJavaBuiltInClasses
                 input.form-control(id=valFocusId type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead container='body' ignite-retain-selection data-min-length='1' bs-options='javaClass for javaClass in javaBuiltInClasses' ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset(false)')
             else
                 input.form-control(id=valFocusId type='text' ng-model=valModel placeholder=valPlaceholder ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset(false)')

http://git-wip-us.apache.org/repos/asf/ignite/blob/31844374/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js b/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js
index 9d7887a..75ee47c 100644
--- a/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js
+++ b/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js
@@ -1681,7 +1681,7 @@ export default class IgniteConfigurationGenerator {
     static domainModelQuery(domain, available, cfg = this.domainConfigurationBean(domain)) {
         if (cfg.valueOf('queryMetadata') === 'Configuration') {
             const fields = _.filter(_.map(domain.fields,
-                (e) => ({name: e.name, className: javaTypes.fullClassName(e.className)})), (field) => {
+                (e) => ({name: e.name, className: javaTypes.stringClassName(e.className)})), (field) => {
                 return field.name !== domain.keyFieldName && field.name !== domain.valueFieldName;
             });
 
@@ -1695,10 +1695,10 @@ export default class IgniteConfigurationGenerator {
                 const valFieldName = cfg.valueOf('valueFieldName');
 
                 if (keyFieldName)
-                    fields.push({name: keyFieldName, className: javaTypes.fullClassName(domain.keyType)});
+                    fields.push({name: keyFieldName, className: javaTypes.stringClassName(domain.keyType)});
 
                 if (valFieldName)
-                    fields.push({name: valFieldName, className: javaTypes.fullClassName(domain.valueType)});
+                    fields.push({name: valFieldName, className: javaTypes.stringClassName(domain.valueType)});
             }
 
             cfg.collectionProperty('keyFields', 'keyFields', domain.queryKeyFields, 'java.lang.String', 'java.util.HashSet')

http://git-wip-us.apache.org/repos/asf/ignite/blob/31844374/modules/web-console/frontend/app/modules/states/configuration/caches/store.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/caches/store.pug b/modules/web-console/frontend/app/modules/states/configuration/caches/store.pug
index d6dcbbe..0c983a2 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/caches/store.pug
+++ b/modules/web-console/frontend/app/modules/states/configuration/caches/store.pug
@@ -194,11 +194,11 @@ mixin hibernateField(name, model, items, valid, save, newItem)
                                                             a.labelFormField(ng-click='tableStartEdit(backupItem, hibernatePropsTbl, $index)') {{item.name}} = {{item.value}}
                                                             +btn-remove('tableRemove(backupItem, hibernatePropsTbl, $index)', '"Remove Property"')
                                                         td.col-sm-12(ng-if='tableEditing(hibernatePropsTbl, $index)')
-                                                            +table-pair-edit('hibernatePropsTbl', 'cur', 'Property name', 'Property value', false, false, '{{::hibernatePropsTbl.focusId + $index}}', '$index', '=')
+                                                            +table-pair-edit('hibernatePropsTbl', 'cur', 'Property name', 'Property value', false, '{{::hibernatePropsTbl.focusId + $index}}', '$index', '=')
                                                 tfoot(ng-show='tableNewItemActive(hibernatePropsTbl)')
                                                     tr
                                                         td.col-sm-12
-                                                            +table-pair-edit('hibernatePropsTbl', 'new', 'Property name', 'Property value', false, false, '{{::hibernatePropsTbl.focusId + $index}}', '-1', '=')
+                                                            +table-pair-edit('hibernatePropsTbl', 'new', 'Property name', 'Property value', false, '{{::hibernatePropsTbl.focusId + $index}}', '-1', '=')
 
 
                 .settings-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/31844374/modules/web-console/frontend/app/modules/states/configuration/clusters/attributes.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/attributes.pug b/modules/web-console/frontend/app/modules/states/configuration/clusters/attributes.pug
index cac122b..beb0739 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/clusters/attributes.pug
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/attributes.pug
@@ -48,10 +48,10 @@ include /app/helpers/jade/mixins
                                             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', '=')
+                                            +table-pair-edit('attributesTbl', 'cur', 'Attribute name', 'Attribute value', 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', '=')
+                                            +table-pair-edit('attributesTbl', 'new', 'Attribute name', 'Attribute value', false, '{{::attributesTbl.focusId + $index}}', '-1', '=')
             .col-sm-6
                 +preview-xml-java(model, 'clusterUserAttributes')

http://git-wip-us.apache.org/repos/asf/ignite/blob/31844374/modules/web-console/frontend/app/modules/states/configuration/clusters/collision/job-stealing.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/collision/job-stealing.pug b/modules/web-console/frontend/app/modules/states/configuration/clusters/collision/job-stealing.pug
index d10a02e..eeb6114 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/clusters/collision/job-stealing.pug
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/collision/job-stealing.pug
@@ -56,8 +56,8 @@ div
                                 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', '=')
+                                +table-pair-edit('stealingAttributesTbl', 'cur', 'Attribute name', 'Attribute value', 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', '=')
+                                +table-pair-edit('stealingAttributesTbl', 'new', 'Attribute name', 'Attribute value', false, '{{::stealingAttributesTbl.focusId + $index}}', '-1', '=')

http://git-wip-us.apache.org/repos/asf/ignite/blob/31844374/modules/web-console/frontend/app/modules/states/configuration/domains/general.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/domains/general.pug b/modules/web-console/frontend/app/modules/states/configuration/domains/general.pug
index f6f4e72..7c8de9a 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/domains/general.pug
+++ b/modules/web-console/frontend/app/modules/states/configuration/domains/general.pug
@@ -44,7 +44,7 @@ include /app/helpers/jade/mixins
                             <li>Configuration via QueryEntity class</li>\
                         </ul>')
                 .settings-row
-                    +java-class-typeahead('Key type:', `${model}.keyType`, '"keyType"', 'javaBuiltInClasses', 'true', 'true', '{{ ' + generatePojo + ' ? "Full class name for Key" : "Key type name" }}', 'Key class used to store key in cache', generatePojo)
+                    +java-class-typeahead('Key type:', `${model}.keyType`, '"keyType"', 'javaBuiltInClassesBase', 'true', 'true', '{{ ' + generatePojo + ' ? "Full class name for Key" : "Key type name" }}', 'Key class used to store key in cache', generatePojo)
                 .settings-row
                     +java-class-autofocus-placholder('Value type:', `${model}.valueType`, '"valueType"', 'true', 'true', 'false', '{{ ' + generatePojo +' ? "Enter fully qualified class name" : "Value type name" }}', 'Value class used to store value in cache', generatePojo)
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/31844374/modules/web-console/frontend/app/modules/states/configuration/domains/query.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/domains/query.pug b/modules/web-console/frontend/app/modules/states/configuration/domains/query.pug
index e8eceac..b4b5abe 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/domains/query.pug
+++ b/modules/web-console/frontend/app/modules/states/configuration/domains/query.pug
@@ -95,11 +95,11 @@ mixin table-index-item-edit(prefix, index, sortAvailable, idAddition)
                                                 a.labelFormField(ng-click='tableStartEdit(backupItem, queryFieldsTbl, $index)') {{item.name}}  / {{item.className}}
                                                 +btn-remove('tableRemove(backupItem, queryFieldsTbl, $index)', '"Remove path"')
                                             td.col-sm-12(ng-show='tableEditing(queryFieldsTbl, $index)')
-                                                +table-pair-edit('queryFieldsTbl', 'cur', 'Field name', 'Field full class name', false, true, '{{::queryFieldsTbl.focusId + $index}}', '$index', '/')
+                                                +table-pair-edit('queryFieldsTbl', 'cur', 'Field name', 'Field full class name', true, '{{::queryFieldsTbl.focusId + $index}}', '$index', '/')
                                     tfoot(ng-show='tableNewItemActive(queryFieldsTbl)')
                                         tr
                                             td.col-sm-12
-                                                +table-pair-edit('queryFieldsTbl', 'new', 'Field name', 'Field full class name', false, true, '{{::queryFieldsTbl.focusId + $index}}', '-1', '/')
+                                                +table-pair-edit('queryFieldsTbl', 'new', 'Field name', 'Field full class name', true, '{{::queryFieldsTbl.focusId + $index}}', '-1', '/')
                     .settings-row
                         +ignite-form-field-dropdown('Key fields:', queryKeyFields, '"queryKeyFields"', false, false, true,
                             'Select key fields', 'Configure available fields', 'fields(\'cur\', ' + queryKeyFields + ')',
@@ -125,11 +125,11 @@ mixin table-index-item-edit(prefix, index, sortAvailable, idAddition)
                                                 a.labelFormField(ng-click='tableStartEdit(backupItem, aliasesTbl, $index)') {{item.field}} &rarr; {{item.alias}}
                                                 +btn-remove('tableRemove(backupItem, aliasesTbl, $index)', '"Remove alias"')
                                             td.col-sm-12(ng-show='tableEditing(aliasesTbl, $index)')
-                                                +table-pair-edit('aliasesTbl', 'cur', 'Field name', 'Field Alias', false, false, '{{::aliasesTbl.focusId + $index}}', '$index', '&rarr;')
+                                                +table-pair-edit('aliasesTbl', 'cur', 'Field name', 'Field Alias', false, '{{::aliasesTbl.focusId + $index}}', '$index', '&rarr;')
                                     tfoot(ng-show='tableNewItemActive(aliasesTbl)')
                                         tr
                                             td.col-sm-12
-                                                +table-pair-edit('aliasesTbl', 'new', 'Field name', 'Field Alias', false, false, '{{::aliasesTbl.focusId + $index}}', '-1', '&rarr;')
+                                                +table-pair-edit('aliasesTbl', 'new', 'Field name', 'Field Alias', false, '{{::aliasesTbl.focusId + $index}}', '-1', '&rarr;')
                     .settings-row(ng-init='indexesTbl={type: "table-indexes", model: "indexes", focusId: "IndexName", ui: "table-indexes"}')
                         +ignite-form-group(ng-model=queryIndexes ng-form=queryIndexesForm)
                             ignite-form-field-label

http://git-wip-us.apache.org/repos/asf/ignite/blob/31844374/modules/web-console/frontend/app/services/JavaTypes.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/services/JavaTypes.service.js b/modules/web-console/frontend/app/services/JavaTypes.service.js
index 944fea5..dff73a4 100644
--- a/modules/web-console/frontend/app/services/JavaTypes.service.js
+++ b/modules/web-console/frontend/app/services/JavaTypes.service.js
@@ -36,6 +36,9 @@ const VALID_PACKAGE = /^(([a-zA-Z_$][a-zA-Z0-9_$]*)\.)*([a-zA-Z_$][a-zA-Z0-9_$]*
 // Regular expression to check UUID string representation.
 const VALID_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/im;
 
+// Extended list of Java built-in class names.
+const JAVA_CLASS_STRINGS = JAVA_CLASSES.slice();
+
 /**
  * Utility service for various check on java types.
  */
@@ -45,6 +48,8 @@ export default class JavaTypes {
     constructor(clusterDflts, cacheDflts, igfsDflts) {
         this.enumClasses = _.uniq(this._enumClassesAcc(_.merge(clusterDflts, cacheDflts, igfsDflts), []));
         this.shortEnumClasses = _.map(this.enumClasses, (cls) => this.shortClassName(cls));
+
+        JAVA_CLASS_STRINGS.push({short: 'byte[]', full: 'byte[]', stringValue: '[B'});
     }
 
     /**
@@ -95,6 +100,16 @@ export default class JavaTypes {
     }
 
     /**
+     * @param clsName Class name to check.
+     * @returns {String} Full class name string presentation for java build-in types or source class otherwise.
+     */
+    stringClassName(clsName) {
+        const type = _.find(JAVA_CLASS_STRINGS, (clazz) => clsName === clazz.short);
+
+        return type ? type.stringValue || type.full : clsName;
+    }
+
+    /**
      * Extract class name from full class name.
      *
      * @param clsName full class name.

http://git-wip-us.apache.org/repos/asf/ignite/blob/31844374/modules/web-console/frontend/app/services/LegacyUtils.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/services/LegacyUtils.service.js b/modules/web-console/frontend/app/services/LegacyUtils.service.js
index e7c064b..be593b0 100644
--- a/modules/web-console/frontend/app/services/LegacyUtils.service.js
+++ b/modules/web-console/frontend/app/services/LegacyUtils.service.js
@@ -50,6 +50,7 @@ export default ['IgniteLegacyUtils', ['IgniteErrorPopover', (ErrorPopover) => {
         'boolean',
         'Boolean',
         'byte',
+        'byte[]',
         'Byte',
         'Date',
         'double',
@@ -88,13 +89,15 @@ export default ['IgniteLegacyUtils', ['IgniteErrorPopover', (ErrorPopover) => {
 
     /**
      * @param clsName Class name to check.
+     * @param additionalClasses List of classes to check as builtin.
      * @returns {Boolean} 'true' if given class name is a java build-in type.
      */
-    function isJavaBuiltInClass(clsName) {
+    function isJavaBuiltInClass(clsName, additionalClasses) {
         if (isEmptyString(clsName))
             return false;
 
-        return _.includes(javaBuiltInClasses, clsName) || _.includes(javaBuiltInFullNameClasses, clsName);
+        return _.includes(javaBuiltInClasses, clsName) || _.includes(javaBuiltInFullNameClasses, clsName)
+            || (_.isArray(additionalClasses) && _.includes(additionalClasses, clsName));
     }
 
     const SUPPORTED_JDBC_TYPES = [
@@ -323,8 +326,13 @@ export default ['IgniteLegacyUtils', ['IgniteErrorPopover', (ErrorPopover) => {
             if (!allowBuiltInClass && isJavaBuiltInClass(ident))
                 return !stopEdit && ErrorPopover.show(elemId, msg + ' should not be the Java build-in class!', panels, panelId);
 
-            if (len < 2 && !isJavaBuiltInClass(ident) && !packageOnly)
-                return !stopEdit && ErrorPopover.show(elemId, msg + ' does not have package specified!', panels, panelId);
+            if (len < 2) {
+                if (isJavaBuiltInClass(ident, allowBuiltInClass))
+                    return true;
+
+                if (!packageOnly)
+                    return !stopEdit && ErrorPopover.show(elemId, msg + ' does not have package specified!', panels, panelId);
+            }
 
             for (let i = 0; i < parts.length; i++) {
                 const part = parts[i];

http://git-wip-us.apache.org/repos/asf/ignite/blob/31844374/modules/web-console/frontend/controllers/domains-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/controllers/domains-controller.js b/modules/web-console/frontend/controllers/domains-controller.js
index 840086e..646f8e5 100644
--- a/modules/web-console/frontend/controllers/domains-controller.js
+++ b/modules/web-console/frontend/controllers/domains-controller.js
@@ -81,7 +81,10 @@ export default ['$rootScope', '$scope', '$http', '$state', '$filter', '$timeout'
             return !item.empty && (!item._id || _.find($scope.displayedRows, {_id: item._id}));
         };
 
-        $scope.javaBuiltInClasses = LegacyUtils.javaBuiltInClasses;
+        $scope.javaBuiltInClassesBase = LegacyUtils.javaBuiltInClasses;
+        $scope.javaBuiltInClasses = $scope.javaBuiltInClassesBase.slice();
+        $scope.javaBuiltInClasses.splice(3, 0, 'byte[]');
+
         $scope.compactJavaName = FormUtils.compactJavaName;
         $scope.widthIsSufficient = FormUtils.widthIsSufficient;
         $scope.saveBtnTipText = FormUtils.saveBtnTipText;
@@ -1600,7 +1603,7 @@ export default ['$rootScope', '$scope', '$http', '$state', '$filter', '$timeout'
                         return !stopEdit && ErrorPopover.show(LegacyTable.tableFieldId(index, pairField.idPrefix + pairField.id), 'Field with such ' + pairField.dupObjName + ' already exists!', $scope.ui, 'query');
                 }
 
-                if (pairField.classValidation && !LegacyUtils.isValidJavaClass(pairField.msg, pairValue.value, true, LegacyTable.tableFieldId(index, 'Value' + pairField.id), false, $scope.ui, 'query', stopEdit)) {
+                if (pairField.classValidation && !LegacyUtils.isValidJavaClass(pairField.msg, pairValue.value, ['byte[]'], LegacyTable.tableFieldId(index, 'Value' + pairField.id), false, $scope.ui, 'query', stopEdit)) {
                     if (stopEdit)
                         return false;
 


[42/50] [abbrv] ignite git commit: IGNITE-6574 Remove pending requests in case STATUS_AUTH_FAILURE && credentials == null.

Posted by ag...@apache.org.
IGNITE-6574 Remove pending requests in case STATUS_AUTH_FAILURE && credentials == null.


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

Branch: refs/heads/ignite-6305
Commit: 85261a341936547693aaed2105dc504fda2a9bf7
Parents: 35589a7
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Sat Oct 7 01:10:08 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Sat Oct 7 01:10:08 2017 +0700

----------------------------------------------------------------------
 .../client/impl/connection/GridClientNioTcpConnection.java         | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/85261a34/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientNioTcpConnection.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientNioTcpConnection.java b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientNioTcpConnection.java
index f72a009..3bedd5f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientNioTcpConnection.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/impl/connection/GridClientNioTcpConnection.java
@@ -575,6 +575,8 @@ public class GridClientNioTcpConnection extends GridClientConnection {
                             "(client has no credentials) [clientId=" + clientId +
                             ", srvAddr=" + serverAddress() + ", errMsg=" + resp.errorMessage() +']'));
 
+                        removePending(resp.requestId());
+
                         return;
                     }
 


[41/50] [abbrv] ignite git commit: IGNITE-6463 Web Console: Fixed output of big numbers in SQL query results.

Posted by ag...@apache.org.
IGNITE-6463 Web Console: Fixed output of big numbers in SQL query results.


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

Branch: refs/heads/ignite-6305
Commit: 35589a776a33285c212ddb7e0d51982cb61ce338
Parents: 79d94cf
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Sat Oct 7 00:11:37 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Sat Oct 7 00:11:37 2017 +0700

----------------------------------------------------------------------
 modules/web-console/backend/package.json                      | 4 +++-
 .../frontend/app/modules/agent/decompress.worker.js           | 3 ++-
 modules/web-console/frontend/package.json                     | 7 +++++--
 3 files changed, 10 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/35589a77/modules/web-console/backend/package.json
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/package.json b/modules/web-console/backend/package.json
index 837f41c..07af45f 100644
--- a/modules/web-console/backend/package.json
+++ b/modules/web-console/backend/package.json
@@ -17,7 +17,9 @@
     }
   ],
   "license": "Apache-2.0",
-  "keywords": "grid",
+  "keywords": [
+    "Apache Ignite Web console"
+  ],
   "homepage": "https://ignite.apache.org/",
   "engines": {
     "npm": "^3.x.x",

http://git-wip-us.apache.org/repos/asf/ignite/blob/35589a77/modules/web-console/frontend/app/modules/agent/decompress.worker.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/agent/decompress.worker.js b/modules/web-console/frontend/app/modules/agent/decompress.worker.js
index d8e176d..2fd294d 100644
--- a/modules/web-console/frontend/app/modules/agent/decompress.worker.js
+++ b/modules/web-console/frontend/app/modules/agent/decompress.worker.js
@@ -17,6 +17,7 @@
 
 import _ from 'lodash';
 import pako from 'pako';
+import bigIntJSON from 'json-bigint';
 
 /** This worker decode & decompress BASE64/Zipped data and parse to JSON. */
 // eslint-disable-next-line no-undef
@@ -27,7 +28,7 @@ onmessage = function(e) {
 
     const unzipped = pako.inflate(binaryString, {to: 'string'});
 
-    const res = JSON.parse(unzipped);
+    const res = bigIntJSON({storeAsString: true}).parse(unzipped);
 
     postMessage(_.get(res, 'result', res));
 };

http://git-wip-us.apache.org/repos/asf/ignite/blob/35589a77/modules/web-console/frontend/package.json
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/package.json b/modules/web-console/frontend/package.json
index 2083640..82c3eea 100644
--- a/modules/web-console/frontend/package.json
+++ b/modules/web-console/frontend/package.json
@@ -18,7 +18,9 @@
     }
   ],
   "license": "Apache-2.0",
-  "keywords": "grid",
+  "keywords": [
+    "Apache Ignite Web console"
+  ],
   "homepage": "https://ignite.apache.org/",
   "engines": {
     "npm": "3.x.x",
@@ -47,7 +49,7 @@
     "angular-touch": "1.5.11",
     "angular-translate": "2.15.2",
     "angular-tree-control": "0.2.28",
-    "angular-ui-grid": "4.0.6",
+    "angular-ui-grid": "4.0.7",
     "@uirouter/angularjs": "1.0.5",
     "babel-core": "6.25.0",
     "babel-eslint": "7.2.3",
@@ -76,6 +78,7 @@
     "html-webpack-plugin": "2.29.0",
     "jquery": "3.2.1",
     "json-loader": "0.5.7",
+    "json-bigint": "0.2.3",
     "jszip": "3.1.4",
     "lodash": "4.17.4",
     "node-sass": "4.5.3",


[11/50] [abbrv] ignite git commit: .NET: Suppress some false VS2017 warnings

Posted by ag...@apache.org.
.NET: Suppress some false VS2017 warnings


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

Branch: refs/heads/ignite-6305
Commit: 5ca7909fdfb129eed1a58650f57d7dd968b1e287
Parents: 7aaacd8
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Mon Oct 2 16:34:12 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Mon Oct 2 16:34:12 2017 +0300

----------------------------------------------------------------------
 modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs        | 2 ++
 .../Apache.Ignite.Core/Impl/Cache/Query/QueryCursorBase.cs     | 3 +++
 .../Impl/Client/Cache/Query/ClientQueryCursor.cs               | 3 +++
 .../dotnet/Apache.Ignite.Core/Impl/Client/ClientSocket.cs      | 2 ++
 .../dotnet/Apache.Ignite.Core/Impl/PlatformJniTarget.cs        | 6 ++++++
 .../Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs    | 1 +
 6 files changed, 17 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5ca7909f/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 886dee9..4e5eae5 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
@@ -454,6 +454,8 @@ namespace Apache.Ignite.Core
         /// </summary>
         /// <param name="interopProc">Interop processor.</param>
         /// <param name="stream">Stream.</param>
+        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope",
+            Justification = "PlatformJniTarget is passed further")]
         internal static void OnStart(IUnmanagedTarget interopProc, IBinaryStream stream)
         {
             try

http://git-wip-us.apache.org/repos/asf/ignite/blob/5ca7909f/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursorBase.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursorBase.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursorBase.cs
index 8f00a2e..216d7ea 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursorBase.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursorBase.cs
@@ -21,6 +21,7 @@ namespace Apache.Ignite.Core.Impl.Cache.Query
     using System.Collections;
     using System.Collections.Generic;
     using System.Diagnostics;
+    using System.Diagnostics.CodeAnalysis;
     using Apache.Ignite.Core.Cache.Query;
     using Apache.Ignite.Core.Impl.Binary;
     using Apache.Ignite.Core.Impl.Binary.IO;
@@ -63,6 +64,8 @@ namespace Apache.Ignite.Core.Impl.Cache.Query
         /// <param name="marsh">Marshaller.</param>
         /// <param name="keepBinary">Keep binary flag.</param>
         /// <param name="initialBatchStream">Optional stream with initial batch.</param>
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
+            Justification = "ConvertGetBatch calls Read, which does not rely on constructor being run.")]
         protected QueryCursorBase(Marshaller marsh, bool keepBinary, IBinaryStream initialBatchStream = null)
         {
             Debug.Assert(marsh != null);

http://git-wip-us.apache.org/repos/asf/ignite/blob/5ca7909f/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs
index 898bbbe..75aa5df 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs
@@ -18,6 +18,8 @@
 namespace Apache.Ignite.Core.Impl.Client.Cache.Query
 {
     using System.Collections.Generic;
+    using System.Diagnostics;
+    using System.Diagnostics.CodeAnalysis;
     using System.Linq;
     using Apache.Ignite.Core.Cache;
     using Apache.Ignite.Core.Impl.Binary;
@@ -65,6 +67,7 @@ namespace Apache.Ignite.Core.Impl.Client.Cache.Query
         }
 
         /** <inheritdoc /> */
+        [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")]
         protected override ICacheEntry<TK, TV> Read(BinaryReader reader)
         {
             return new CacheEntry<TK, TV>(reader.ReadObject<TK>(), reader.ReadObject<TV>());

http://git-wip-us.apache.org/repos/asf/ignite/blob/5ca7909f/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientSocket.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientSocket.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientSocket.cs
index 4eb53dd..e565f31 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientSocket.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientSocket.cs
@@ -201,6 +201,8 @@ namespace Apache.Ignite.Core.Impl.Client
         /// <summary>
         /// Connects the socket.
         /// </summary>
+        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", 
+            Justification = "Socket is returned from this method.")]
         private static Socket Connect(IgniteClientConfiguration cfg)
         {
             List<Exception> errors = null;

http://git-wip-us.apache.org/repos/asf/ignite/blob/5ca7909f/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PlatformJniTarget.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PlatformJniTarget.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PlatformJniTarget.cs
index 725c112..c7d9ab4 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PlatformJniTarget.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PlatformJniTarget.cs
@@ -174,6 +174,7 @@ namespace Apache.Ignite.Core.Impl
         }
 
         /** <inheritdoc /> */
+        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
         public unsafe TR InObjectStreamOutObjectStream<TR>(int type, Action<IBinaryStream> writeAction, 
             Func<IBinaryStream, IPlatformTargetInternal, TR> readAction, IPlatformTargetInternal arg)
         {
@@ -244,6 +245,7 @@ namespace Apache.Ignite.Core.Impl
         /// <param name="keepBinary">Keep binary flag, only applicable to object futures. False by default.</param>
         /// <param name="convertFunc">The function to read future result from stream.</param>
         /// <returns>Created future.</returns>
+        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
         private Future<T> GetFuture<T>(Func<long, int, IUnmanagedTarget> listenAction, bool keepBinary = false,
             Func<BinaryReader, T> convertFunc = null)
         {
@@ -325,6 +327,7 @@ namespace Apache.Ignite.Core.Impl
         }
 
         /** <inheritdoc /> */
+        [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")]
         public long InStreamOutLong(int type, Action<IBinaryRawWriter> writeAction)
         {
             using (var stream = IgniteManager.Memory.Allocate().GetStream())
@@ -340,6 +343,7 @@ namespace Apache.Ignite.Core.Impl
         }
 
         /** <inheritdoc /> */
+        [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")]
         public T InStreamOutStream<T>(int type, Action<IBinaryRawWriter> writeAction, 
             Func<IBinaryRawReader, T> readAction)
         {
@@ -361,6 +365,7 @@ namespace Apache.Ignite.Core.Impl
         }
 
         /** <inheritdoc /> */
+        [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")]
         public IPlatformTarget InStreamOutObject(int type, Action<IBinaryRawWriter> writeAction)
         {
             using (var stream = IgniteManager.Memory.Allocate().GetStream())
@@ -429,6 +434,7 @@ namespace Apache.Ignite.Core.Impl
         }
 
         /** <inheritdoc /> */
+        [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")]
         public T OutStream<T>(int type, Func<IBinaryRawReader, T> readAction)
         {
             using (var stream = IgniteManager.Memory.Allocate().GetStream())

http://git-wip-us.apache.org/repos/asf/ignite/blob/5ca7909f/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 b291b3d..37a24b1 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs
@@ -1210,6 +1210,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged
 
         #region AffinityFunction
 
+        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
         private long AffinityFunctionInit(long memPtr, long unused, long unused1, void* baseFunc)
         {
             using (var stream = IgniteManager.Memory.Get(memPtr).GetStream())


[32/50] [abbrv] ignite git commit: IGNITE-6556: JDBC thin: fixed setSchema() case sensitivity handling. This closes #2805.

Posted by ag...@apache.org.
IGNITE-6556: JDBC thin: fixed setSchema() case sensitivity handling. This closes #2805.


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

Branch: refs/heads/ignite-6305
Commit: 3c355e9f6e8c4c38bb14ac3d3c6ccfee378af1ab
Parents: df3c407
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Thu Oct 5 16:45:31 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Thu Oct 5 16:45:31 2017 +0300

----------------------------------------------------------------------
 .../JdbcThinAbstractDmlStatementSelfTest.java   |  2 +-
 .../thin/JdbcThinAutoCloseServerCursorTest.java |  8 ++--
 .../jdbc/thin/JdbcThinComplexQuerySelfTest.java |  2 +-
 .../jdbc/thin/JdbcThinConnectionSelfTest.java   |  4 ++
 .../JdbcThinDynamicIndexAbstractSelfTest.java   |  2 +-
 .../jdbc/thin/JdbcThinEmptyCacheSelfTest.java   |  2 +-
 .../jdbc/thin/JdbcThinMetadataSelfTest.java     |  4 +-
 .../JdbcThinMissingLongArrayResultsTest.java    |  2 +-
 .../jdbc/thin/JdbcThinNoDefaultSchemaTest.java  |  5 ++-
 .../thin/JdbcThinPreparedStatementSelfTest.java |  2 +-
 .../jdbc/thin/JdbcThinResultSetSelfTest.java    |  2 +-
 .../jdbc/thin/JdbcThinStatementSelfTest.java    | 46 +++++++++++---------
 .../internal/jdbc/thin/JdbcThinConnection.java  |  6 +--
 .../jdbc/thin/JdbcThinPreparedStatement.java    |  5 ++-
 .../internal/jdbc/thin/JdbcThinStatement.java   |  9 +++-
 15 files changed, 59 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAbstractDmlStatementSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAbstractDmlStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAbstractDmlStatementSelfTest.java
index 607f557..afe5e2e 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAbstractDmlStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAbstractDmlStatementSelfTest.java
@@ -69,7 +69,7 @@ public abstract class JdbcThinAbstractDmlStatementSelfTest extends JdbcThinAbstr
 
         conn = DriverManager.getConnection(URL);
 
-        conn.setSchema(DEFAULT_CACHE_NAME);
+        conn.setSchema('"' + DEFAULT_CACHE_NAME + '"');
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAutoCloseServerCursorTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAutoCloseServerCursorTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAutoCloseServerCursorTest.java
index eff504b..db4ed3f 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAutoCloseServerCursorTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAutoCloseServerCursorTest.java
@@ -115,7 +115,7 @@ public class JdbcThinAutoCloseServerCursorTest extends JdbcThinAbstractSelfTest
             cache.put(person.id, person);
 
         try (Connection conn = DriverManager.getConnection(URL)) {
-            conn.setSchema(CACHE_NAME);
+            conn.setSchema('"' + CACHE_NAME + '"');
 
             String sqlText = "select * from Person";
 
@@ -198,7 +198,7 @@ public class JdbcThinAutoCloseServerCursorTest extends JdbcThinAbstractSelfTest
      */
     public void testInsert() throws Exception {
         try (Connection conn = DriverManager.getConnection(URL)) {
-            conn.setSchema(CACHE_NAME);
+            conn.setSchema('"' + CACHE_NAME + '"');
 
             String sqlText = "insert into Person (_key, id, name, age) values (?, ?, ?, ?)";
 
@@ -233,7 +233,7 @@ public class JdbcThinAutoCloseServerCursorTest extends JdbcThinAbstractSelfTest
         cache.put(1, p);
 
         try (Connection conn = DriverManager.getConnection(URL)) {
-            conn.setSchema(CACHE_NAME);
+            conn.setSchema('"' + CACHE_NAME + '"');
 
             String sqlText = "update Person set age = age + 1";
 
@@ -258,7 +258,7 @@ public class JdbcThinAutoCloseServerCursorTest extends JdbcThinAbstractSelfTest
         cache.put(1, p);
 
         try (Connection conn = DriverManager.getConnection(URL)) {
-            conn.setSchema(CACHE_NAME);
+            conn.setSchema('"' + CACHE_NAME + '"');
 
             String sqlText = "delete Person where age = ?";
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexQuerySelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexQuerySelfTest.java
index 1714ab1..ad1e312 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexQuerySelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexQuerySelfTest.java
@@ -113,7 +113,7 @@ public class JdbcThinComplexQuerySelfTest extends JdbcThinAbstractSelfTest {
     @Override protected void beforeTest() throws Exception {
         Connection conn = DriverManager.getConnection(URL);
 
-        conn.setSchema("pers");
+        conn.setSchema("\"pers\"");
 
         stmt = conn.createStatement();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java
index 17ce686..fbbec0d 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java
@@ -1633,6 +1633,10 @@ public class JdbcThinConnectionSelfTest extends JdbcThinAbstractSelfTest {
 
             conn.setSchema(schema);
 
+            assertEquals(schema.toUpperCase(), conn.getSchema());
+
+            conn.setSchema('"' + schema + '"');
+
             assertEquals(schema, conn.getSchema());
 
             conn.close();

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDynamicIndexAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDynamicIndexAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDynamicIndexAbstractSelfTest.java
index 5089894..dbe93a4 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDynamicIndexAbstractSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDynamicIndexAbstractSelfTest.java
@@ -309,7 +309,7 @@ public abstract class JdbcThinDynamicIndexAbstractSelfTest extends JdbcThinAbstr
         assertEquals(expSize, cache().size());
 
         try (Statement stmt = conn.createStatement()) {
-            conn.setSchema(DEFAULT_CACHE_NAME);
+            conn.setSchema('"' + DEFAULT_CACHE_NAME + '"');
 
             try (ResultSet rs = stmt.executeQuery("SELECT COUNT(*) from Person")) {
                 assertEquals(expSize, getSingleValue(rs));

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinEmptyCacheSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinEmptyCacheSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinEmptyCacheSelfTest.java
index 1ede536..41b4338 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinEmptyCacheSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinEmptyCacheSelfTest.java
@@ -87,7 +87,7 @@ public class JdbcThinEmptyCacheSelfTest extends JdbcThinAbstractSelfTest {
     @Override protected void beforeTest() throws Exception {
         Connection conn = DriverManager.getConnection(URL);
 
-        conn.setSchema(CACHE_NAME);
+        conn.setSchema('"' + CACHE_NAME + '"');
 
         stmt = conn.createStatement();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
index abbe4e1..6c20de0 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
@@ -156,7 +156,7 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest {
     public void testResultSetMetaData() throws Exception {
         Connection conn = DriverManager.getConnection(URL);
 
-        conn.setSchema("pers");
+        conn.setSchema("\"pers\"");
 
         Statement stmt = conn.createStatement();
 
@@ -528,7 +528,7 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest {
      */
     public void testParametersMetadata() throws Exception {
         try (Connection conn = DriverManager.getConnection(URL)) {
-            conn.setSchema("pers");
+            conn.setSchema("\"pers\"");
 
             PreparedStatement stmt = conn.prepareStatement("select orgId from Person p where p.name > ? and p.orgId > ?");
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMissingLongArrayResultsTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMissingLongArrayResultsTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMissingLongArrayResultsTest.java
index 1a53ab7..1f6e2c0 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMissingLongArrayResultsTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMissingLongArrayResultsTest.java
@@ -171,7 +171,7 @@ public class JdbcThinMissingLongArrayResultsTest extends JdbcThinAbstractSelfTes
     @SuppressWarnings({"EmptyTryBlock", "unused"})
     public void testDefaults() throws Exception {
         try (Connection conn = DriverManager.getConnection(URL)) {
-            conn.setSchema(CACHE_NAME);
+            conn.setSchema('"' + CACHE_NAME + '"');
 
             try (PreparedStatement st = conn.prepareStatement("SELECT * FROM VALUE")) {
                 ResultSet rs = st.executeQuery();

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinNoDefaultSchemaTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinNoDefaultSchemaTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinNoDefaultSchemaTest.java
index cab28f4..a1be582 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinNoDefaultSchemaTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinNoDefaultSchemaTest.java
@@ -219,10 +219,13 @@ public class JdbcThinNoDefaultSchemaTest extends JdbcThinAbstractSelfTest {
                 }
             }, SQLException.class, "Failed to parse query");
 
-            conn.setSchema("cache1");
+            conn.setSchema("\"cache1\"");
 
             Statement stmt = conn.createStatement();
 
+            //Must not affects previous created statements.
+            conn.setSchema("invalid_schema");
+
             stmt.execute("select t._key, t._val from Integer t");
 
             ResultSet rs = stmt.getResultSet();

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinPreparedStatementSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinPreparedStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinPreparedStatementSelfTest.java
index 85eb1d3..c577853 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinPreparedStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinPreparedStatementSelfTest.java
@@ -148,7 +148,7 @@ public class JdbcThinPreparedStatementSelfTest extends JdbcThinAbstractSelfTest
     @Override protected void beforeTest() throws Exception {
         conn = DriverManager.getConnection(URL);
 
-        conn.setSchema(DEFAULT_CACHE_NAME);
+        conn.setSchema('"' + DEFAULT_CACHE_NAME + '"');
 
         assert conn != null;
         assert !conn.isClosed();

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java
index 5a3c5df..fd46cda 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java
@@ -120,7 +120,7 @@ public class JdbcThinResultSetSelfTest extends JdbcThinAbstractSelfTest {
     @Override protected void beforeTest() throws Exception {
         Connection conn = DriverManager.getConnection(URL);
 
-        conn.setSchema(DEFAULT_CACHE_NAME);
+        conn.setSchema('"' + DEFAULT_CACHE_NAME + '"');
 
         stmt = conn.createStatement();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java
index 5309465..82c0512 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java
@@ -104,7 +104,7 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest {
     @Override protected void beforeTest() throws Exception {
         conn = DriverManager.getConnection(URL);
 
-        conn.setSchema(DEFAULT_CACHE_NAME);
+        conn.setSchema('"' + DEFAULT_CACHE_NAME + '"');
 
         stmt = conn.createStatement();
 
@@ -444,6 +444,8 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest {
     public void testExecuteQueryMultipleOnlyDml() throws Exception {
         conn.setSchema(null);
 
+        Statement stmt0 = conn.createStatement();
+
         int stmtCnt = 10;
 
         StringBuilder sql = new StringBuilder("drop table if exists test; create table test(ID int primary key, NAME varchar(20)); ");
@@ -451,24 +453,24 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest {
         for (int i = 0; i < stmtCnt; ++i)
             sql.append("insert into test (ID, NAME) values (" + i + ", 'name_" + i +"'); ");
 
-        assert !stmt.execute(sql.toString());
+        assert !stmt0.execute(sql.toString());
 
         // DROP TABLE statement
-        assert stmt.getResultSet() == null;
-        assert stmt.getUpdateCount() == 0;
+        assert stmt0.getResultSet() == null;
+        assert stmt0.getUpdateCount() == 0;
 
         // CREATE TABLE statement
-        assert stmt.getResultSet() == null;
-        assert stmt.getUpdateCount() == 0;
+        assert stmt0.getResultSet() == null;
+        assert stmt0.getUpdateCount() == 0;
 
         for (int i = 0; i < stmtCnt; ++i) {
-            assert stmt.getMoreResults();
+            assert stmt0.getMoreResults();
 
-            assert stmt.getResultSet() == null;
-            assert stmt.getUpdateCount() == 1;
+            assert stmt0.getResultSet() == null;
+            assert stmt0.getUpdateCount() == 1;
         }
 
-        assert !stmt.getMoreResults();
+        assert !stmt0.getMoreResults();
     }
 
     /**
@@ -477,6 +479,8 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest {
     public void testExecuteQueryMultipleMixed() throws Exception {
         conn.setSchema(null);
 
+        Statement stmt0 = conn.createStatement();
+
         int stmtCnt = 10;
 
         StringBuilder sql = new StringBuilder("drop table if exists test; create table test(ID int primary key, NAME varchar(20)); ");
@@ -488,29 +492,29 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest {
                 sql.append(" select * from test where id < " + i + "; ");
         }
 
-        assert !stmt.execute(sql.toString());
+        assert !stmt0.execute(sql.toString());
 
         // DROP TABLE statement
-        assert stmt.getResultSet() == null;
-        assert stmt.getUpdateCount() == 0;
+        assert stmt0.getResultSet() == null;
+        assert stmt0.getUpdateCount() == 0;
 
         // CREATE TABLE statement
-        assert stmt.getResultSet() == null;
-        assert stmt.getUpdateCount() == 0;
+        assert stmt0.getResultSet() == null;
+        assert stmt0.getUpdateCount() == 0;
 
         boolean notEmptyResult = false;
 
         for (int i = 0; i < stmtCnt; ++i) {
-            assert stmt.getMoreResults();
+            assert stmt0.getMoreResults();
 
             if (i % 2 == 0) {
-                assert stmt.getResultSet() == null;
-                assert stmt.getUpdateCount() == 1;
+                assert stmt0.getResultSet() == null;
+                assert stmt0.getUpdateCount() == 1;
             }
             else {
-                assert stmt.getUpdateCount() == -1;
+                assert stmt0.getUpdateCount() == -1;
 
-                ResultSet rs = stmt.getResultSet();
+                ResultSet rs = stmt0.getResultSet();
 
                 int rowsCnt = 0;
 
@@ -526,7 +530,7 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest {
 
         assert notEmptyResult;
 
-        assert !stmt.getMoreResults();
+        assert !stmt0.getMoreResults();
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
index d804750..5afed4e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
@@ -168,7 +168,7 @@ public class JdbcThinConnection implements Connection {
 
         checkCursorOptions(resSetType, resSetConcurrency, resSetHoldability);
 
-        JdbcThinStatement stmt  = new JdbcThinStatement(this, resSetHoldability);
+        JdbcThinStatement stmt  = new JdbcThinStatement(this, resSetHoldability, schema);
 
         if (timeout > 0)
             stmt.timeout(timeout);
@@ -197,7 +197,7 @@ public class JdbcThinConnection implements Connection {
         if (sql == null)
             throw new SQLException("SQL string cannot be null.");
 
-        JdbcThinPreparedStatement stmt = new JdbcThinPreparedStatement(this, sql, resSetHoldability);
+        JdbcThinPreparedStatement stmt = new JdbcThinPreparedStatement(this, sql, resSetHoldability, schema);
 
         if (timeout > 0)
             stmt.timeout(timeout);
@@ -592,7 +592,7 @@ public class JdbcThinConnection implements Connection {
     @Override public void setSchema(String schema) throws SQLException {
         ensureNotClosed();
 
-        this.schema = schema;
+        this.schema = normalizeSchema(schema);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
index fb2810d..23d3bbe 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
@@ -65,9 +65,10 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep
      * @param conn Connection.
      * @param sql SQL query.
      * @param resHoldability Result set holdability.
+     * @param schema Schema name.
      */
-    JdbcThinPreparedStatement(JdbcThinConnection conn, String sql, int resHoldability) {
-        super(conn, resHoldability);
+    JdbcThinPreparedStatement(JdbcThinConnection conn, String sql, int resHoldability, String schema) {
+        super(conn, resHoldability, schema);
 
         this.sql = sql;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/3c355e9f/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
index 603545b..d29df93 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
@@ -55,6 +55,9 @@ public class JdbcThinStatement implements Statement {
     /** JDBC Connection implementation. */
     protected JdbcThinConnection conn;
 
+    /** Schema name. */
+    private final String schema;
+
     /** Closed flag. */
     private boolean closed;
 
@@ -87,12 +90,14 @@ public class JdbcThinStatement implements Statement {
      *
      * @param conn JDBC connection.
      * @param resHoldability Result set holdability.
+     * @param schema Schema name.
      */
-    JdbcThinStatement(JdbcThinConnection conn, int resHoldability) {
+    JdbcThinStatement(JdbcThinConnection conn, int resHoldability, String schema) {
         assert conn != null;
 
         this.conn = conn;
         this.resHoldability = resHoldability;
+        this.schema = schema;
     }
 
     /** {@inheritDoc} */
@@ -122,7 +127,7 @@ public class JdbcThinStatement implements Statement {
         if (sql == null || sql.isEmpty())
             throw new SQLException("SQL query is empty.");
 
-        JdbcResult res0 = conn.sendRequest(new JdbcQueryExecuteRequest(stmtType, conn.getSchema(), pageSize,
+        JdbcResult res0 = conn.sendRequest(new JdbcQueryExecuteRequest(stmtType, schema, pageSize,
             maxRows, sql, args == null ? null : args.toArray(new Object[args.size()])));
 
         assert res0 != null;


[05/50] [abbrv] ignite git commit: IGNITE-6286: SQL: fixed BigDecimal argument handling. This closes #2750.

Posted by ag...@apache.org.
IGNITE-6286: SQL: fixed BigDecimal argument handling. This closes #2750.


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

Branch: refs/heads/ignite-6305
Commit: 013d7dbf7811a1b8e207d6238aff67e43c28adad
Parents: 59ee8af
Author: Sergey Chernolyas <se...@gmail.com>
Authored: Mon Oct 2 10:52:21 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Oct 2 10:52:21 2017 +0300

----------------------------------------------------------------------
 .../processors/query/h2/IgniteH2Indexing.java   |   3 +
 .../query/IgniteSqlParameterizedQueryTest.java  | 392 +++++++++++++++++++
 .../IgniteCacheQuerySelfTestSuite.java          |   3 +-
 3 files changed, 397 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/013d7dbf/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
----------------------------------------------------------------------
diff --git 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
index 9e6a1fa..fd7b9a8 100644
--- 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
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.query.h2;
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.sql.Connection;
 import java.sql.DriverManager;
@@ -511,6 +512,8 @@ public class IgniteH2Indexing implements GridQueryIndexing {
                 stmt.setNull(idx, Types.VARCHAR);
             else if (obj instanceof BigInteger)
                 stmt.setObject(idx, obj, Types.JAVA_OBJECT);
+            else if (obj instanceof BigDecimal)
+                stmt.setObject(idx, obj, Types.DECIMAL);
             else
                 stmt.setObject(idx, obj);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/013d7dbf/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlParameterizedQueryTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlParameterizedQueryTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlParameterizedQueryTest.java
new file mode 100644
index 0000000..b5039cd
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlParameterizedQueryTest.java
@@ -0,0 +1,392 @@
+/*
+ * 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.query;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+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.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * Test sql queries with parameters for all types.
+ * The test is fix  for issue 'IGNITE-6286'
+ *
+ * @author Sergey Chernolyas &amp;sergey_chernolyas@gmail.com&amp;
+ * @see <a href="https://issues.apache.org/jira/browse/IGNITE-6286">IGNITE-6286</a>
+ */
+public class IgniteSqlParameterizedQueryTest extends GridCommonAbstractTest {
+    /** IP finder. */
+    private static final TcpDiscoveryVmIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** */
+    private static final String CACHE_BOOKMARK = "Bookmark";
+
+    /** */
+    private static final String NODE_CLIENT = "client";
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration c = super.getConfiguration(gridName);
+
+        TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+        disco.setIpFinder(IP_FINDER);
+
+        c.setDiscoverySpi(disco);
+
+        c.setCacheConfiguration(buildCacheConfiguration(CACHE_BOOKMARK));
+        if (gridName.equals(NODE_CLIENT))
+            c.setClientMode(true);
+
+        return c;
+    }
+
+    /**
+     * build cache configuration
+     * @param name cache name
+     * @return configuration
+     * @see CacheConfiguration
+     */
+    private CacheConfiguration buildCacheConfiguration(String name) {
+        CacheConfiguration ccfg = new CacheConfiguration(name);
+        ccfg.setIndexedTypes(String.class, Bookmark.class);
+        return ccfg;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        startGrid(0);
+        startGrid(NODE_CLIENT);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        stopAllGrids();
+    }
+
+    /**
+     * method for create parametrized query and get first result
+     * @param field name of field
+     * @param val value
+     * @return fist searched object
+     * @see Bookmark
+     */
+    private Object columnValue(String field, Object val) {
+        IgniteCache<String, Bookmark> cache = grid(NODE_CLIENT).cache(CACHE_BOOKMARK);
+        SqlFieldsQuery qry = new SqlFieldsQuery("SELECT " + field + " from  Bookmark where " + field + " = ?");
+        qry.setArgs(val);
+
+        QueryCursor<List<?>> cursor = cache.query(qry);
+        List<List<?>> results = cursor.getAll();
+        assertEquals("Search by field '" + field +"' returns incorrect row count!",1, results.size());
+        List<?> row0 = results.get(0);
+        return row0.get(0);
+    }
+
+    /**
+     * testing parametrized query by field with supported type
+     * @throws Exception if any error occurs
+     */
+    public void testSupportedTypes() throws Exception {
+        IgniteCache<String, Bookmark> cache = grid(NODE_CLIENT).cache(CACHE_BOOKMARK);
+        Bookmark bookmark = new Bookmark();
+        bookmark.setId(UUID.randomUUID().toString());
+        bookmark.setStockCount(Integer.MAX_VALUE);
+        bookmark.setUrlPort(Short.MAX_VALUE);
+        bookmark.setUserId(Long.MAX_VALUE);
+        bookmark.setVisitRatio(Float.MAX_VALUE);
+        bookmark.setTaxPercentage(Double.MAX_VALUE);
+        bookmark.setFavourite(true);
+        bookmark.setDisplayMask(Byte.MAX_VALUE);
+        bookmark.setSerialNumber(UUID.randomUUID());
+        bookmark.setVisitCount(new BigInteger("1000000000000000"));
+        bookmark.setSiteWeight(new BigDecimal("1000000000000000.001"));
+        bookmark.setCreated(new Date());
+        cache.put(bookmark.id, bookmark);
+
+        assertEquals(bookmark.getId(), columnValue("id", bookmark.getId()));
+        assertEquals(bookmark.getStockCount(), columnValue("stockcount", bookmark.getStockCount()));
+        assertEquals(bookmark.getUrlPort(), columnValue("urlport", bookmark.getUrlPort()));
+        assertEquals(bookmark.getUserId(), columnValue("userid", bookmark.getUserId()));
+        assertEquals(bookmark.getVisitRatio(), columnValue("visitratio", bookmark.getVisitRatio()));
+        assertEquals(bookmark.getTaxPercentage(), columnValue("taxpercentage", bookmark.getTaxPercentage()));
+        assertEquals(bookmark.getFavourite(), columnValue("favourite", bookmark.getFavourite()));
+        assertEquals(bookmark.getDisplayMask(), columnValue("displaymask", bookmark.getDisplayMask()));
+        assertEquals(bookmark.getSerialNumber(), columnValue("serialnumber", bookmark.getSerialNumber()));
+        assertEquals(bookmark.getVisitCount(), columnValue("visitcount", bookmark.getVisitCount()));
+        assertEquals(bookmark.getSiteWeight(), columnValue("siteweight", bookmark.getSiteWeight()));
+        assertEquals(bookmark.getCreated(), columnValue("created", bookmark.getCreated()));
+    }
+
+    /**
+     * Object with all predefined SQL Data Types
+     * @see <a href="https://apacheignite.readme.io/docs/dml#section-advanced-configuration">SQL Data Types</a>
+     */
+    private static class Bookmark implements Serializable {
+        /** */
+        @QuerySqlField
+        private String id;
+
+        /** */
+        @QuerySqlField
+        private Integer stockCount;
+
+        /** */
+        @QuerySqlField
+        private Short urlPort;
+
+        /** */
+        @QuerySqlField
+        private Long userId;
+
+        /** */
+        @QuerySqlField
+        private Float visitRatio;
+
+        /** */
+        @QuerySqlField
+        private Double taxPercentage;
+
+        /** */
+        @QuerySqlField
+        private Boolean favourite;
+
+        /** */
+        @QuerySqlField
+        private Byte displayMask;
+
+        /** */
+        @QuerySqlField
+        private UUID serialNumber;
+
+        /** */
+        @QuerySqlField
+        private BigDecimal siteWeight;
+
+        /** */
+        @QuerySqlField
+        private BigInteger visitCount;
+
+        /** */
+        @QuerySqlField
+        private Date created;
+
+        /**
+         *
+         */
+        public String getId() {
+            return id;
+        }
+
+        /**
+         *
+         */
+        public void setId(String id) {
+            this.id = id;
+        }
+
+        /**
+         *
+         */
+        public Integer getStockCount() {
+            return stockCount;
+        }
+
+        /**
+         *
+         */
+        public void setStockCount(Integer stockCount) {
+            this.stockCount = stockCount;
+        }
+
+        /**
+         *
+         */
+        public Short getUrlPort() {
+            return urlPort;
+        }
+
+        /**
+         *
+         */
+        public void setUrlPort(Short urlPort) {
+            this.urlPort = urlPort;
+        }
+
+        /**
+         *
+         */
+        public Long getUserId() {
+            return userId;
+        }
+
+        /**
+         *
+         */
+        public void setUserId(Long userId) {
+            this.userId = userId;
+        }
+
+        /**
+         *
+         */
+        public Float getVisitRatio() {
+            return visitRatio;
+        }
+
+        /**
+         *
+         */
+        public void setVisitRatio(Float visitRatio) {
+            this.visitRatio = visitRatio;
+        }
+
+        /**
+         *
+         */
+        public Double getTaxPercentage() {
+            return taxPercentage;
+        }
+
+        /**
+         *
+         */
+        public void setTaxPercentage(Double taxPercentage) {
+            this.taxPercentage = taxPercentage;
+        }
+
+        /**
+         *
+         */
+        public Boolean getFavourite() {
+            return favourite;
+        }
+
+        /**
+         *
+         */
+        public void setFavourite(Boolean favourite) {
+            this.favourite = favourite;
+        }
+
+        /**
+         *
+         */
+        public Byte getDisplayMask() {
+            return displayMask;
+        }
+
+        /**
+         *
+         */
+        public void setDisplayMask(Byte displayMask) {
+            this.displayMask = displayMask;
+        }
+
+        /**
+         *
+         */
+        public UUID getSerialNumber() {
+            return serialNumber;
+        }
+
+        /**
+         *
+         */
+        public void setSerialNumber(UUID serialNumber) {
+            this.serialNumber = serialNumber;
+        }
+
+        /**
+         *
+         */
+        public BigDecimal getSiteWeight() {
+            return siteWeight;
+        }
+
+        /**
+         *
+         */
+        public void setSiteWeight(BigDecimal siteWeight) {
+            this.siteWeight = siteWeight;
+        }
+
+        /**
+         *
+         */
+        public BigInteger getVisitCount() {
+            return visitCount;
+        }
+
+        /**
+         *
+         */
+        public void setVisitCount(BigInteger visitCount) {
+            this.visitCount = visitCount;
+        }
+
+        /**
+         *
+         */
+        public Date getCreated() {
+            return created;
+        }
+
+        /**
+         *
+         */
+        public void setCreated(Date created) {
+            this.created = created;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o)
+                return true;
+            if (o == null || getClass() != o.getClass())
+                return false;
+            Bookmark bookmark = (Bookmark)o;
+            return Objects.equals(id, bookmark.id);
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return Objects.hash(id);
+        }
+    }
+
+}
+
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/013d7dbf/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 aaa8e57..c49649b 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
@@ -123,6 +123,7 @@ import org.apache.ignite.internal.processors.cache.query.IgniteCacheQueryCacheDe
 import org.apache.ignite.internal.processors.cache.query.IndexingSpiQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.query.IndexingSpiQueryTxSelfTest;
 import org.apache.ignite.internal.processors.client.ClientConnectorConfigurationValidationSelfTest;
+import org.apache.ignite.internal.processors.query.IgniteSqlParameterizedQueryTest;
 import org.apache.ignite.internal.processors.query.h2.IgniteSqlBigIntegerKeyTest;
 import org.apache.ignite.internal.processors.query.IgniteQueryDedicatedPoolTest;
 import org.apache.ignite.internal.processors.query.IgniteSqlEntryCacheModeAgnosticTest;
@@ -336,8 +337,8 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
         suite.addTestSuite(IgniteSqlRoutingTest.class);
         suite.addTestSuite(IgniteSqlNotNullConstraintTest.class);
         suite.addTestSuite(LongIndexNameTest.class);
-
         suite.addTestSuite(GridCacheQuerySqlFieldInlineSizeSelfTest.class);
+        suite.addTestSuite(IgniteSqlParameterizedQueryTest.class);
 
         return suite;
     }


[03/50] [abbrv] ignite git commit: IGNITE-6120 Fixed missing "lazy query" flag.

Posted by ag...@apache.org.
IGNITE-6120 Fixed missing "lazy query" flag.


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

Branch: refs/heads/ignite-6305
Commit: 55886b14cc6e7171acf05991f7f265dbadcb8db2
Parents: 2c39351
Author: vsisko <vs...@gridgain.com>
Authored: Sun Oct 1 19:00:22 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Oct 2 13:56:51 2017 +0700

----------------------------------------------------------------------
 modules/web-console/frontend/app/filters/duration.filter.js   | 2 +-
 .../frontend/app/modules/agent/AgentManager.service.js        | 7 ++++---
 .../web-console/frontend/app/modules/sql/sql.controller.js    | 2 +-
 modules/web-console/frontend/package.json                     | 2 +-
 4 files changed, 7 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/55886b14/modules/web-console/frontend/app/filters/duration.filter.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/filters/duration.filter.js b/modules/web-console/frontend/app/filters/duration.filter.js
index 46d50d8..703b6a4 100644
--- a/modules/web-console/frontend/app/filters/duration.filter.js
+++ b/modules/web-console/frontend/app/filters/duration.filter.js
@@ -36,6 +36,6 @@ export default [() => {
         const s = Math.floor((t - d * cd - h * ch - m * cm) / cs);
         const ms = Math.round(t % 1000);
 
-        return a(d, 'd') + a(h, 'h') + a(m, 'm') + a(s, 's') + (t < cm ? ms + 'ms' : '');
+        return a(d, 'd') + a(h, 'h') + a(m, 'm') + a(s, 's') + (t === 0 || (t < cm && ms !== 0) ? ms + 'ms' : '');
     };
 }];

http://git-wip-us.apache.org/repos/asf/ignite/blob/55886b14/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/agent/AgentManager.service.js b/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
index 9a736b6..e4bde6f 100644
--- a/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
+++ b/modules/web-console/frontend/app/modules/agent/AgentManager.service.js
@@ -310,7 +310,7 @@ export default class IgniteAgentManager {
             this.socket.removeListener('disconnect', onDisconnect);
 
             if (err)
-                latch.reject(err);
+                return latch.reject(err);
 
             latch.resolve(res);
         });
@@ -552,9 +552,10 @@ export default class IgniteAgentManager {
      * @param {Boolean} enforceJoinOrder Flag whether enforce join order is enabled.
      * @param {Boolean} replicatedOnly Flag whether query contains only replicated tables.
      * @param {Boolean} local Flag whether to execute query locally.
+     * @param {Boolean} lazy query flag.
      * @returns {Promise}
      */
-    querySqlGetAll(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local) {
+    querySqlGetAll(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, lazy) {
         // Page size for query.
         const pageSz = 1024;
 
@@ -572,7 +573,7 @@ export default class IgniteAgentManager {
                 });
         };
 
-        return this.querySql(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz)
+        return this.querySql(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz, lazy)
             .then(fetchResult);
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/55886b14/modules/web-console/frontend/app/modules/sql/sql.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/sql/sql.controller.js b/modules/web-console/frontend/app/modules/sql/sql.controller.js
index c43dc5c..420c4b9 100644
--- a/modules/web-console/frontend/app/modules/sql/sql.controller.js
+++ b/modules/web-console/frontend/app/modules/sql/sql.controller.js
@@ -1630,7 +1630,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
             return Promise.resolve(args.localNid || _chooseNode(args.cacheName, false))
                 .then((nid) => args.type === 'SCAN'
                     ? agentMgr.queryScanGetAll(nid, args.cacheName, args.query, !!args.regEx, !!args.caseSensitive, !!args.near, !!args.localNid)
-                    : agentMgr.querySqlGetAll(nid, args.cacheName, args.query, !!args.nonCollocatedJoins, !!args.enforceJoinOrder, false, !!args.localNid))
+                    : agentMgr.querySqlGetAll(nid, args.cacheName, args.query, !!args.nonCollocatedJoins, !!args.enforceJoinOrder, false, !!args.localNid, !!args.lazy))
                 .then((res) => _export(paragraph.name + '-all.csv', paragraph.gridOptions.columnDefs, res.columns, res.rows))
                 .catch(Messages.showError)
                 .then(() => paragraph.ace && paragraph.ace.focus());

http://git-wip-us.apache.org/repos/asf/ignite/blob/55886b14/modules/web-console/frontend/package.json
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/package.json b/modules/web-console/frontend/package.json
index f96c322..d828e17 100644
--- a/modules/web-console/frontend/package.json
+++ b/modules/web-console/frontend/package.json
@@ -76,7 +76,7 @@
     "html-webpack-plugin": "2.29.0",
     "jquery": "3.2.1",
     "json-loader": "0.5.7",
-    "jszip": "3.1.3",
+    "jszip": "3.1.4",
     "lodash": "4.17.4",
     "node-sass": "4.5.3",
     "nvd3": "1.8.4",


[20/50] [abbrv] ignite git commit: .NET: Fix TestRecordLocal

Posted by ag...@apache.org.
.NET: Fix TestRecordLocal


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

Branch: refs/heads/ignite-6305
Commit: 855fe4b51982933742106678ccd01bdcba66d210
Parents: db69e90
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Tue Oct 3 18:33:57 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Tue Oct 3 18:33:57 2017 +0300

----------------------------------------------------------------------
 modules/platforms/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/855fe4b5/modules/platforms/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs
index 672ff9e..a7c0534 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs
@@ -314,7 +314,7 @@ namespace Apache.Ignite.Core.Tests
         [Test]
         public void TestRecordLocal()
         {
-            Assert.Throws<NotImplementedException>(() => _grid1.GetEvents().RecordLocal(new MyEvent()));
+            Assert.Throws<NotSupportedException>(() => _grid1.GetEvents().RecordLocal(new MyEvent()));
         }
 
         /// <summary>


[44/50] [abbrv] ignite git commit: Fixed JavaDoc again.

Posted by ag...@apache.org.
Fixed JavaDoc again.


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

Branch: refs/heads/ignite-6305
Commit: 87e7b32d506a0b3caa93c9da2be1ea51f20ae96d
Parents: e9764f1
Author: devozerov <vo...@gridgain.com>
Authored: Mon Oct 9 11:34:51 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Oct 9 11:34:51 2017 +0300

----------------------------------------------------------------------
 .../cache/persistence/wal/serializer/RecordV2Serializer.java       | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/87e7b32d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java
index a06b6d7..98804d9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java
@@ -39,7 +39,7 @@ import static org.apache.ignite.internal.processors.cache.persistence.wal.serial
  * Record V2 serializer.
  * Stores records in following format:
  * <ul>
- * <li>Record type from {@link WALRecord.RecordType} incremented by 1</li>
+ * <li>Record type from {@code WALRecord.RecordType} incremented by 1</li>
  * <li>WAL pointer to double check consistency</li>
  * <li>Record length</li>
  * <li>Data</li>


[49/50] [abbrv] ignite git commit: ignite-6305 Ignite update checker

Posted by ag...@apache.org.
ignite-6305 Ignite update checker


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

Branch: refs/heads/ignite-6305
Commit: ca832d5ff708ad7b0d475b0f798d1391557c6824
Parents: a45677c
Author: Andrey Gura <ag...@apache.org>
Authored: Wed Sep 27 13:50:26 2017 +0300
Committer: Andrey Gura <ag...@apache.org>
Committed: Mon Oct 9 16:08:42 2017 +0300

----------------------------------------------------------------------
 .../processors/cluster/ClusterProcessor.java    |  41 ++---
 .../processors/cluster/GridUpdateNotifier.java  | 182 ++++++-------------
 .../cluster/HttpIgniteUpdatesChecker.java       |  29 ++-
 .../cluster/GridUpdateNotifierSelfTest.java     |  50 +----
 4 files changed, 92 insertions(+), 210 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ca832d5f/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
index dc503fb..7591911 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/ClusterProcessor.java
@@ -18,7 +18,6 @@
 package org.apache.ignite.internal.processors.cluster;
 
 import java.io.Serializable;
-import java.lang.ref.WeakReference;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
@@ -30,6 +29,7 @@ import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.events.Event;
@@ -38,6 +38,7 @@ import org.apache.ignite.internal.IgniteDiagnosticInfo;
 import org.apache.ignite.internal.IgniteDiagnosticMessage;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteKernal;
+import org.apache.ignite.internal.IgniteProperties;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.cluster.IgniteClusterImpl;
 import org.apache.ignite.internal.managers.communication.GridIoPolicy;
@@ -60,6 +61,7 @@ import org.apache.ignite.spi.discovery.DiscoveryDataBag.GridDiscoveryData;
 import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_DIAGNOSTIC_ENABLED;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_UPDATE_NOTIFIER;
 import static org.apache.ignite.IgniteSystemProperties.getBoolean;
 import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
 import static org.apache.ignite.events.EventType.EVT_NODE_LEFT;
@@ -84,7 +86,7 @@ public class ClusterProcessor extends GridProcessorAdapter {
     private IgniteClusterImpl cluster;
 
     /** */
-    private final AtomicBoolean notifyEnabled = new AtomicBoolean(false);
+    private final AtomicBoolean notifyEnabled = new AtomicBoolean();
 
     /** */
     @GridToStringExclude
@@ -107,6 +109,9 @@ public class ClusterProcessor extends GridProcessorAdapter {
     public ClusterProcessor(GridKernalContext ctx) {
         super(ctx);
 
+        notifyEnabled.set(IgniteSystemProperties.getBoolean(IGNITE_UPDATE_NOTIFIER,
+            Boolean.parseBoolean(IgniteProperties.get("ignite.update.notifier.enabled.by.default"))));
+
         cluster = new IgniteClusterImpl(ctx);
     }
 
@@ -297,12 +302,13 @@ public class ClusterProcessor extends GridProcessorAdapter {
     /**
      * @param vals collection to seek through.
      */
+    @SuppressWarnings("unchecked")
     private Boolean findLastFlag(Collection<Serializable> vals) {
         Boolean flag = null;
 
         for (Serializable ser : vals) {
             if (ser != null) {
-                Map<String, Object> map = (Map<String, Object>) ser;
+                Map<String, Object> map = (Map<String, Object>)ser;
 
                 if (map.containsKey(ATTR_UPDATE_NOTIFIER_STATUS))
                     flag = (Boolean) map.get(ATTR_UPDATE_NOTIFIER_STATUS);
@@ -316,11 +322,7 @@ public class ClusterProcessor extends GridProcessorAdapter {
     @Override public void onKernalStart(boolean active) throws IgniteCheckedException {
         if (notifyEnabled.get()) {
             try {
-                verChecker = new GridUpdateNotifier(ctx.igniteInstanceName(),
-                    VER_STR,
-                    ctx.gateway(),
-                    ctx.plugins().allProviders(),
-                    false);
+                verChecker = new GridUpdateNotifier(ctx.igniteInstanceName(), VER_STR, false);
 
                 updateNtfTimer = new Timer("ignite-update-notifier-timer", true);
 
@@ -473,9 +475,6 @@ public class ClusterProcessor extends GridProcessorAdapter {
      * Update notifier timer task.
      */
     private static class UpdateNotifierTimerTask extends GridTimerTask {
-        /** Reference to kernal. */
-        private final WeakReference<IgniteKernal> kernalRef;
-
         /** Logger. */
         private final IgniteLogger log;
 
@@ -494,10 +493,11 @@ public class ClusterProcessor extends GridProcessorAdapter {
          * @param kernal Kernal.
          * @param verChecker Version checker.
          */
-        private UpdateNotifierTimerTask(IgniteKernal kernal, GridUpdateNotifier verChecker,
-            AtomicBoolean notifyEnabled) {
-            kernalRef = new WeakReference<>(kernal);
-
+        private UpdateNotifierTimerTask(
+            IgniteKernal kernal,
+            GridUpdateNotifier verChecker,
+            AtomicBoolean notifyEnabled
+        ) {
             log = kernal.context().log(UpdateNotifierTimerTask.class);
 
             this.verChecker = verChecker;
@@ -509,14 +509,7 @@ public class ClusterProcessor extends GridProcessorAdapter {
             if (!notifyEnabled.get())
                 return;
 
-            if (!first) {
-                IgniteKernal kernal = kernalRef.get();
-
-                if (kernal != null)
-                    verChecker.topologySize(kernal.cluster().nodes().size());
-            }
-
-            verChecker.checkForNewVersion(log);
+            verChecker.checkForNewVersion(log, first);
 
             // Just wait for 10 secs.
             Thread.sleep(PERIODIC_VER_CHECK_CONN_TIMEOUT);
@@ -530,7 +523,7 @@ public class ClusterProcessor extends GridProcessorAdapter {
             // No-op if status is NOT available.
             verChecker.reportStatus(log);
 
-            if (first) {
+            if (first && verChecker.error() == null) {
                 first = false;
 
                 verChecker.reportOnlyNew(true);

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca832d5f/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifier.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifier.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifier.java
index eacc42f..e92f216 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifier.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifier.java
@@ -17,34 +17,16 @@
 
 package org.apache.ignite.internal.processors.cluster;
 
-import java.io.BufferedReader;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.Collection;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.IgniteSystemProperties;
-import org.apache.ignite.internal.GridKernalGateway;
 import org.apache.ignite.internal.IgniteKernal;
-import org.apache.ignite.internal.IgniteProperties;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.internal.util.worker.GridWorker;
-import org.apache.ignite.plugin.PluginProvider;
 import org.jetbrains.annotations.Nullable;
 
-import static java.net.URLEncoder.encode;
-
 /**
  * This class is responsible for notification about new version availability.
  * <p>
@@ -55,21 +37,24 @@ class GridUpdateNotifier {
     /** Default encoding. */
     private static final String CHARSET = "UTF-8";
 
-    /** Access URL to be used to access latest version data. */
-    private final String UPD_STATUS_PARAMS = IgniteProperties.get("ignite.update.status.params");
-
     /** Throttling for logging out. */
     private static final long THROTTLE_PERIOD = 24 * 60 * 60 * 1000; // 1 day.
 
     /** Sleep milliseconds time for worker thread. */
     private static final int WORKER_THREAD_SLEEP_TIME = 5000;
 
-    /** Default url for request Ignite updates. */
-    private final static String DEFAULT_IGNITE_UPDATES_URL = "https://ignite.run/update_status_ignite-plain-text.php";
+    /** Default URL for request Ignite updates. */
+    private final static String DEFAULT_IGNITE_UPDATES_URL = "https://ignite.apache.org/latest";
+
+    /** Default HTTP parameter for request Ignite updates. */
+    private final static String DEFAULT_IGNITE_UPDATES_PARAMS = "?ver=";
 
     /** Grid version. */
     private final String ver;
 
+    /** Error during obtaining data. */
+    private volatile Exception err;
+
     /** Latest version. */
     private volatile String latestVer;
 
@@ -83,18 +68,6 @@ class GridUpdateNotifier {
     private volatile boolean reportOnlyNew;
 
     /** */
-    private volatile int topSize;
-
-    /** System properties */
-    private final String vmProps;
-
-    /** Plugins information for request */
-    private final String pluginsVers;
-
-    /** Kernal gateway */
-    private final GridKernalGateway gw;
-
-    /** */
     private long lastLog = -1;
 
     /** Command for worker thread. */
@@ -111,88 +84,50 @@ class GridUpdateNotifier {
      *
      * @param igniteInstanceName igniteInstanceName
      * @param ver Compound Ignite version.
-     * @param gw Kernal gateway.
-     * @param pluginProviders Kernal gateway.
      * @param reportOnlyNew Whether or not to report only new version.
      * @param updatesChecker Service for getting Ignite updates
      * @throws IgniteCheckedException If failed.
      */
-    GridUpdateNotifier(String igniteInstanceName, String ver, GridKernalGateway gw, Collection<PluginProvider> pluginProviders,
-                       boolean reportOnlyNew, HttpIgniteUpdatesChecker updatesChecker) throws IgniteCheckedException {
-        try {
-            this.ver = ver;
-            this.igniteInstanceName = igniteInstanceName == null ? "null" : igniteInstanceName;
-            this.gw = gw;
-            this.updatesChecker = updatesChecker;
-
-            SB pluginsBuilder = new SB();
-
-            for (PluginProvider provider : pluginProviders)
-                pluginsBuilder.a("&").a(provider.name() + "-plugin-version").a("=").
-                    a(encode(provider.version(), CHARSET));
-
-            pluginsVers = pluginsBuilder.toString();
-
-            this.reportOnlyNew = reportOnlyNew;
-
-            vmProps = getSystemProperties();
+    GridUpdateNotifier(
+        String igniteInstanceName,
+        String ver,
+        boolean reportOnlyNew,
+        HttpIgniteUpdatesChecker updatesChecker
+    ) throws IgniteCheckedException {
+        this.ver = ver;
+        this.igniteInstanceName = igniteInstanceName == null ? "null" : igniteInstanceName;
+        this.updatesChecker = updatesChecker;
+        this.reportOnlyNew = reportOnlyNew;
 
-            workerThread = new Thread(new Runnable() {
-                @Override public void run() {
-                    try {
-                        while(!Thread.currentThread().isInterrupted()) {
-                            Runnable cmd0 = cmd.getAndSet(null);
+        workerThread = new Thread(new Runnable() {
+            @Override public void run() {
+                try {
+                    while(!Thread.currentThread().isInterrupted()) {
+                        Runnable cmd0 = cmd.getAndSet(null);
 
-                            if (cmd0 != null)
-                                cmd0.run();
-                            else
-                                Thread.sleep(WORKER_THREAD_SLEEP_TIME);
-                        }
-                    }
-                    catch (InterruptedException ignore) {
-                        // No-op.
+                        if (cmd0 != null)
+                            cmd0.run();
+                        else
+                            Thread.sleep(WORKER_THREAD_SLEEP_TIME);
                     }
                 }
-            }, "upd-ver-checker");
+                catch (InterruptedException ignore) {
+                    // No-op.
+                }
+            }
+        }, "upd-ver-checker");
 
-            workerThread.setDaemon(true);
+        workerThread.setDaemon(true);
 
-            workerThread.start();
-        }
-        catch (UnsupportedEncodingException e) {
-            throw new IgniteCheckedException("Failed to encode.", e);
-        }
+        workerThread.start();
     }
 
     /**
      * Creates new notifier with default Ignite updates URL
      */
-    GridUpdateNotifier(String igniteInstanceName, String ver, GridKernalGateway gw, Collection<PluginProvider> pluginProviders,
-                       boolean reportOnlyNew) throws IgniteCheckedException {
-        this(igniteInstanceName, ver, gw, pluginProviders, reportOnlyNew, new HttpIgniteUpdatesChecker(DEFAULT_IGNITE_UPDATES_URL, CHARSET));
-    }
-
-    /**
-     * Gets system properties.
-     *
-     * @return System properties.
-     */
-    private static String getSystemProperties() {
-        try {
-            StringWriter sw = new StringWriter();
-
-            try {
-                IgniteSystemProperties.safeSnapshot().store(new PrintWriter(sw), "");
-            }
-            catch (IOException ignore) {
-                return null;
-            }
-
-            return sw.toString();
-        }
-        catch (SecurityException ignore) {
-            return null;
-        }
+    GridUpdateNotifier(String igniteInstanceName, String ver, boolean reportOnlyNew) throws IgniteCheckedException {
+        this(igniteInstanceName, ver, reportOnlyNew,
+            new HttpIgniteUpdatesChecker(DEFAULT_IGNITE_UPDATES_URL, DEFAULT_IGNITE_UPDATES_PARAMS + ver, CHARSET));
     }
 
     /**
@@ -203,31 +138,32 @@ class GridUpdateNotifier {
     }
 
     /**
-     * @param topSize Size of topology for license verification purpose.
+     * @return Latest version.
      */
-    void topologySize(int topSize) {
-        this.topSize = topSize;
+    String latestVersion() {
+        return latestVer;
     }
 
     /**
-     * @return Latest version.
+     * @return Error.
      */
-    String latestVersion() {
-        return latestVer;
+    Exception error() {
+        return err;
     }
 
     /**
      * Starts asynchronous process for retrieving latest version data.
      *
      * @param log Logger.
+     * @param first First checking.
      */
-    void checkForNewVersion(IgniteLogger log) {
+    void checkForNewVersion(IgniteLogger log, boolean first) {
         assert log != null;
 
         log = log.getLogger(getClass());
 
         try {
-            cmd.set(new UpdateChecker(log));
+            cmd.set(new UpdateChecker(log, first));
         }
         catch (RejectedExecutionException e) {
             U.error(log, "Failed to schedule a thread due to execution rejection (safely ignoring): " +
@@ -302,35 +238,29 @@ class GridUpdateNotifier {
         /** Logger. */
         private final IgniteLogger log;
 
+        /** First. */
+        private final boolean first;
+
         /**
          * Creates checked with given logger.
          *
          * @param log Logger.
          */
-        UpdateChecker(IgniteLogger log) {
+        UpdateChecker(IgniteLogger log, boolean first) {
             super(igniteInstanceName, "grid-version-checker", log);
 
             this.log = log.getLogger(getClass());
+            this.first = first;
         }
 
         /** {@inheritDoc} */
         @Override protected void body() throws InterruptedException {
             try {
-                String stackTrace = gw != null ? gw.userStackTrace() : null;
-
-                String postParams =
-                    "igniteInstanceName=" + encode(igniteInstanceName, CHARSET) +
-                    (!F.isEmpty(UPD_STATUS_PARAMS) ? "&" + UPD_STATUS_PARAMS : "") +
-                    (topSize > 0 ? "&topSize=" + topSize : "") +
-                    (!F.isEmpty(stackTrace) ? "&stackTrace=" + encode(stackTrace, CHARSET) : "") +
-                    (!F.isEmpty(vmProps) ? "&vmProps=" + encode(vmProps, CHARSET) : "") +
-                        pluginsVers;
-
                 if (!isCancelled()) {
                     try {
-                        String updatesResponse = updatesChecker.getUpdates(postParams);
+                        String updatesRes = updatesChecker.getUpdates(first);
 
-                        String[] lines = updatesResponse.split("\n");
+                        String[] lines = updatesRes.split("\n");
 
                         for (String line : lines) {
                             if (line.contains("version"))
@@ -338,14 +268,20 @@ class GridUpdateNotifier {
                             else if (line.contains("downloadUrl"))
                                 downloadUrl = obtainDownloadUrlFrom(line);
                         }
+
+                        err = null;
                     }
                     catch (IOException e) {
+                        err = e;
+
                         if (log.isDebugEnabled())
                             log.debug("Failed to connect to Ignite update server. " + e.getMessage());
                     }
                 }
             }
             catch (Exception e) {
+                err = e;
+
                 if (log.isDebugEnabled())
                     log.debug("Unexpected exception in update checker. " + e.getMessage());
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca832d5f/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/HttpIgniteUpdatesChecker.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/HttpIgniteUpdatesChecker.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/HttpIgniteUpdatesChecker.java
index 2b93ceb..5d6732e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/HttpIgniteUpdatesChecker.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/HttpIgniteUpdatesChecker.java
@@ -21,7 +21,6 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.io.OutputStream;
 import java.net.URL;
 import java.net.URLConnection;
 
@@ -32,6 +31,9 @@ public class HttpIgniteUpdatesChecker {
     /** Url for request updates. */
     private final String url;
 
+    /** Params. */
+    private final String params;
+
     /** Charset for encoding requests/responses */
     private final String charset;
 
@@ -40,43 +42,38 @@ public class HttpIgniteUpdatesChecker {
      * @param url URL for getting Ignite updates information
      * @param charset Charset for encoding
      */
-    HttpIgniteUpdatesChecker(String url, String charset) {
+    HttpIgniteUpdatesChecker(String url, String params, String charset) {
         this.url = url;
+        this.params = params;
         this.charset = charset;
     }
 
     /**
      * Gets information about Ignite updates via HTTP
-     * @param updateRequest HTTP Request parameters
      * @return Information about Ignite updates separated by line endings
      * @throws IOException If HTTP request was failed
      */
-    public String getUpdates(String updateRequest) throws IOException {
-        URLConnection conn = new URL(url).openConnection();
-        conn.setDoOutput(true);
+    public String getUpdates(boolean first) throws IOException {
+        String addr = first ? url + params : url;
+
+        URLConnection conn = new URL(addr).openConnection();
         conn.setRequestProperty("Accept-Charset", charset);
-        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);
 
         conn.setConnectTimeout(3000);
         conn.setReadTimeout(3000);
 
-        try (OutputStream os = conn.getOutputStream()) {
-            os.write(updateRequest.getBytes(charset));
-        }
-
         try (InputStream in = conn.getInputStream()) {
             if (in == null)
                 return null;
 
             BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset));
 
-            StringBuilder response = new StringBuilder();
+            StringBuilder res = new StringBuilder();
 
-            for (String line; (line = reader.readLine()) != null; ) {
-                response.append(line).append('\n');
-            }
+            for (String line; (line = reader.readLine()) != null; )
+                res.append(line).append('\n');
 
-            return response.toString();
+            return res.toString();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca832d5f/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifierSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifierSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifierSelfTest.java
index 1a20f26..f295b2b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifierSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cluster/GridUpdateNotifierSelfTest.java
@@ -17,19 +17,13 @@
 
 package org.apache.ignite.internal.processors.cluster;
 
-import java.util.Collections;
 import java.util.Properties;
 import org.apache.ignite.IgniteSystemProperties;
-import org.apache.ignite.internal.GridKernalGateway;
-import org.apache.ignite.internal.GridKernalState;
 import org.apache.ignite.internal.IgniteProperties;
-import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteProductVersion;
-import org.apache.ignite.plugin.PluginProvider;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.testframework.junits.common.GridCommonTest;
-import org.mockito.Matchers;
 import org.mockito.Mockito;
 
 /**
@@ -78,13 +72,12 @@ public class GridUpdateNotifierSelfTest extends GridCommonAbstractTest {
         HttpIgniteUpdatesChecker updatesCheckerMock = Mockito.mock(HttpIgniteUpdatesChecker.class);
 
         // Return current node version and some other info
-        Mockito.when(updatesCheckerMock.getUpdates(Matchers.anyString()))
+        Mockito.when(updatesCheckerMock.getUpdates(true))
                 .thenReturn("meta=meta" + "\n" + "version=" + nodeVer + "\n" + "downloadUrl=url");
 
-        GridUpdateNotifier ntf = new GridUpdateNotifier(null, nodeVer,
-            TEST_GATEWAY, Collections.<PluginProvider>emptyList(), false, updatesCheckerMock);
+        GridUpdateNotifier ntf = new GridUpdateNotifier(null, nodeVer, false, updatesCheckerMock);
 
-        ntf.checkForNewVersion(log);
+        ntf.checkForNewVersion(log, true);
 
         String ver = ntf.latestVersion();
 
@@ -108,41 +101,4 @@ public class GridUpdateNotifierSelfTest extends GridCommonAbstractTest {
 
         ntf.reportStatus(log);
     }
-
-    /**
-     * Test kernal gateway that always return uninitialized user stack trace.
-     */
-    private static final GridKernalGateway TEST_GATEWAY = new GridKernalGateway() {
-        @Override public void readLock() throws IllegalStateException {}
-
-        @Override public void readLockAnyway() {}
-
-        @Override public void setState(GridKernalState state) {}
-
-        @Override public GridKernalState getState() {
-            return null;
-        }
-
-        @Override public void readUnlock() {}
-
-        @Override public void writeLock() {}
-
-        @Override public void writeUnlock() {}
-
-        @Override public String userStackTrace() {
-            return null;
-        }
-
-        @Override public boolean tryWriteLock(long timeout) {
-            return false;
-        }
-
-        @Override public GridFutureAdapter<?> onDisconnected() {
-            return null;
-        }
-
-        @Override public void onReconnected() {
-            // No-op.
-        }
-    };
 }


[07/50] [abbrv] ignite git commit: IGNITE-6485: Binary marshalling with writeReplace/readResolve fixed. This closes #2778.

Posted by ag...@apache.org.
IGNITE-6485: Binary marshalling with writeReplace/readResolve fixed. This closes #2778.


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

Branch: refs/heads/ignite-6305
Commit: d7fbbd546126252af45cb48a5d173a7a66ad9838
Parents: 9160d5e
Author: Andrey Gura <ag...@apache.org>
Authored: Mon Oct 2 12:38:34 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Oct 2 12:38:34 2017 +0300

----------------------------------------------------------------------
 .../internal/binary/BinaryClassDescriptor.java  |   4 +-
 .../ignite/internal/util/IgniteUtils.java       |  43 ++++--
 .../binary/BinaryMarshallerSelfTest.java        | 136 +++++++++++++------
 3 files changed, 130 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d7fbbd54/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
index 4950a53..935211e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
@@ -344,9 +344,9 @@ public class BinaryClassDescriptor {
         Method writeReplaceMthd;
 
         if (mode == BinaryWriteMode.BINARY || mode == BinaryWriteMode.OBJECT) {
-            readResolveMtd = U.findNonPublicMethod(cls, "readResolve");
+            readResolveMtd = U.getNonPublicMethod(cls, "readResolve");
 
-            writeReplaceMthd = U.findNonPublicMethod(cls, "writeReplace");
+            writeReplaceMthd = U.getNonPublicMethod(cls, "writeReplace");
         }
         else {
             readResolveMtd = null;

http://git-wip-us.apache.org/repos/asf/ignite/blob/d7fbbd54/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 31b556d..bdcf87e 100755
--- 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
@@ -9407,22 +9407,14 @@ public abstract class IgniteUtils {
      * @param cls The class to search,
      * @param name Name of the method.
      * @param paramTypes Method parameters.
-     * @return Method or {@code null}
+     * @return Method or {@code null}.
      */
     @Nullable public static Method findNonPublicMethod(Class<?> cls, String name, Class<?>... paramTypes) {
         while (cls != null) {
-            try {
-                Method mtd = cls.getDeclaredMethod(name, paramTypes);
+            Method mtd = getNonPublicMethod(cls, name, paramTypes);
 
-                if (mtd.getReturnType() != void.class) {
-                    mtd.setAccessible(true);
-
-                    return mtd;
-                }
-            }
-            catch (NoSuchMethodException ignored) {
-                // No-op.
-            }
+            if (mtd != null)
+                return mtd;
 
             cls = cls.getSuperclass();
         }
@@ -9431,6 +9423,33 @@ public abstract class IgniteUtils {
     }
 
     /**
+     * Gets a method from the class.
+     *
+     * Method.getMethod() does not return non-public method.
+     *
+     * @param cls Target class.
+     * @param name Name of the method.
+     * @param paramTypes Method parameters.
+     * @return Method or {@code null}.
+     */
+    @Nullable public static Method getNonPublicMethod(Class<?> cls, String name, Class<?>... paramTypes) {
+        try {
+            Method mtd = cls.getDeclaredMethod(name, paramTypes);
+
+            if (mtd.getReturnType() != void.class) {
+                mtd.setAccessible(true);
+
+                return mtd;
+            }
+        }
+        catch (NoSuchMethodException ignored) {
+            // No-op.
+        }
+
+        return null;
+    }
+
+    /**
      * @param cls The class to search.
      * @param name Name of a field to get.
      * @return Field or {@code null}.

http://git-wip-us.apache.org/repos/asf/ignite/blob/d7fbbd54/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
index 926b3c0..ef68cd1 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
@@ -938,6 +938,23 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * @throws Exception If failed.
+     */
+    public void testWriteReplace() throws Exception {
+        BinaryMarshaller marsh = binaryMarshaller(Collections.singleton(
+            new BinaryTypeConfiguration(TestObject.class.getName())
+        ));
+
+        TestObject obj = new TestObject();
+
+        BinaryObject po = marshal(obj, marsh);
+
+        assertEquals(obj, po.deserialize());
+
+        assertEquals(obj.val, ((BinaryObject)po.field("val")).deserialize());
+    }
+
+    /**
      *
      */
     private static class EnclosingObj implements Serializable {
@@ -2626,19 +2643,6 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception If ecxeption thrown.
-     */
-    public void testDeclareReadResolveInParent() throws Exception {
-        BinaryMarshaller marsh = binaryMarshaller(Arrays.asList(new BinaryTypeConfiguration(ChildBinary.class.getName())));
-
-        BinaryObjectImpl binaryObj = marshal(new ChildBinary(), marsh);
-
-        ChildBinary singleton = binaryObj.deserialize();
-
-        assertNotNull(singleton.s);
-    }
-
-    /**
      *
      */
     public void testDecimalFields() throws Exception {
@@ -5117,13 +5121,6 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
     /**
      *
      */
-    public static class ChildBinary extends ParentBinary {
-
-    }
-
-    /**
-     *
-     */
     public static class SimpleEnclosingObject {
         /** */
         private Object simpl;
@@ -5180,25 +5177,6 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
     }
 
     /**
-     *
-     */
-    private static class ParentBinary {
-        /** */
-        public String s;
-
-        /**
-         * Package only visibility!!!!
-         *
-         * @return Object.
-         */
-        Object readResolve() {
-            s = "readResolve";
-
-            return this;
-        }
-    }
-
-    /**
      * Class B for duplicate fields test.
      */
     private static class DuplicateFieldsA {
@@ -5517,4 +5495,84 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
 
         abstract boolean isSupported();
     }
+
+    /** */
+    interface Intf {
+        /** */
+        long value();
+    }
+
+    /** */
+    static class TestObject {
+        /** Value. */
+        Intf val = new IntfImpl();
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o)
+                return true;
+            if (o == null || getClass() != o.getClass())
+                return false;
+
+            TestObject obj = (TestObject)o;
+
+            return val.equals(obj.val);
+        }
+    }
+
+    /** */
+    static class IntfImpl extends Cls implements Intf {
+        /** {@inheritDoc} */
+        @Override public long value() {
+            return longValue();
+        }
+    }
+
+    /** */
+    static class Cls implements Serializable {
+        /** Value. */
+        long val;
+
+        /** */
+        public long longValue() {
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o)
+                return true;
+            if (o == null || getClass() != o.getClass())
+                return false;
+
+            Cls cls = (Cls)o;
+
+            return val == cls.val;
+        }
+
+        /** */
+        private Object writeReplace() {
+            return new SerializationProxy(this);
+        }
+
+        /** */
+        private static class SerializationProxy implements Serializable {
+            /** Value. */
+            private final long val;
+
+            /** */
+            SerializationProxy(Cls a) {
+                val = a.longValue();
+            }
+
+            /** */
+            private Object readResolve() {
+                Cls a = new Cls();
+
+                a.val = val;
+
+                return a;
+            }
+        }
+    }
 }
\ No newline at end of file


[06/50] [abbrv] ignite git commit: IGNITE-6520: Using actual AffinityReadyFuture result

Posted by ag...@apache.org.
IGNITE-6520: Using actual AffinityReadyFuture result


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

Branch: refs/heads/ignite-6305
Commit: 9160d5eaf75d07ef16f6fe02b09aaa2ed76132b5
Parents: 013d7db
Author: Andrey Kuznetsov <st...@gmail.com>
Authored: Mon Oct 2 11:28:32 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Mon Oct 2 11:28:32 2017 +0300

----------------------------------------------------------------------
 .../cache/distributed/dht/GridPartitionedGetFuture.java        | 6 ++----
 .../cache/distributed/dht/GridPartitionedSingleGetFuture.java  | 6 ++----
 .../processors/cache/distributed/near/GridNearGetFuture.java   | 6 ++----
 3 files changed, 6 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/9160d5ea/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
index 73c0ea5..015eb82 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
@@ -713,17 +713,15 @@ public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAda
                 onDone(Collections.<K, V>emptyMap());
             }
             else {
-                final AffinityTopologyVersion updTopVer =
+                AffinityTopologyVersion updTopVer =
                     new AffinityTopologyVersion(Math.max(topVer.topologyVersion() + 1, cctx.discovery().topologyVersion()));
 
                 cctx.affinity().affinityReadyFuture(updTopVer).listen(
                     new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
                         @Override public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut) {
                             try {
-                                fut.get();
-
                                 // Remap.
-                                map(keys.keySet(), F.t(node, keys), updTopVer);
+                                map(keys.keySet(), F.t(node, keys), fut.get());
 
                                 onDone(Collections.<K, V>emptyMap());
                             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9160d5ea/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
index 234ee91..61489e5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedSingleGetFuture.java
@@ -703,16 +703,14 @@ public class GridPartitionedSingleGetFuture extends GridCacheFutureAdapter<Objec
             return false;
 
         if (canRemap) {
-            final AffinityTopologyVersion updTopVer = new AffinityTopologyVersion(
+            AffinityTopologyVersion updTopVer = new AffinityTopologyVersion(
                 Math.max(topVer.topologyVersion() + 1, cctx.discovery().topologyVersion()));
 
             cctx.affinity().affinityReadyFuture(updTopVer).listen(
                 new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
                     @Override public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut) {
                         try {
-                            fut.get();
-
-                            remap(updTopVer);
+                            remap(fut.get());
                         }
                         catch (IgniteCheckedException e) {
                             onDone(e);

http://git-wip-us.apache.org/repos/asf/ignite/blob/9160d5ea/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 807270d..2361507 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
@@ -917,17 +917,15 @@ public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdap
                 onDone(Collections.<K, V>emptyMap());
             }
             else {
-                final AffinityTopologyVersion updTopVer =
+                AffinityTopologyVersion updTopVer =
                     new AffinityTopologyVersion(Math.max(topVer.topologyVersion() + 1, cctx.discovery().topologyVersion()));
 
                 cctx.affinity().affinityReadyFuture(updTopVer).listen(
                     new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
                         @Override public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut) {
                             try {
-                                fut.get();
-
                                 // Remap.
-                                map(keys.keySet(), F.t(node, keys), updTopVer);
+                                map(keys.keySet(), F.t(node, keys), fut.get());
 
                                 onDone(Collections.<K, V>emptyMap());
                             }


[47/50] [abbrv] ignite git commit: IGNITE-6529: JDBC thin: fixed driver protocol compatibility. This closes #2819.

Posted by ag...@apache.org.
IGNITE-6529: JDBC thin: fixed driver protocol compatibility. This closes #2819.


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

Branch: refs/heads/ignite-6305
Commit: dc514c7083bc5529c886f6cce3d600663733e6d7
Parents: 3184437
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Mon Oct 9 15:14:23 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Oct 9 15:14:23 2017 +0300

----------------------------------------------------------------------
 .../internal/jdbc/thin/JdbcThinTcpIo.java       | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/dc514c70/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
index 688f908..9e12fbf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
@@ -49,6 +49,9 @@ public class JdbcThinTcpIo {
     /** Version 2.1.0. */
     private static final ClientListenerProtocolVersion VER_2_1_0 = ClientListenerProtocolVersion.create(2, 1, 0);
 
+    /** Version 2.1.5: added "lazy" flag. */
+    private static final ClientListenerProtocolVersion VER_2_1_5 = ClientListenerProtocolVersion.create(2, 1, 5);
+
     /** Version 2.3.1. */
     private static final ClientListenerProtocolVersion VER_2_3_0 = ClientListenerProtocolVersion.create(2, 3, 0);
 
@@ -180,22 +183,25 @@ public class JdbcThinTcpIo {
                 SqlStateCode.CLIENT_CONNECTION_FAILED, e);
         }
 
-        handshake();
+        handshake(CURRENT_VER);
     }
 
     /**
+     * Used for versions: 2.1.5 and 2.3.0. The protocol version is changed but handshake format isn't changed.
+     *
+     * @param ver JDBC client version.
      * @throws IOException On IO error.
      * @throws SQLException On connection reject.
      */
-    public void handshake() throws IOException, SQLException {
+    public void handshake(ClientListenerProtocolVersion ver) throws IOException, SQLException {
         BinaryWriterExImpl writer = new BinaryWriterExImpl(null, new BinaryHeapOutputStream(HANDSHAKE_MSG_SIZE),
             null, null);
 
         writer.writeByte((byte) ClientListenerRequest.HANDSHAKE);
 
-        writer.writeShort(CURRENT_VER.major());
-        writer.writeShort(CURRENT_VER.minor());
-        writer.writeShort(CURRENT_VER.maintenance());
+        writer.writeShort(ver.major());
+        writer.writeShort(ver.minor());
+        writer.writeShort(ver.maintenance());
 
         writer.writeByte(ClientListenerNioListener.JDBC_CLIENT);
 
@@ -238,7 +244,9 @@ public class JdbcThinTcpIo {
 
             ClientListenerProtocolVersion srvProtocolVer = ClientListenerProtocolVersion.create(maj, min, maintenance);
 
-            if (VER_2_1_0.equals(srvProtocolVer))
+            if (VER_2_1_5.equals(srvProtocolVer))
+                handshake(VER_2_1_5);
+            else if (VER_2_1_0.equals(srvProtocolVer))
                 handshake_2_1_0();
             else {
                 throw new SQLException("Handshake failed [driverProtocolVer=" + CURRENT_VER +


[43/50] [abbrv] ignite git commit: Fixed JavaDoc.

Posted by ag...@apache.org.
Fixed JavaDoc.


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

Branch: refs/heads/ignite-6305
Commit: e9764f159262e1aec12c8b418061294cc9914726
Parents: 85261a3
Author: devozerov <vo...@gridgain.com>
Authored: Mon Oct 9 10:48:06 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Oct 9 10:48:06 2017 +0300

----------------------------------------------------------------------
 .../cache/persistence/wal/serializer/RecordV2Serializer.java       | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e9764f15/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java
index 0a5bf01..a06b6d7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordV2Serializer.java
@@ -39,7 +39,7 @@ import static org.apache.ignite.internal.processors.cache.persistence.wal.serial
  * Record V2 serializer.
  * Stores records in following format:
  * <ul>
- * <li>Record type from {@link WALRecord.RecordType#ordinal()} incremented by 1</li>
+ * <li>Record type from {@link WALRecord.RecordType} incremented by 1</li>
  * <li>WAL pointer to double check consistency</li>
  * <li>Record length</li>
  * <li>Data</li>


[02/50] [abbrv] ignite git commit: IGNITE-5863 Fixed select ALL logic.

Posted by ag...@apache.org.
IGNITE-5863 Fixed select ALL logic.


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

Branch: refs/heads/ignite-6305
Commit: 2c393516f618820d27a2cb8ad58a22c046b4fe68
Parents: 4cb0fc73
Author: Dmitriy Shabalin <dm...@gmail.com>
Authored: Sun Oct 1 18:57:18 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Oct 2 13:56:37 2017 +0700

----------------------------------------------------------------------
 .../frontend/app/components/grid-item-selected/controller.js      | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/2c393516/modules/web-console/frontend/app/components/grid-item-selected/controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/grid-item-selected/controller.js b/modules/web-console/frontend/app/components/grid-item-selected/controller.js
index 4923924..0e8dadc 100644
--- a/modules/web-console/frontend/app/components/grid-item-selected/controller.js
+++ b/modules/web-console/frontend/app/components/grid-item-selected/controller.js
@@ -27,7 +27,10 @@ export default class {
             this.applyValues();
 
             this.gridApi.grid.registerDataChangeCallback(() => this.applyValues(), [this.uiGridConstants.dataChange.ROW]);
+            // Used to toggle selected of one row.
             this.gridApi.selection.on.rowSelectionChanged(this.$scope, () => this.applyValues());
+            // Used to toggle all selected of rows.
+            this.gridApi.selection.on.rowSelectionChangedBatch(this.$scope, () => this.applyValues());
         }
     }
 


[35/50] [abbrv] ignite git commit: IGNITE-6553 Standalone WAL iterator fails to handle WAL delete data records - Fixes #2797.

Posted by ag...@apache.org.
IGNITE-6553 Standalone WAL iterator fails to handle WAL delete data records - Fixes #2797.


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

Branch: refs/heads/ignite-6305
Commit: 49b835812a607a116c4dbc99ce60ed1684229b34
Parents: 474479c
Author: dpavlov <dp...@gridgain.com>
Authored: Thu Oct 5 18:10:25 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Oct 5 18:11:58 2017 +0300

----------------------------------------------------------------------
 .../internal/pagemem/wal/record/DataEntry.java  | 13 ++++++------
 .../pagemem/wal/record/UnwrapDataEntry.java     | 22 +++++++++++++-------
 .../reader/StandaloneWalRecordsIterator.java    | 11 +++++++---
 .../db/wal/reader/IgniteWalReaderTest.java      | 14 ++++++++++---
 4 files changed, 41 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/49b83581/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/DataEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/DataEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/DataEntry.java
index d4e0b9f..cb6b482 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/DataEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/DataEntry.java
@@ -23,6 +23,7 @@ import org.apache.ignite.internal.processors.cache.KeyCacheObject;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * Represents Data Entry ({@link #key}, {@link #val value}) pair update {@link #op operation} in WAL log.
@@ -32,13 +33,13 @@ public class DataEntry {
     @GridToStringInclude
     protected int cacheId;
 
-    /** Cache object key */
+    /** Cache object key. */
     protected KeyCacheObject key;
 
-    /** Cache object value */
-    protected CacheObject val;
+    /** Cache object value. May be {@code} null for {@link GridCacheOperation#DELETE} */
+    @Nullable protected CacheObject val;
 
-    /** Entry operation performed */
+    /** Entry operation performed. */
     @GridToStringInclude
     protected GridCacheOperation op;
 
@@ -67,7 +68,7 @@ public class DataEntry {
     /**
      * @param cacheId Cache ID.
      * @param key Key.
-     * @param val Value.
+     * @param val Value or null for delete operation.
      * @param op Operation.
      * @param nearXidVer Near transaction version.
      * @param writeVer Write version.
@@ -78,7 +79,7 @@ public class DataEntry {
     public DataEntry(
         int cacheId,
         KeyCacheObject key,
-        CacheObject val,
+        @Nullable CacheObject val,
         GridCacheOperation op,
         GridCacheVersion nearXidVer,
         GridCacheVersion writeVer,

http://git-wip-us.apache.org/repos/asf/ignite/blob/49b83581/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/UnwrapDataEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/UnwrapDataEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/UnwrapDataEntry.java
index 678539d..dbcc651 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/UnwrapDataEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/UnwrapDataEntry.java
@@ -31,13 +31,13 @@ public class UnwrapDataEntry extends DataEntry {
     /** Cache object value context. Context is used for unwrapping objects. */
     private final CacheObjectValueContext cacheObjValCtx;
 
-    /** Keep binary. This flag disables converting of non primitive types (BinaryObjects) */
+    /** Keep binary. This flag disables converting of non primitive types (BinaryObjects). */
     private boolean keepBinary;
 
     /**
      * @param cacheId Cache ID.
      * @param key Key.
-     * @param val Value.
+     * @param val Value or null for delete operation.
      * @param op Operation.
      * @param nearXidVer Near transaction version.
      * @param writeVer Write version.
@@ -45,7 +45,7 @@ public class UnwrapDataEntry extends DataEntry {
      * @param partId Partition ID.
      * @param partCnt Partition counter.
      * @param cacheObjValCtx cache object value context for unwrapping objects.
-     * @param keepBinary disable unwrapping for non primitive objects, Binary Objects would be returned instead
+     * @param keepBinary disable unwrapping for non primitive objects, Binary Objects would be returned instead.
      */
     public UnwrapDataEntry(
         final int cacheId,
@@ -66,39 +66,47 @@ public class UnwrapDataEntry extends DataEntry {
 
     /**
      * Unwraps key value from cache key object into primitive boxed type or source class. If client classes were used
-     * in key, call of this method requires classes to be available in classpath
+     * in key, call of this method requires classes to be available in classpath.
      *
-     * @return Key which was placed into cache. Or null if failed
+     * @return Key which was placed into cache. Or null if failed to convert.
      */
     public Object unwrappedKey() {
         try {
             if (keepBinary && key instanceof BinaryObject)
                 return key;
+
             Object unwrapped = key.value(cacheObjValCtx, false);
+
             if (unwrapped instanceof BinaryObject) {
                 if (keepBinary)
                     return unwrapped;
                 unwrapped = ((BinaryObject)unwrapped).deserialize();
             }
+
             return unwrapped;
         }
         catch (Exception e) {
             cacheObjValCtx.kernalContext().log(UnwrapDataEntry.class)
                 .error("Unable to convert key [" + key + "]", e);
+
             return null;
         }
     }
 
     /**
      * Unwraps value value from cache value object into primitive boxed type or source class. If client classes were
-     * used in key, call of this method requires classes to be available in classpath
+     * used in key, call of this method requires classes to be available in classpath.
      *
-     * @return Value which was placed into cache. Or null if failed
+     * @return Value which was placed into cache. Or null for delete operation or for failure.
      */
     public Object unwrappedValue() {
         try {
+            if (val == null)
+                return null;
+
             if (keepBinary && val instanceof BinaryObject)
                 return val;
+
             return val.value(cacheObjValCtx, false);
         }
         catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/49b83581/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
index 42bb410..a4d9e95 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
@@ -335,12 +335,17 @@ class StandaloneWalRecordsIterator extends AbstractWalRecordsIterator {
 
         if (dataEntry instanceof LazyDataEntry) {
             final LazyDataEntry lazyDataEntry = (LazyDataEntry)dataEntry;
+
             key = processor.toKeyCacheObject(fakeCacheObjCtx,
                 lazyDataEntry.getKeyType(),
                 lazyDataEntry.getKeyBytes());
-            val = processor.toCacheObject(fakeCacheObjCtx,
-                lazyDataEntry.getValType(),
-                lazyDataEntry.getValBytes());
+
+            final byte type = lazyDataEntry.getValType();
+
+            val = type == 0 ? null :
+                processor.toCacheObject(fakeCacheObjCtx,
+                    type,
+                    lazyDataEntry.getValBytes());
         }
         else {
             key = dataEntry.key();

http://git-wip-us.apache.org/repos/asf/ignite/blob/49b83581/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
index 93df8b2..79387e3 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/reader/IgniteWalReaderTest.java
@@ -356,6 +356,7 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
 
         cache0.putAll(values);
     }
+
     /**
      * Puts provided number of records to fill WAL under transactions
      *
@@ -912,8 +913,16 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
             deletesFound != null && deletesFound > 0);
     }
 
-    @NotNull private IgniteWalIteratorFactory createWalIteratorFactory(String subfolderName,
-        String workDir) throws IgniteCheckedException {
+    /**
+     * @param subfolderName Subfolder name.
+     * @param workDir Work directory.
+     * @return WAL iterator factory.
+     * @throws IgniteCheckedException If failed.
+     */
+    @NotNull private IgniteWalIteratorFactory createWalIteratorFactory(
+        String subfolderName,
+        String workDir
+    ) throws IgniteCheckedException {
         final File binaryMeta = U.resolveWorkDirectory(workDir, "binary_meta", false);
         final File binaryMetaWithConsId = new File(binaryMeta, subfolderName);
         final File marshallerMapping = U.resolveWorkDirectory(workDir, "marshaller", false);
@@ -924,7 +933,6 @@ public class IgniteWalReaderTest extends GridCommonAbstractTest {
             marshallerMapping);
     }
 
-
     /**
      * @param values collection with numbers
      * @return sum of numbers