You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2017/08/30 16:01:28 UTC

[1/6] ignite git commit: IGNITE-6193 ML profile is missing in 2.1 binary release [Forced Update!]

Repository: ignite
Updated Branches:
  refs/heads/ignite-5896 757f56a4e -> 085cc80e5 (forced update)


IGNITE-6193 ML profile is missing in 2.1 binary release

(cherry picked from commit c06ceba)


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

Branch: refs/heads/ignite-5896
Commit: b7d198ea3dc70ec1ceb28cb9def26c315ea5d365
Parents: 08a831f
Author: Oleg Ignatenko <oi...@gridgain.com>
Authored: Wed Aug 30 14:15:32 2017 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Wed Aug 30 14:17:29 2017 +0300

----------------------------------------------------------------------
 examples/pom.xml | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b7d198ea/examples/pom.xml
----------------------------------------------------------------------
diff --git a/examples/pom.xml b/examples/pom.xml
index f15edeb..170391d 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -103,6 +103,7 @@
         <spark.test.folder>src/test/java</spark.test.folder>
         <lgpl.test.folder>src/test/java</lgpl.test.folder>
         <java8.test.folder>src/test/java</java8.test.folder>
+        <ml.folder>src/main/java</ml.folder>
     </properties>
 
     <profiles>
@@ -234,6 +235,23 @@
         </profile>
 
         <profile>
+            <id>ml</id>
+
+            <properties>
+                <ml.folder>src/main/ml</ml.folder>
+                <java.ver>1.8</java.ver>
+            </properties>
+
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.ignite</groupId>
+                    <artifactId>ignite-ml</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+
+        <profile>
             <id>lgpl</id>
 
             <properties>
@@ -292,6 +310,7 @@
                                 <source>${lgpl.folder}</source>
                                 <source>${java8.folder}</source>
                                 <source>${spark.folder}</source>
+                                <source>${ml.folder}</source>
                             </sources>
                         </configuration>
                     </execution>


[5/6] ignite git commit: IGNITE-5899 Thin client: cache.Get for primitives

Posted by pt...@apache.org.
IGNITE-5899 Thin client: cache.Get for primitives

This closes #2376


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

Branch: refs/heads/ignite-5896
Commit: bb6f3fa8d6a634f2112d5764f4548a3860ee244e
Parents: eae6e3b
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Tue Aug 29 18:57:07 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Wed Aug 30 18:59:49 2017 +0300

----------------------------------------------------------------------
 .../processors/odbc/SqlListenerNioListener.java |  15 +-
 .../platform/client/ClientCacheRequest.java     |  54 ++++++
 .../platform/client/ClientGetRequest.java       |  48 ++++++
 .../platform/client/ClientGetResponse.java      |  46 +++++
 .../platform/client/ClientMessageParser.java    |  83 +++++++++
 .../platform/client/ClientRequest.java          |  58 +++++++
 .../platform/client/ClientRequestHandler.java   |  58 +++++++
 .../platform/client/ClientResponse.java         |  49 ++++++
 .../Apache.Ignite.Core.Tests.csproj             |   1 +
 .../Client/RawSocketTest.cs                     | 167 +++++++++++++++++++
 10 files changed, 577 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/bb6f3fa8/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java
index 8dad71b..3e8299c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java
@@ -32,6 +32,8 @@ import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMessageParser;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequestHandler;
 import org.apache.ignite.internal.processors.odbc.odbc.OdbcMessageParser;
 import org.apache.ignite.internal.processors.odbc.odbc.OdbcRequestHandler;
+import org.apache.ignite.internal.processors.platform.client.ClientMessageParser;
+import org.apache.ignite.internal.processors.platform.client.ClientRequestHandler;
 import org.apache.ignite.internal.util.GridSpinBusyLock;
 import org.apache.ignite.internal.util.nio.GridNioServerListenerAdapter;
 import org.apache.ignite.internal.util.nio.GridNioSession;
@@ -42,10 +44,10 @@ import org.jetbrains.annotations.Nullable;
  * SQL message listener.
  */
 public class SqlListenerNioListener extends GridNioServerListenerAdapter<byte[]> {
-    /** The value corresponds to ODBC driver of the parser field of the handshake request. */
+    /** ODBC driver handshake code. */
     public static final byte ODBC_CLIENT = 0;
 
-    /** The value corresponds to JDBC driver of the parser field of the handshake request. */
+    /** JDBC driver handshake code. */
     public static final byte JDBC_CLIENT = 1;
 
     /** Version 2.1.0. */
@@ -54,6 +56,9 @@ public class SqlListenerNioListener extends GridNioServerListenerAdapter<byte[]>
     /** Version 2.1.5: added "lazy" flag. */
     private static final SqlListenerProtocolVersion VER_2_1_5 = SqlListenerProtocolVersion.create(2, 1, 5);
 
+    /** Thin client handshake code. */
+    public static final byte THIN_CLIENT = 2;
+
     /** Current version. */
     private static final SqlListenerProtocolVersion CURRENT_VER = VER_2_1_5;
 
@@ -278,6 +283,12 @@ public class SqlListenerNioListener extends GridNioServerListenerAdapter<byte[]>
 
             return new SqlListenerConnectionContext(handler, parser);
         }
+        else if (clientType == THIN_CLIENT) {
+            ClientMessageParser parser = new ClientMessageParser(ctx);
+            ClientRequestHandler handler = new ClientRequestHandler(ctx);
+
+            return new SqlListenerConnectionContext(handler, parser);
+        }
         else
             throw new IgniteException("Unknown client type: " + clientType);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb6f3fa8/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientCacheRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientCacheRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientCacheRequest.java
new file mode 100644
index 0000000..7036853
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientCacheRequest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.platform.client;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.binary.BinaryRawReader;
+import org.apache.ignite.internal.GridKernalContext;
+
+/**
+ * Cache get request.
+ */
+class ClientCacheRequest extends ClientRequest {
+    /** */
+    private final int cacheId;
+
+    /**
+     * Ctor.
+     *
+     * @param reader Reader.
+     */
+    ClientCacheRequest(BinaryRawReader reader) {
+        super(reader);
+
+        cacheId = reader.readInt();
+        reader.readByte();  // Flags (skipStore, etc);
+    }
+
+    /**
+     * Gets the cache for current cache id.
+     *
+     * @param ctx Kernal context.
+     * @return Cache.
+     */
+    protected IgniteCache getCache(GridKernalContext ctx) {
+        String cacheName = ctx.cache().context().cacheContext(cacheId).cache().name();
+
+        return ctx.grid().cache(cacheName).withKeepBinary();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb6f3fa8/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientGetRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientGetRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientGetRequest.java
new file mode 100644
index 0000000..72d3507
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientGetRequest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.platform.client;
+
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.binary.BinaryRawReaderEx;
+
+/**
+ * Cache get request.
+ */
+class ClientGetRequest extends ClientCacheRequest {
+    /** */
+    private final Object key;
+
+    /**
+     * Ctor.
+     *
+     * @param reader Reader.
+     */
+    ClientGetRequest(BinaryRawReaderEx reader) {
+        super(reader);
+
+        key = reader.readObjectDetached();
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public ClientResponse process(GridKernalContext ctx) {
+        Object val = getCache(ctx).get(key);
+
+        return new ClientGetResponse(getRequestId(), val);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb6f3fa8/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientGetResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientGetResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientGetResponse.java
new file mode 100644
index 0000000..58a3062
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientGetResponse.java
@@ -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.
+ */
+
+package org.apache.ignite.internal.processors.platform.client;
+
+import org.apache.ignite.binary.BinaryRawWriter;
+
+/**
+ * Cache get response.
+ */
+class ClientGetResponse extends ClientResponse {
+    /** */
+    private final Object val;
+
+    /**
+     * Ctor.
+     *
+     * @param requestId Request id.
+     */
+    ClientGetResponse(int requestId, Object val) {
+        super(requestId);
+
+        this.val = val;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void encode(BinaryRawWriter writer) {
+        super.encode(writer);
+
+        writer.writeObject(val);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb6f3fa8/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java
new file mode 100644
index 0000000..5ad7ba9
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.platform.client;
+
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.binary.BinaryRawWriter;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.binary.BinaryRawReaderEx;
+import org.apache.ignite.internal.binary.GridBinaryMarshaller;
+import org.apache.ignite.internal.binary.streams.BinaryHeapInputStream;
+import org.apache.ignite.internal.binary.streams.BinaryHeapOutputStream;
+import org.apache.ignite.internal.binary.streams.BinaryInputStream;
+import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
+import org.apache.ignite.internal.processors.odbc.SqlListenerMessageParser;
+import org.apache.ignite.internal.processors.odbc.SqlListenerRequest;
+import org.apache.ignite.internal.processors.odbc.SqlListenerResponse;
+
+/**
+ * Thin client message parser.
+ */
+public class ClientMessageParser implements SqlListenerMessageParser {
+    /** */
+    private static final short OP_CACHE_GET = 1;
+
+    /** Marshaller. */
+    private final GridBinaryMarshaller marsh;
+
+    /**
+     * Ctor.
+     *
+     * @param ctx Kernal context.
+     */
+    public ClientMessageParser(GridKernalContext ctx) {
+        assert ctx != null;
+
+        CacheObjectBinaryProcessorImpl cacheObjProc = (CacheObjectBinaryProcessorImpl)ctx.cacheObjects();
+        marsh = cacheObjProc.marshaller();
+    }
+
+    /** {@inheritDoc} */
+    @Override public SqlListenerRequest decode(byte[] msg) {
+        assert msg != null;
+
+        BinaryInputStream inStream = new BinaryHeapInputStream(msg);
+        BinaryRawReaderEx reader = marsh.reader(inStream);
+
+        short opCode = reader.readShort();
+
+        switch (opCode) {
+            case OP_CACHE_GET: {
+                return new ClientGetRequest(reader);
+            }
+        }
+
+        throw new IgniteException("Invalid operation: " + opCode);
+    }
+
+    /** {@inheritDoc} */
+    @Override public byte[] encode(SqlListenerResponse resp) {
+        BinaryHeapOutputStream outStream = new BinaryHeapOutputStream(32);
+
+        BinaryRawWriter writer = marsh.writer(outStream);
+
+        ((ClientResponse)resp).encode(writer);
+
+        return outStream.array();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb6f3fa8/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequest.java
new file mode 100644
index 0000000..f542850
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequest.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.processors.platform.client;
+
+import org.apache.ignite.binary.BinaryRawReader;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.processors.odbc.SqlListenerRequest;
+
+/**
+ * Thin client request.
+ */
+class ClientRequest extends SqlListenerRequest {
+    /** Request id. */
+    private final int requestId;
+
+    /**
+     * Ctor.
+     *
+     * @param reader Reader.
+     */
+    ClientRequest(BinaryRawReader reader) {
+        reader.readByte();  //  Flags: Compression, etc.
+        requestId = reader.readInt();
+    }
+
+    /**
+     * Gets the request id.
+     *
+     * @return Data.
+     */
+    public int getRequestId() {
+        return requestId;
+    }
+
+    /**
+     * Processes the request.
+     *
+     * @return Response.
+     */
+    public ClientResponse process(GridKernalContext ctx) {
+        return new ClientResponse(requestId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb6f3fa8/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.java
new file mode 100644
index 0000000..7f019cf
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.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.processors.platform.client;
+
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.processors.odbc.SqlListenerRequest;
+import org.apache.ignite.internal.processors.odbc.SqlListenerRequestHandler;
+import org.apache.ignite.internal.processors.odbc.SqlListenerResponse;
+
+/**
+ * Thin client request handler.
+ */
+public class ClientRequestHandler implements SqlListenerRequestHandler {
+    /** Kernal context. */
+    private final GridKernalContext ctx;
+
+    /**
+     * Ctor.
+     *
+     * @param ctx Kernal context.
+     */
+    public ClientRequestHandler(GridKernalContext ctx) {
+        assert ctx != null;
+
+        this.ctx = ctx;
+    }
+
+    /** {@inheritDoc} */
+    @Override public SqlListenerResponse handle(SqlListenerRequest req) {
+        return ((ClientRequest)req).process(ctx);
+    }
+
+    /** {@inheritDoc} */
+    @Override public SqlListenerResponse handleException(Exception e) {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeHandshake(BinaryWriterExImpl writer) {
+        writer.writeBoolean(true);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb6f3fa8/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientResponse.java
new file mode 100644
index 0000000..2fe65c7
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientResponse.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.platform.client;
+
+import org.apache.ignite.binary.BinaryRawWriter;
+import org.apache.ignite.internal.processors.odbc.SqlListenerResponse;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Thin client response.
+ */
+class ClientResponse extends SqlListenerResponse {
+    /** Request id. */
+    private final int requestId;
+
+    /**
+     * Ctor.
+     *
+     * @param requestId Request id.
+     */
+    ClientResponse(int requestId) {
+        super(STATUS_SUCCESS, null);
+
+        this.requestId = requestId;
+    }
+
+    /**
+     * Encodes the response data.
+     */
+    public void encode(BinaryRawWriter writer) {
+        writer.writeInt(requestId);
+        writer.writeByte((byte)0);  // Flags (compression, etc);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb6f3fa8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
index 3f5f9b3..f704005 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
@@ -92,6 +92,7 @@
     <Compile Include="Cache\Query\Linq\CacheLinqTest.Contains.cs" />
     <Compile Include="Cache\Store\CacheStoreSessionTestCodeConfig.cs" />
     <Compile Include="Cache\Store\CacheStoreSessionTestSharedFactory.cs" />
+    <Compile Include="Client\RawSocketTest.cs" />
     <Compile Include="Deployment\CacheGetFunc.cs" />
     <Compile Include="Deployment\GetAddressFunc.cs" />
     <Compile Include="Deployment\PeerAssemblyLoadingAllApisTest.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb6f3fa8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSocketTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSocketTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSocketTest.cs
new file mode 100644
index 0000000..9d8c427
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSocketTest.cs
@@ -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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Client
+{
+    using System;
+    using System.Net;
+    using System.Net.Sockets;
+    using Apache.Ignite.Core.Cache.Configuration;
+    using Apache.Ignite.Core.Configuration;
+    using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Impl.Binary;
+    using Apache.Ignite.Core.Impl.Binary.IO;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests the thin client mode with a raw socket.
+    /// </summary>
+    public class RawSocketTest
+    {
+        /// <summary>
+        /// Tests the socket handshake connection.
+        /// </summary>
+        [Test]
+        public void TestCacheGet()
+        {
+            var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
+            {
+                SqlConnectorConfiguration = new SqlConnectorConfiguration()
+            };
+
+            using (var ignite = Ignition.Start(cfg))
+            {
+                var marsh = ((Ignite) ignite).Marshaller;
+
+                // Create cache.
+                var cacheCfg = new CacheConfiguration("foo", new QueryEntity(typeof(int), typeof(string)));
+                var cache = ignite.CreateCache<int, string>(cacheCfg);
+                cache[1] = "bar";
+
+                // Connect socket.
+                var sock = GetSocket(SqlConnectorConfiguration.DefaultPort);
+                Assert.IsTrue(sock.Connected);
+
+                DoHandshake(sock);
+
+                // Cache get.
+                SendRequest(sock, stream =>
+                {
+                    stream.WriteShort(1);  // OP_GET
+                    stream.WriteByte(0); // Flags (compression, etc)
+                    stream.WriteInt(1);  // Request id.
+                    var cacheId = BinaryUtils.GetStringHashCode(cache.Name);
+                    stream.WriteInt(cacheId);
+                    stream.WriteByte(0);  // Flags (withSkipStore, etc)
+
+                    var writer = marsh.StartMarshal(stream);
+
+                    writer.WriteObject(1);  // Key
+                });
+
+                var msg = ReceiveMessage(sock);
+                
+                using (var stream = new BinaryHeapStream(msg))
+                {
+                    var reader = marsh.StartUnmarshal(stream);
+
+                    int requestId = reader.ReadInt();
+                    Assert.AreEqual(1, requestId);
+
+                    reader.ReadByte(); // Flags
+
+                    var res = reader.ReadObject<string>();
+                    Assert.AreEqual(cache[1], res);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Does the handshake.
+        /// </summary>
+        /// <param name="sock">The sock.</param>
+        private static void DoHandshake(Socket sock)
+        {
+            var sentBytes = SendRequest(sock, stream =>
+            {
+                // Handshake.
+                stream.WriteByte(1);
+
+                // Protocol version.
+                stream.WriteShort(2);
+                stream.WriteShort(1);
+                stream.WriteShort(0);
+
+                // Client type: platform.
+                stream.WriteByte(2);
+            });
+
+            Assert.AreEqual(12, sentBytes);
+
+            // ACK.
+            var ack = ReceiveMessage(sock);
+
+            Assert.AreEqual(1, ack.Length);
+            Assert.AreEqual(1, ack[0]);
+        }
+
+        /// <summary>
+        /// Receives the message.
+        /// </summary>
+        private static byte[] ReceiveMessage(Socket sock)
+        {
+            var buf = new byte[4];
+            sock.Receive(buf);
+
+            using (var stream = new BinaryHeapStream(buf))
+            {
+                var size = stream.ReadInt();
+                buf = new byte[size];
+                sock.Receive(buf);
+                return buf;
+            }
+        }
+
+        /// <summary>
+        /// Sends the request.
+        /// </summary>
+        private static int SendRequest(Socket sock, Action<BinaryHeapStream> writeAction)
+        {
+            using (var stream = new BinaryHeapStream(128))
+            {
+                stream.WriteInt(0);  // Reserve message size.
+
+                writeAction(stream);
+
+                stream.WriteInt(0, stream.Position - 4);  // Write message size.
+
+                return sock.Send(stream.GetArray(), stream.Position, SocketFlags.None);
+            }
+        }
+
+        /// <summary>
+        /// Gets the socket.
+        /// </summary>
+        private static Socket GetSocket(int port)
+        {
+            var endPoint = new IPEndPoint(IPAddress.Loopback, port);
+            var sock = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+            sock.Connect(endPoint);
+            return sock;
+        }
+    }
+}


[4/6] ignite git commit: IGNITE-5931 .NET: Fix type registration race condition

Posted by pt...@apache.org.
IGNITE-5931 .NET: Fix type registration race condition

This closes #2553


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

Branch: refs/heads/ignite-5896
Commit: eae6e3b9fd43b42fc9d74e61118800dc0f3f6f0c
Parents: d253c02
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Wed Aug 30 18:35:05 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Wed Aug 30 18:35:05 2017 +0300

----------------------------------------------------------------------
 .../Binary/BinaryDynamicRegistrationTest.cs     | 49 ++++++++++++++++++++
 .../Binary/BinarySelfTest.cs                    | 12 -----
 .../Cache/Affinity/AffinityFieldTest.cs         | 10 +++-
 .../Impl/Binary/Marshaller.cs                   | 43 ++++++++++-------
 4 files changed, 84 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/eae6e3b9/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs
index 4f458f4..01804b7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryDynamicRegistrationTest.cs
@@ -25,6 +25,8 @@ namespace Apache.Ignite.Core.Tests.Binary
     using System.Collections.Generic;
     using System.IO;
     using System.Linq;
+    using System.Threading;
+    using System.Threading.Tasks;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cache.Configuration;
     using Apache.Ignite.Core.Cache.Store;
@@ -357,6 +359,53 @@ namespace Apache.Ignite.Core.Tests.Binary
         }
 
         /// <summary>
+        /// Tests registration in multiple threads.
+        /// </summary>
+        [Test]
+        public void TestRegistrationMultithreaded([Values(true, false)] bool useTypeName)
+        {
+            const int iterations = 50;
+            const int threads = 4;
+
+            using (var ignite = Ignition.Start(TestUtils.GetTestConfiguration()))
+            {
+                var cache = ignite.CreateCache<int, int>("c").WithKeepBinary<int, IBinaryObject>();
+                var bin = ignite.GetBinary();
+                Func<Type, IBinaryObjectBuilder> getBuilder = x =>
+                    useTypeName ? bin.GetBuilder(x.FullName) : bin.GetBuilder(x);
+                    
+                var types = new[] { typeof(Foo), typeof(Bar), typeof(Bin) };
+
+                foreach (var type in types)
+                {
+                    var type0 = type;  // Modified closure.
+
+                    for (var i = 0; i < iterations; i++)
+                    {
+                        var countdown = new CountdownEvent(threads);
+
+                        Action registerType = () =>
+                        {
+                            countdown.Signal();
+                            Assert.IsTrue(countdown.Wait(5000));
+
+                            var binObj = getBuilder(type0).SetIntField("x", 1).Build();
+                            cache[1] = binObj;
+
+                            Assert.AreEqual(binObj, cache[1]);
+                        };
+
+                        var tasks = Enumerable.Range(0, threads)
+                            .Select(x => Task.Factory.StartNew(registerType))
+                            .ToArray();
+
+                        Task.WaitAll(tasks);
+                    }
+                }
+            }
+        }
+
+        /// <summary>
         /// Tests the type registration.
         /// </summary>
         private static void Test(IIgnite ignite1, IIgnite ignite2)

http://git-wip-us.apache.org/repos/asf/ignite/blob/eae6e3b9/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
index e24dca0..4237eda 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
@@ -1534,18 +1534,6 @@ namespace Apache.Ignite.Core.Tests.Binary
             Assert.AreEqual(nDateArr, obj2.NDateArr);
         }
 
-        [Test]
-        public void TestBinaryConfigurationValidation()
-        {
-            var cfg = new BinaryConfiguration(typeof (PropertyType))
-            {
-                Types = new[] {typeof(PropertyType).AssemblyQualifiedName}
-            };
-
-            // ReSharper disable once ObjectCreationAsStatement
-            Assert.Throws<BinaryObjectException>(() => new Marshaller(cfg));
-        }
-
         /// <summary>
         /// Tests the compact footer setting.
         /// </summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/eae6e3b9/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFieldTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFieldTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFieldTest.cs
index 31326b7..c3482bb 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFieldTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFieldTest.cs
@@ -76,7 +76,8 @@ namespace Apache.Ignite.Core.Tests.Cache.Affinity
             _cache1.Put(new CacheKeyAttrOverride(), string.Empty);
 
             // Verify
-            foreach (var type in new[] { typeof(CacheKey) , typeof(CacheKeyAttr), typeof(CacheKeyAttrOverride)})
+            foreach (var type in new[] { typeof(CacheKey), typeof(CacheKeyAttr), 
+                typeof(CacheKeyAttrDynamicRegistration), typeof(CacheKeyAttrOverride)})
             {
                 Assert.AreEqual("AffinityKey", _cache1.Ignite.GetBinary().GetBinaryType(type).AffinityKeyFieldName);
                 Assert.AreEqual("AffinityKey", _cache2.Ignite.GetBinary().GetBinaryType(type).AffinityKeyFieldName);
@@ -91,6 +92,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Affinity
         {
             TestKeyLocation0((key, affKey) => new CacheKey {Key = key, AffinityKey = affKey});
             TestKeyLocation0((key, affKey) => new CacheKeyAttr {Key = key, AffinityKey = affKey});
+            TestKeyLocation0((key, affKey) => new CacheKeyAttrDynamicRegistration {Key = key, AffinityKey = affKey});
             TestKeyLocation0((key, affKey) => new CacheKeyAttrOverride {Key = key, AffinityKey = affKey});
         }
 
@@ -190,6 +192,12 @@ namespace Apache.Ignite.Core.Tests.Cache.Affinity
             [AffinityKeyMapped] public int AffinityKey { get; set; }
         }
 
+        private class CacheKeyAttrDynamicRegistration
+        {
+            public int Key { get; set; }
+            [AffinityKeyMapped] public int AffinityKey { get; set; }
+        }
+
         private class CacheKeyAttrOverride
         {
             [AffinityKeyMapped] public int Key { get; set; }

http://git-wip-us.apache.org/repos/asf/ignite/blob/eae6e3b9/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
index 5ede542..a6d5517 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
@@ -503,21 +503,28 @@ namespace Apache.Ignite.Core.Impl.Binary
 
             desc = desc == null
                 ? new BinaryFullTypeDescriptor(type, typeId, typeName, true, _cfg.NameMapper,
-                    _cfg.IdMapper, ser, false, null, BinaryUtils.IsIgniteEnum(type), registered)
+                    _cfg.IdMapper, ser, false, GetAffinityKeyFieldNameFromAttribute(type), 
+                    BinaryUtils.IsIgniteEnum(type), registered)
                 : new BinaryFullTypeDescriptor(desc, type, ser, registered);
 
             if (RegistrationDisabled)
+            {
                 return desc;
+            }
 
             var typeKey = BinaryUtils.TypeKey(true, typeId);
 
             var desc0 = _idToDesc.GetOrAdd(typeKey, x => desc);
-            if (desc0.Type != null && desc0.Type.FullName != type.FullName)
+            if (desc0.Type != null && desc0.TypeName != typeName)
+            {
                 ThrowConflictingTypeError(type, desc0.Type, typeId);
+            }
 
             desc0 = _typeNameToDesc.GetOrAdd(typeName, x => desc);
-            if (desc0.Type != null && desc0.Type.FullName != type.FullName)
+            if (desc0.Type != null && desc0.TypeName != typeName)
+            {
                 ThrowConflictingTypeError(type, desc0.Type, typeId);
+            }
 
             _typeToDesc.Set(type, desc);
 
@@ -652,34 +659,36 @@ namespace Apache.Ignite.Core.Impl.Binary
             bool keepDeserialized, IBinaryNameMapper nameMapper, IBinaryIdMapper idMapper,
             IBinarySerializerInternal serializer, string affKeyFieldName, bool isEnum)
         {
+            Debug.Assert(!string.IsNullOrEmpty(typeName));
+
             long typeKey = BinaryUtils.TypeKey(userType, typeId);
 
             BinaryFullTypeDescriptor conflictingType;
 
-            if (_idToDesc.TryGetValue(typeKey, out conflictingType))
+            if (_idToDesc.TryGetValue(typeKey, out conflictingType) && conflictingType.TypeName != typeName)
             {
-                var type1 = conflictingType.Type != null
-                    ? conflictingType.Type.AssemblyQualifiedName
-                    : conflictingType.TypeName;
-
-                var type2 = type != null ? type.AssemblyQualifiedName : typeName;
-
-                ThrowConflictingTypeError(type1, type2, typeId);
+                ThrowConflictingTypeError(typeName, conflictingType.TypeName, typeId);
             }
 
-            if (userType && _typeNameToDesc.ContainsKey(typeName))
-                throw new BinaryObjectException("Conflicting type name: " + typeName);
-
             var descriptor = new BinaryFullTypeDescriptor(type, typeId, typeName, userType, nameMapper, idMapper, 
                 serializer, keepDeserialized, affKeyFieldName, isEnum);
 
+            if (RegistrationDisabled)
+            {
+                return descriptor;
+            }
+
             if (type != null)
-                _typeToDesc.GetOrAdd(type, x => descriptor);
+            {
+                _typeToDesc.Set(type, descriptor);
+            }
 
             if (userType)
-                _typeNameToDesc.GetOrAdd(typeName, x => descriptor);
+            {
+                _typeNameToDesc.Set(typeName, descriptor);
+            }
 
-            _idToDesc.GetOrAdd(typeKey, _ => descriptor);
+            _idToDesc.Set(typeKey, descriptor);
 
             return descriptor;
         }


[3/6] ignite git commit: gg-12686 : Fixed null CacheMapHolder if node is restarted with partition in RENTING state.

Posted by pt...@apache.org.
gg-12686 : Fixed null CacheMapHolder if node is restarted with partition in RENTING state.

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/d253c024
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d253c024
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d253c024

Branch: refs/heads/ignite-5896
Commit: d253c02496f54ce4669fe19fefcf5856fa48d08e
Parents: faa156f
Author: Ilya Lantukh <il...@gridgain.com>
Authored: Wed Aug 30 16:58:32 2017 +0300
Committer: Andrey Gura <ag...@apache.org>
Committed: Wed Aug 30 17:56:22 2017 +0300

----------------------------------------------------------------------
 .../cache/distributed/dht/GridDhtLocalPartition.java         | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d253c024/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
index 4d1bb38..f0e0d47 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
@@ -932,12 +932,8 @@ public class GridDhtLocalPartition extends GridCacheConcurrentMapImpl implements
                     try {
                         CacheDataRow row = it0.next();
 
-                        if (grp.sharedGroup() && (hld == null || hld.cctx.cacheId() != row.cacheId())) {
-                            hld = cacheMaps.get(row.cacheId());
-
-                            if (hld == null)
-                                continue;
-                        }
+                        if (grp.sharedGroup() && (hld == null || hld.cctx.cacheId() != row.cacheId()))
+                            hld = cacheMapHolder(ctx.cacheContext(row.cacheId()));
 
                         assert hld != null;
 


[2/6] ignite git commit: IGNITE-6125: JDBC thick: several fixes to JdbcDatabaseMetadata. This closes #2506.

Posted by pt...@apache.org.
IGNITE-6125: JDBC thick: several fixes to JdbcDatabaseMetadata. This closes #2506.


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

Branch: refs/heads/ignite-5896
Commit: faa156f0da68d49acbb3f446b3905ad2c64ae505
Parents: b7d198e
Author: Ilya Kasnacheev <il...@gmail.com>
Authored: Wed Aug 30 16:20:45 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Wed Aug 30 16:20:45 2017 +0300

----------------------------------------------------------------------
 .../internal/jdbc2/JdbcMetadataSelfTest.java    | 120 ++++-
 .../internal/jdbc2/JdbcDatabaseMetadata.java    | 466 ++++++++++---------
 2 files changed, 360 insertions(+), 226 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/faa156f0/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 f2ef769..bc4ef5b 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
@@ -21,12 +21,21 @@ import java.io.Serializable;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.DriverManager;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.Statement;
+import java.sql.Types;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Set;
 import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.QueryIndex;
 import org.apache.ignite.cache.affinity.AffinityKey;
 import org.apache.ignite.cache.query.annotations.QuerySqlField;
 import org.apache.ignite.configuration.CacheConfiguration;
@@ -61,9 +70,20 @@ public class JdbcMetadataSelfTest extends GridCommonAbstractTest {
     @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
         IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
 
+        LinkedHashMap<String, Boolean> persFields = new LinkedHashMap<>();
+
+        persFields.put("name", true);
+        persFields.put("age", false);
+
         cfg.setCacheConfiguration(
-            cacheConfiguration("pers", AffinityKey.class, Person.class),
-            cacheConfiguration("org", String.class, Organization.class));
+            cacheConfiguration("pers").setQueryEntities(Arrays.asList(
+                new QueryEntity(AffinityKey.class, Person.class)
+                    .setIndexes(Arrays.asList(
+                        new QueryIndex("orgId"),
+                        new QueryIndex().setFields(persFields))))
+            ),
+            cacheConfiguration("org").setQueryEntities(Arrays.asList(
+                new QueryEntity(AffinityKey.class, Organization.class))));
 
         TcpDiscoverySpi disco = new TcpDiscoverySpi();
 
@@ -78,11 +98,9 @@ public class JdbcMetadataSelfTest extends GridCommonAbstractTest {
 
     /**
      * @param name Name.
-     * @param clsK Class k.
-     * @param clsV Class v.
      * @return Cache configuration.
      */
-    protected CacheConfiguration cacheConfiguration(@NotNull String name, Class<?> clsK, Class<?> clsV) {
+    protected CacheConfiguration cacheConfiguration(@NotNull String name) {
         CacheConfiguration<?,?> cache = defaultCacheConfiguration();
 
         cache.setName(name);
@@ -90,7 +108,6 @@ public class JdbcMetadataSelfTest extends GridCommonAbstractTest {
         cache.setBackups(1);
         cache.setWriteSynchronizationMode(FULL_SYNC);
         cache.setAtomicityMode(TRANSACTIONAL);
-        cache.setIndexedTypes(clsK, clsV);
 
         return cache;
     }
@@ -194,7 +211,7 @@ public class JdbcMetadataSelfTest extends GridCommonAbstractTest {
         try (Connection conn = DriverManager.getConnection(BASE_URL)) {
             DatabaseMetaData meta = conn.getMetaData();
 
-            ResultSet rs = meta.getColumns("", "pers", "Person", "%");
+            ResultSet rs = meta.getColumns("", "pers", "PERSON", "%");
 
             assertNotNull(rs);
 
@@ -227,7 +244,7 @@ public class JdbcMetadataSelfTest extends GridCommonAbstractTest {
             assertTrue(names.isEmpty());
             assertEquals(3, cnt);
 
-            rs = meta.getColumns("", "org", "Organization", "%");
+            rs = meta.getColumns("", "org", "ORGANIZATION", "%");
 
             assertNotNull(rs);
 
@@ -287,10 +304,95 @@ public class JdbcMetadataSelfTest extends GridCommonAbstractTest {
             int cnt = 0;
 
             while (rs.next()) {
+                String idxName = rs.getString("INDEX_NAME");
+                String field = rs.getString("COLUMN_NAME");
+                String ascOrDesc = rs.getString("ASC_OR_DESC");
+
+                assertEquals(DatabaseMetaData.tableIndexOther, rs.getInt("TYPE"));
+
+                if ("PERSON_ORGID_ASC_IDX".equals(idxName)) {
+                    assertEquals("ORGID", field);
+                    assertEquals("A", ascOrDesc);
+                }
+                else if ("PERSON_NAME_ASC_AGE_DESC_IDX".equals(idxName)) {
+                    if ("NAME".equals(field))
+                        assertEquals("A", ascOrDesc);
+                    else if ("AGE".equals(field))
+                        assertEquals("D", ascOrDesc);
+                    else
+                        fail("Unexpected field: " + field);
+                }
+                else
+                    fail("Unexpected index: " + idxName);
+
+                cnt++;
+            }
+
+            assertEquals(3, cnt);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPrimaryKeyMetadata() throws Exception {
+        try (Connection conn = DriverManager.getConnection(BASE_URL);
+             ResultSet rs = conn.getMetaData().getPrimaryKeys(null, "pers", "PERSON")) {
+
+            int cnt = 0;
+
+            while (rs.next()) {
+                assertEquals("_KEY", rs.getString("COLUMN_NAME"));
+
                 cnt++;
             }
 
-            assertEquals(0, cnt);
+            assertEquals(1, cnt);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testParametersMetadata() throws Exception {
+        try (Connection conn = DriverManager.getConnection(BASE_URL)) {
+            conn.setSchema("pers");
+
+            PreparedStatement stmt = conn.prepareStatement("select orgId from Person p where p.name > ? and p.orgId > ?");
+
+            ParameterMetaData meta = stmt.getParameterMetaData();
+
+            assertNotNull(meta);
+
+            assertEquals(2, meta.getParameterCount());
+
+            assertEquals(Types.VARCHAR, meta.getParameterType(1));
+            assertEquals(ParameterMetaData.parameterNullableUnknown, meta.isNullable(1));
+            assertEquals(Integer.MAX_VALUE, meta.getPrecision(1));
+
+            assertEquals(Types.INTEGER, meta.getParameterType(2));
+            assertEquals(ParameterMetaData.parameterNullableUnknown, meta.isNullable(2));
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testSchemasMetadata() throws Exception {
+        try (Connection conn = DriverManager.getConnection(BASE_URL)) {
+            ResultSet rs = conn.getMetaData().getSchemas();
+
+            Set<String> expectedSchemas = new HashSet<>(Arrays.asList("pers", "org"));
+
+            Set<String> schemas = new HashSet<>();
+
+            while (rs.next()) {
+                schemas.add(rs.getString(1));
+
+                assertNull(rs.getString(2));
+            }
+
+            assertEquals(expectedSchemas, schemas);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/faa156f0/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 e9a5fde..aad6daa 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
@@ -66,67 +66,67 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     }
 
     /** {@inheritDoc} */
-    @Override public boolean allProceduresAreCallable() throws SQLException {
+    @Override public boolean allProceduresAreCallable() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean allTablesAreSelectable() throws SQLException {
+    @Override public boolean allTablesAreSelectable() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public String getURL() throws SQLException {
+    @Override public String getURL() {
         return conn.url();
     }
 
     /** {@inheritDoc} */
-    @Override public String getUserName() throws SQLException {
+    @Override public String getUserName() {
         return "";
     }
 
     /** {@inheritDoc} */
-    @Override public boolean isReadOnly() throws SQLException {
-        return true;
+    @Override public boolean isReadOnly() {
+        return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean nullsAreSortedHigh() throws SQLException {
+    @Override public boolean nullsAreSortedHigh() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean nullsAreSortedLow() throws SQLException {
+    @Override public boolean nullsAreSortedLow() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean nullsAreSortedAtStart() throws SQLException {
+    @Override public boolean nullsAreSortedAtStart() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean nullsAreSortedAtEnd() throws SQLException {
+    @Override public boolean nullsAreSortedAtEnd() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public String getDatabaseProductName() throws SQLException {
+    @Override public String getDatabaseProductName() {
         return "Ignite Cache";
     }
 
     /** {@inheritDoc} */
-    @Override public String getDatabaseProductVersion() throws SQLException {
+    @Override public String getDatabaseProductVersion() {
         return "4.1.0";
     }
 
     /** {@inheritDoc} */
-    @Override public String getDriverName() throws SQLException {
+    @Override public String getDriverName() {
         return "Ignite JDBC Driver";
     }
 
     /** {@inheritDoc} */
-    @Override public String getDriverVersion() throws SQLException {
+    @Override public String getDriverVersion() {
         return "1.0";
     }
 
@@ -141,517 +141,517 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     }
 
     /** {@inheritDoc} */
-    @Override public boolean usesLocalFiles() throws SQLException {
+    @Override public boolean usesLocalFiles() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean usesLocalFilePerTable() throws SQLException {
+    @Override public boolean usesLocalFilePerTable() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsMixedCaseIdentifiers() throws SQLException {
+    @Override public boolean supportsMixedCaseIdentifiers() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean storesUpperCaseIdentifiers() throws SQLException {
+    @Override public boolean storesUpperCaseIdentifiers() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean storesLowerCaseIdentifiers() throws SQLException {
+    @Override public boolean storesLowerCaseIdentifiers() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean storesMixedCaseIdentifiers() throws SQLException {
+    @Override public boolean storesMixedCaseIdentifiers() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+    @Override public boolean supportsMixedCaseQuotedIdentifiers() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+    @Override public boolean storesUpperCaseQuotedIdentifiers() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+    @Override public boolean storesLowerCaseQuotedIdentifiers() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+    @Override public boolean storesMixedCaseQuotedIdentifiers() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public String getIdentifierQuoteString() throws SQLException {
-        return " ";
+    @Override public String getIdentifierQuoteString() {
+        return "\"";
     }
 
     /** {@inheritDoc} */
-    @Override public String getSQLKeywords() throws SQLException {
-        return "";
+    @Override public String getSQLKeywords() {
+        return "LIMIT,MINUS,ROWNUM,SYSDATE,SYSTIME,SYSTIMESTAMP,TODAY";
     }
 
     /** {@inheritDoc} */
-    @Override public String getNumericFunctions() throws SQLException {
+    @Override public String getNumericFunctions() {
         return "";
     }
 
     /** {@inheritDoc} */
-    @Override public String getStringFunctions() throws SQLException {
+    @Override public String getStringFunctions() {
         return "";
     }
 
     /** {@inheritDoc} */
-    @Override public String getSystemFunctions() throws SQLException {
+    @Override public String getSystemFunctions() {
         return "";
     }
 
     /** {@inheritDoc} */
-    @Override public String getTimeDateFunctions() throws SQLException {
+    @Override public String getTimeDateFunctions() {
         return "";
     }
 
     /** {@inheritDoc} */
-    @Override public String getSearchStringEscape() throws SQLException {
-        return "";
+    @Override public String getSearchStringEscape() {
+        return "\\";
     }
 
     /** {@inheritDoc} */
-    @Override public String getExtraNameCharacters() throws SQLException {
+    @Override public String getExtraNameCharacters() {
         return "";
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsAlterTableWithAddColumn() throws SQLException {
+    @Override public boolean supportsAlterTableWithAddColumn() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsAlterTableWithDropColumn() throws SQLException {
+    @Override public boolean supportsAlterTableWithDropColumn() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsColumnAliasing() throws SQLException {
+    @Override public boolean supportsColumnAliasing() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean nullPlusNonNullIsNull() throws SQLException {
+    @Override public boolean nullPlusNonNullIsNull() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsConvert() throws SQLException {
-        return false;
+    @Override public boolean supportsConvert() {
+        return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsConvert(int fromType, int toType) throws SQLException {
-        return false;
+    @Override public boolean supportsConvert(int fromType, int toType) {
+        return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsTableCorrelationNames() throws SQLException {
+    @Override public boolean supportsTableCorrelationNames() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+    @Override public boolean supportsDifferentTableCorrelationNames() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsExpressionsInOrderBy() throws SQLException {
+    @Override public boolean supportsExpressionsInOrderBy() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsOrderByUnrelated() throws SQLException {
+    @Override public boolean supportsOrderByUnrelated() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsGroupBy() throws SQLException {
+    @Override public boolean supportsGroupBy() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsGroupByUnrelated() throws SQLException {
+    @Override public boolean supportsGroupByUnrelated() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsGroupByBeyondSelect() throws SQLException {
+    @Override public boolean supportsGroupByBeyondSelect() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsLikeEscapeClause() throws SQLException {
+    @Override public boolean supportsLikeEscapeClause() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsMultipleResultSets() throws SQLException {
+    @Override public boolean supportsMultipleResultSets() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsMultipleTransactions() throws SQLException {
+    @Override public boolean supportsMultipleTransactions() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsNonNullableColumns() throws SQLException {
+    @Override public boolean supportsNonNullableColumns() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsMinimumSQLGrammar() throws SQLException {
+    @Override public boolean supportsMinimumSQLGrammar() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsCoreSQLGrammar() throws SQLException {
-        return false;
+    @Override public boolean supportsCoreSQLGrammar() {
+        return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsExtendedSQLGrammar() throws SQLException {
+    @Override public boolean supportsExtendedSQLGrammar() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+    @Override public boolean supportsANSI92EntryLevelSQL() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsANSI92IntermediateSQL() throws SQLException {
+    @Override public boolean supportsANSI92IntermediateSQL() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsANSI92FullSQL() throws SQLException {
+    @Override public boolean supportsANSI92FullSQL() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+    @Override public boolean supportsIntegrityEnhancementFacility() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsOuterJoins() throws SQLException {
+    @Override public boolean supportsOuterJoins() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsFullOuterJoins() throws SQLException {
-        return true;
+    @Override public boolean supportsFullOuterJoins() {
+        return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsLimitedOuterJoins() throws SQLException {
+    @Override public boolean supportsLimitedOuterJoins() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public String getSchemaTerm() throws SQLException {
+    @Override public String getSchemaTerm() {
         return "";
     }
 
     /** {@inheritDoc} */
-    @Override public String getProcedureTerm() throws SQLException {
+    @Override public String getProcedureTerm() {
         return "";
     }
 
     /** {@inheritDoc} */
-    @Override public String getCatalogTerm() throws SQLException {
+    @Override public String getCatalogTerm() {
         return "";
     }
 
     /** {@inheritDoc} */
-    @Override public boolean isCatalogAtStart() throws SQLException {
+    @Override public boolean isCatalogAtStart() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public String getCatalogSeparator() throws SQLException {
+    @Override public String getCatalogSeparator() {
         return "";
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsSchemasInDataManipulation() throws SQLException {
-        return false;
+    @Override public boolean supportsSchemasInDataManipulation() {
+        return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsSchemasInProcedureCalls() throws SQLException {
+    @Override public boolean supportsSchemasInProcedureCalls() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsSchemasInTableDefinitions() throws SQLException {
+    @Override public boolean supportsSchemasInTableDefinitions() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+    @Override public boolean supportsSchemasInIndexDefinitions() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+    @Override public boolean supportsSchemasInPrivilegeDefinitions() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsCatalogsInDataManipulation() throws SQLException {
+    @Override public boolean supportsCatalogsInDataManipulation() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+    @Override public boolean supportsCatalogsInProcedureCalls() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+    @Override public boolean supportsCatalogsInTableDefinitions() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+    @Override public boolean supportsCatalogsInIndexDefinitions() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+    @Override public boolean supportsCatalogsInPrivilegeDefinitions() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsPositionedDelete() throws SQLException {
+    @Override public boolean supportsPositionedDelete() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsPositionedUpdate() throws SQLException {
+    @Override public boolean supportsPositionedUpdate() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsSelectForUpdate() throws SQLException {
+    @Override public boolean supportsSelectForUpdate() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsStoredProcedures() throws SQLException {
+    @Override public boolean supportsStoredProcedures() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsSubqueriesInComparisons() throws SQLException {
+    @Override public boolean supportsSubqueriesInComparisons() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsSubqueriesInExists() throws SQLException {
+    @Override public boolean supportsSubqueriesInExists() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsSubqueriesInIns() throws SQLException {
+    @Override public boolean supportsSubqueriesInIns() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+    @Override public boolean supportsSubqueriesInQuantifieds() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsCorrelatedSubqueries() throws SQLException {
+    @Override public boolean supportsCorrelatedSubqueries() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsUnion() throws SQLException {
+    @Override public boolean supportsUnion() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsUnionAll() throws SQLException {
+    @Override public boolean supportsUnionAll() {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+    @Override public boolean supportsOpenCursorsAcrossCommit() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+    @Override public boolean supportsOpenCursorsAcrossRollback() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+    @Override public boolean supportsOpenStatementsAcrossCommit() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+    @Override public boolean supportsOpenStatementsAcrossRollback() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxBinaryLiteralLength() throws SQLException {
+    @Override public int getMaxBinaryLiteralLength() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxCharLiteralLength() throws SQLException {
+    @Override public int getMaxCharLiteralLength() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxColumnNameLength() throws SQLException {
+    @Override public int getMaxColumnNameLength() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxColumnsInGroupBy() throws SQLException {
+    @Override public int getMaxColumnsInGroupBy() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxColumnsInIndex() throws SQLException {
+    @Override public int getMaxColumnsInIndex() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxColumnsInOrderBy() throws SQLException {
+    @Override public int getMaxColumnsInOrderBy() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxColumnsInSelect() throws SQLException {
+    @Override public int getMaxColumnsInSelect() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxColumnsInTable() throws SQLException {
+    @Override public int getMaxColumnsInTable() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxConnections() throws SQLException {
+    @Override public int getMaxConnections() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxCursorNameLength() throws SQLException {
+    @Override public int getMaxCursorNameLength() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxIndexLength() throws SQLException {
+    @Override public int getMaxIndexLength() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxSchemaNameLength() throws SQLException {
+    @Override public int getMaxSchemaNameLength() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxProcedureNameLength() throws SQLException {
+    @Override public int getMaxProcedureNameLength() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxCatalogNameLength() throws SQLException {
+    @Override public int getMaxCatalogNameLength() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxRowSize() throws SQLException {
+    @Override public int getMaxRowSize() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+    @Override public boolean doesMaxRowSizeIncludeBlobs() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxStatementLength() throws SQLException {
+    @Override public int getMaxStatementLength() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxStatements() throws SQLException {
+    @Override public int getMaxStatements() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxTableNameLength() throws SQLException {
+    @Override public int getMaxTableNameLength() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxTablesInSelect() throws SQLException {
+    @Override public int getMaxTablesInSelect() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getMaxUserNameLength() throws SQLException {
+    @Override public int getMaxUserNameLength() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getDefaultTransactionIsolation() throws SQLException {
+    @Override public int getDefaultTransactionIsolation() {
         return TRANSACTION_NONE;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsTransactions() throws SQLException {
+    @Override public boolean supportsTransactions() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
+    @Override public boolean supportsTransactionIsolationLevel(int level) {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
+    @Override public boolean supportsDataDefinitionAndDataManipulationTransactions() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
+    @Override public boolean supportsDataManipulationTransactionsOnly() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+    @Override public boolean dataDefinitionCausesTransactionCommit() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+    @Override public boolean dataDefinitionIgnoredInTransactions() {
         return false;
     }
 
@@ -697,12 +697,16 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
         List<List<?>> rows = new LinkedList<>();
 
-        if (tblTypes == null || Arrays.asList(tblTypes).contains("TABLE"))
-            for (Map.Entry<String, Map<String, Map<String, String>>> schema : meta.entrySet())
-                if (matches(schema.getKey(), schemaPtrn))
-                    for (String tbl : schema.getValue().keySet())
+        if (validCatalogPattern(catalog) && (tblTypes == null || Arrays.asList(tblTypes).contains("TABLE"))) {
+            for (Map.Entry<String, Map<String, Map<String, String>>> schema : meta.entrySet()) {
+                if (matches(schema.getKey(), schemaPtrn)) {
+                    for (String tbl : schema.getValue().keySet()) {
                         if (matches(tbl, tblNamePtrn))
                             rows.add(tableRow(schema.getKey(), tbl));
+                    }
+                }
+            }
+        }
 
         return new JdbcResultSet(null,
             conn.createStatement0(),
@@ -775,14 +779,21 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
         int cnt = 0;
 
-        for (Map.Entry<String, Map<String, Map<String, String>>> schema : meta.entrySet())
-            if (matches(schema.getKey(), schemaPtrn))
-                for (Map.Entry<String, Map<String, String>> tbl : schema.getValue().entrySet())
-                    if (matches(tbl.getKey(), tblNamePtrn))
-                        for (Map.Entry<String, String> 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));
+        if (validCatalogPattern(catalog)) {
+            for (Map.Entry<String, Map<String, Map<String, String>>> schema : meta.entrySet()) {
+                if (matches(schema.getKey(), schemaPtrn)) {
+                    for (Map.Entry<String, Map<String, String>> tbl : schema.getValue().entrySet()) {
+                        if (matches(tbl.getKey(), tblNamePtrn)) {
+                            for (Map.Entry<String, String> 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));
+                            }
+                        }
+                    }
+                }
+            }
+        }
 
         return new JdbcResultSet(null,
             conn.createStatement0(),
@@ -891,17 +902,22 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     }
 
     /** {@inheritDoc} */
-    @Override public ResultSet getPrimaryKeys(String catalog, String schema, String tbl) throws SQLException {
+    @Override public ResultSet getPrimaryKeys(String catalog, String schemaPtrn, String tblNamePtrn)
+        throws SQLException {
         updateMetaData();
 
         List<List<?>> rows = new LinkedList<>();
 
-        for (Map.Entry<String, Map<String, Map<String, String>>> s : meta.entrySet())
-            if (schema == null || schema.toUpperCase().equals(s.getKey()))
-                for (Map.Entry<String, Map<String, String>> t : s.getValue().entrySet())
-                    if (tbl == null || tbl.toUpperCase().equals(t.getKey()))
-                        rows.add(Arrays.<Object>asList(null, s.getKey().toUpperCase(),
-                            t.getKey().toUpperCase(), "_KEY", 1, "_KEY"));
+        if (validCatalogPattern(catalog)) {
+            for (Map.Entry<String, Map<String, Map<String, String>>> schema : meta.entrySet()) {
+                if (matches(schema.getKey(), schemaPtrn)) {
+                    for (Map.Entry<String, Map<String, String>> tbl : schema.getValue().entrySet()) {
+                        if (matches(tbl.getKey(), tblNamePtrn))
+                            rows.add(Arrays.<Object>asList(null, schema.getKey(), tbl.getKey(), "_KEY", 1, "_KEY"));
+                    }
+                }
+            }
+        }
 
         return new JdbcResultSet(null,
             conn.createStatement0(),
@@ -969,28 +985,30 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
         Collection<List<?>> rows = new ArrayList<>(indexes.size());
 
-        for (List<Object> idx : indexes) {
-            String idxSchema = (String)idx.get(0);
-            String idxTbl = (String)idx.get(1);
-
-            if ((schema == null || schema.equals(idxSchema)) && (tbl == null || tbl.equals(idxTbl))) {
-                List<Object> row = new ArrayList<>(13);
-
-                row.add(null);
-                row.add(idxSchema);
-                row.add(idxTbl);
-                row.add(idx.get(2));
-                row.add(null);
-                row.add(idx.get(3));
-                row.add((int)tableIndexOther);
-                row.add(idx.get(4));
-                row.add(idx.get(5));
-                row.add((Boolean)idx.get(6) ? "D" : "A");
-                row.add(0);
-                row.add(0);
-                row.add(null);
-
-                rows.add(row);
+        if (validCatalogPattern(catalog)) {
+            for (List<Object> idx : indexes) {
+                String idxSchema = (String)idx.get(0);
+                String idxTbl = (String)idx.get(1);
+
+                if ((schema == null || schema.equals(idxSchema)) && (tbl == null || tbl.equals(idxTbl))) {
+                    List<Object> row = new ArrayList<>(13);
+
+                    row.add(null);
+                    row.add(idxSchema);
+                    row.add(idxTbl);
+                    row.add(idx.get(2));
+                    row.add(null);
+                    row.add(idx.get(3));
+                    row.add((int)tableIndexOther);
+                    row.add(idx.get(4));
+                    row.add(idx.get(5));
+                    row.add((Boolean)idx.get(6) ? "D" : "A");
+                    row.add(0);
+                    row.add(0);
+                    row.add(null);
+
+                    rows.add(row);
+                }
             }
         }
 
@@ -1009,62 +1027,62 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsResultSetType(int type) throws SQLException {
+    @Override public boolean supportsResultSetType(int type) {
         return true;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException {
+    @Override public boolean supportsResultSetConcurrency(int type, int concurrency) {
         return concurrency == CONCUR_READ_ONLY;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean ownUpdatesAreVisible(int type) throws SQLException {
+    @Override public boolean ownUpdatesAreVisible(int type) {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean ownDeletesAreVisible(int type) throws SQLException {
+    @Override public boolean ownDeletesAreVisible(int type) {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean ownInsertsAreVisible(int type) throws SQLException {
+    @Override public boolean ownInsertsAreVisible(int type) {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean othersUpdatesAreVisible(int type) throws SQLException {
+    @Override public boolean othersUpdatesAreVisible(int type) {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean othersDeletesAreVisible(int type) throws SQLException {
+    @Override public boolean othersDeletesAreVisible(int type) {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean othersInsertsAreVisible(int type) throws SQLException {
+    @Override public boolean othersInsertsAreVisible(int type) {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean updatesAreDetected(int type) throws SQLException {
+    @Override public boolean updatesAreDetected(int type) {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean deletesAreDetected(int type) throws SQLException {
+    @Override public boolean deletesAreDetected(int type) {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean insertsAreDetected(int type) throws SQLException {
+    @Override public boolean insertsAreDetected(int type) {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsBatchUpdates() throws SQLException {
+    @Override public boolean supportsBatchUpdates() {
         return true;
     }
 
@@ -1082,27 +1100,27 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     }
 
     /** {@inheritDoc} */
-    @Override public Connection getConnection() throws SQLException {
+    @Override public Connection getConnection() {
         return conn;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsSavepoints() throws SQLException {
+    @Override public boolean supportsSavepoints() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsNamedParameters() throws SQLException {
+    @Override public boolean supportsNamedParameters() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsMultipleOpenResults() throws SQLException {
+    @Override public boolean supportsMultipleOpenResults() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsGetGeneratedKeys() throws SQLException {
+    @Override public boolean supportsGetGeneratedKeys() {
         return false;
     }
 
@@ -1146,52 +1164,52 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsResultSetHoldability(int holdability) throws SQLException {
+    @Override public boolean supportsResultSetHoldability(int holdability) {
         return holdability == HOLD_CURSORS_OVER_COMMIT;
     }
 
     /** {@inheritDoc} */
-    @Override public int getResultSetHoldability() throws SQLException {
+    @Override public int getResultSetHoldability() {
         return HOLD_CURSORS_OVER_COMMIT;
     }
 
     /** {@inheritDoc} */
-    @Override public int getDatabaseMajorVersion() throws SQLException {
+    @Override public int getDatabaseMajorVersion() {
         return 1;
     }
 
     /** {@inheritDoc} */
-    @Override public int getDatabaseMinorVersion() throws SQLException {
+    @Override public int getDatabaseMinorVersion() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getJDBCMajorVersion() throws SQLException {
+    @Override public int getJDBCMajorVersion() {
         return 1;
     }
 
     /** {@inheritDoc} */
-    @Override public int getJDBCMinorVersion() throws SQLException {
+    @Override public int getJDBCMinorVersion() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public int getSQLStateType() throws SQLException {
+    @Override public int getSQLStateType() {
         return 0;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean locatorsUpdateCopy() throws SQLException {
+    @Override public boolean locatorsUpdateCopy() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsStatementPooling() throws SQLException {
+    @Override public boolean supportsStatementPooling() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public RowIdLifetime getRowIdLifetime() throws SQLException {
+    @Override public RowIdLifetime getRowIdLifetime() {
         return ROWID_UNSUPPORTED;
     }
 
@@ -1201,9 +1219,12 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
         List<List<?>> rows = new ArrayList<>(meta.size());
 
-        for (String schema : meta.keySet())
-            if (matches(schema, schemaPtrn))
-                rows.add(Arrays.<Object>asList(schema, null));
+        if (validCatalogPattern(catalog)) {
+            for (String schema : meta.keySet()) {
+                if (matches(schema, schemaPtrn))
+                    rows.add(Arrays.<Object>asList(schema, null));
+            }
+        }
 
         return new JdbcResultSet(null,
             conn.createStatement0(),
@@ -1215,12 +1236,17 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     }
 
     /** {@inheritDoc} */
-    @Override public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
+    @Override public boolean supportsStoredFunctionsUsingCallSyntax() {
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
+    @Override public boolean autoCommitFailureClosesAllResultSets() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean generatedKeyAlwaysReturned() {
         return false;
     }
 
@@ -1270,20 +1296,6 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     }
 
     /** {@inheritDoc} */
-    @SuppressWarnings("unchecked")
-    @Override public <T> T unwrap(Class<T> iface) throws SQLException {
-        if (!isWrapperFor(iface))
-            throw new SQLException("Database meta data is not a wrapper for " + iface.getName());
-
-        return (T)this;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
-        return iface != null && iface == DatabaseMetaData.class;
-    }
-
-    /** {@inheritDoc} */
     @Override public ResultSet getPseudoColumns(String catalog, String schemaPtrn, String tblNamePtrn,
         String colNamePtrn) throws SQLException {
         return new JdbcResultSet(null,
@@ -1297,8 +1309,17 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     }
 
     /** {@inheritDoc} */
-    @Override public boolean generatedKeyAlwaysReturned() throws SQLException {
-        return false;
+    @SuppressWarnings("unchecked")
+    @Override public <T> T unwrap(Class<T> iface) throws SQLException {
+        if (!isWrapperFor(iface))
+            throw new SQLException("Database meta data is not a wrapper for " + iface.getName());
+
+        return (T)this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isWrapperFor(Class<?> iface) {
+        return iface != null && iface == DatabaseMetaData.class;
     }
 
     /**
@@ -1344,7 +1365,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
 
                         for (String field : idx.fields()) {
                             indexes.add(F.<Object>asList(name, type.toUpperCase(), !idx.unique(),
-                                idx.name().toUpperCase(), ++cnt, field, idx.descending(field)));
+                                idx.name(), ++cnt, field, idx.descending(field)));
                         }
                     }
                 }
@@ -1364,9 +1385,20 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
      * @param ptrn Pattern.
      * @return Whether string matches pattern.
      */
-    private boolean matches(String str, String ptrn) {
+    private static boolean matches(String str, String ptrn) {
         return str != null && (ptrn == null ||
-            str.toUpperCase().matches(ptrn.toUpperCase().replace("%", ".*").replace("_", ".")));
+            str.matches(ptrn.replace("%", ".*").replace("_", ".")));
+    }
+
+    /**
+     * Checks whether pattern matches any catalog.
+     *
+     * @param catalog Catalog pattern.
+     * @return {@code true} If patter is valid for Ignite (null, empty, or '%' wildcard).
+     *  Otherwise returns {@code false}.
+     */
+    private static boolean validCatalogPattern(String catalog) {
+        return F.isEmpty(catalog) || "%".equals(catalog);
     }
 
     /**


[6/6] ignite git commit: IGNITE-5905 .NET: Thin client: cache.Get for primitives

Posted by pt...@apache.org.
IGNITE-5905 .NET: Thin client: cache.Get for primitives

This closes #2542


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

Branch: refs/heads/ignite-5896
Commit: 085cc80e5337ff01f7173342b0fa913392aa90a6
Parents: bb6f3fa
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Wed Aug 30 18:58:57 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Wed Aug 30 18:59:49 2017 +0300

----------------------------------------------------------------------
 .../processors/odbc/SqlListenerNioListener.java |   6 +-
 .../Apache.Ignite.Core.Tests.csproj             |   3 +
 .../Client/CacheTest.cs                         | 126 ++++
 .../Client/ClientConnectionTest.cs              | 120 ++++
 .../Client/IgniteClientConfigurationTest.cs     |  42 ++
 .../IgniteConfigurationTest.cs                  |   2 +
 .../Apache.Ignite.Core.csproj                   |   6 +
 .../Client/IgniteClientConfiguration.cs         |  92 +++
 .../dotnet/Apache.Ignite.Core/Ignition.cs       |  25 +
 .../Impl/Binary/BinaryUtils.cs                  |  16 +-
 .../Impl/Cache/CacheClient.cs                   | 639 +++++++++++++++++++
 .../Apache.Ignite.Core/Impl/Client/ClientOp.cs  |  27 +
 .../Impl/Client/ClientProtocolVersion.cs        | 107 ++++
 .../Impl/Client/ClientSocket.cs                 | 254 ++++++++
 .../Impl/Client/IgniteClient.cs                 | 300 +++++++++
 15 files changed, 1757 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java
index 3e8299c..4567cb8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java
@@ -50,15 +50,15 @@ public class SqlListenerNioListener extends GridNioServerListenerAdapter<byte[]>
     /** JDBC driver handshake code. */
     public static final byte JDBC_CLIENT = 1;
 
+    /** Thin client handshake code. */
+    public static final byte THIN_CLIENT = 2;
+
     /** Version 2.1.0. */
     private static final SqlListenerProtocolVersion VER_2_1_0 = SqlListenerProtocolVersion.create(2, 1, 0);
 
     /** Version 2.1.5: added "lazy" flag. */
     private static final SqlListenerProtocolVersion VER_2_1_5 = SqlListenerProtocolVersion.create(2, 1, 5);
 
-    /** Thin client handshake code. */
-    public static final byte THIN_CLIENT = 2;
-
     /** Current version. */
     private static final SqlListenerProtocolVersion CURRENT_VER = VER_2_1_5;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
index f704005..c9942ca 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
@@ -93,6 +93,9 @@
     <Compile Include="Cache\Store\CacheStoreSessionTestCodeConfig.cs" />
     <Compile Include="Cache\Store\CacheStoreSessionTestSharedFactory.cs" />
     <Compile Include="Client\RawSocketTest.cs" />
+    <Compile Include="Client\CacheTest.cs" />
+    <Compile Include="Client\ClientConnectionTest.cs" />
+    <Compile Include="Client\IgniteClientConfigurationTest.cs" />
     <Compile Include="Deployment\CacheGetFunc.cs" />
     <Compile Include="Deployment\GetAddressFunc.cs" />
     <Compile Include="Deployment\PeerAssemblyLoadingAllApisTest.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTest.cs
new file mode 100644
index 0000000..53cffd0
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTest.cs
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Tests.Client
+{
+    using System;
+    using System.Collections.Concurrent;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Threading;
+    using Apache.Ignite.Core.Cache;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Thin client cache test.
+    /// </summary>
+    public class CacheTest
+    {
+        /** Cache name. */
+        private const string CacheName = "cache";
+
+        /// <summary>
+        /// Fixture tear down.
+        /// </summary>
+        [TestFixtureSetUp]
+        public void FixtureSetUp()
+        {
+            Ignition.Start(TestUtils.GetTestConfiguration());
+        }
+
+        /// <summary>
+        /// Fixture tear down.
+        /// </summary>
+        [TestFixtureTearDown]
+        public void FixtureTearDown()
+        {
+            Ignition.StopAll(true);
+        }
+
+        /// <summary>
+        /// Tests the cache put / get with primitive data types.
+        /// </summary>
+        [Test]
+        public void TestPutGetPrimitives()
+        {
+            using (var client = Ignition.GetClient())
+            {
+                GetCache().Put(1, "foo");
+
+                var clientCache = client.GetCache<int, string>(CacheName);
+
+                // Existing key.
+                Assert.AreEqual("foo", clientCache.Get(1));
+                Assert.AreEqual("foo", clientCache[1]);
+
+                // Missing key.
+                Assert.Throws<KeyNotFoundException>(() => clientCache.Get(2));
+            }
+        }
+
+        /// <summary>
+        /// Tests client get in multiple threads with a single client.
+        /// </summary>
+        [Test]
+        [Category(TestUtils.CategoryIntensive)]
+        public void TestGetMultithreadedSingleClient()
+        {
+            GetCache().Put(1, "foo");
+
+            using (var client = Ignition.GetClient())
+            {
+                var clientCache = client.GetCache<int, string>(CacheName);
+
+                TestUtils.RunMultiThreaded(() => Assert.AreEqual("foo", clientCache.Get(1)),
+                    Environment.ProcessorCount, 5);
+            }
+        }
+
+        /// <summary>
+        /// Tests client get in multiple threads with multiple clients.
+        /// </summary>
+        [Test]
+        [Category(TestUtils.CategoryIntensive)]
+        public void TestGetMultithreadedMultiClient()
+        {
+            GetCache().Put(1, "foo");
+
+            // One client per thread.
+            ConcurrentDictionary<int, IIgnite> clients = new ConcurrentDictionary<int, IIgnite>();
+
+            TestUtils.RunMultiThreaded(() =>
+                {
+                    var client = clients.GetOrAdd(Thread.CurrentThread.ManagedThreadId, _ => Ignition.GetClient());
+
+                    var clientCache = client.GetCache<int, string>(CacheName);
+
+                    Assert.AreEqual("foo", clientCache.Get(1));
+                },
+                Environment.ProcessorCount, 5);
+
+            clients.ToList().ForEach(x => x.Value.Dispose());
+        }
+
+        /// <summary>
+        /// Gets the cache.
+        /// </summary>
+        private static ICache<int, string> GetCache()
+        {
+            return Ignition.GetIgnite().GetOrCreateCache<int, string>(CacheName);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs
new file mode 100644
index 0000000..c6743b1
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs
@@ -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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Client
+{
+    using System;
+    using System.Linq;
+    using System.Net.Sockets;
+    using Apache.Ignite.Core.Client;
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Configuration;
+    using Apache.Ignite.Core.Impl.Client;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests client connection: port ranges, version checks, etc.
+    /// </summary>
+    public class ClientConnectionTest
+    {
+        /// <summary>
+        /// Fixture tear down.
+        /// </summary>
+        [TestFixtureTearDown]
+        public void FixtureTearDown()
+        {
+            Ignition.StopAll(true);
+        }
+
+        /// <summary>
+        /// Tests that missing server yields connection refused error.
+        /// </summary>
+        [Test]
+        public void TestNoServerConnectionRefused()
+        {
+            var ex = Assert.Throws<AggregateException>(() => Ignition.GetClient());
+            var socketEx = ex.InnerExceptions.OfType<SocketException>().First();
+            Assert.AreEqual(SocketError.ConnectionRefused, socketEx.SocketErrorCode);
+        }
+
+        /// <summary>
+        /// Tests that multiple clients can connect to one server.
+        /// </summary>
+        [Test]
+        public void TestMultipleClients()
+        {
+            using (Ignition.Start(TestUtils.GetTestConfiguration()))
+            {
+                var client1 = Ignition.GetClient();
+                var client2 = Ignition.GetClient();
+                var client3 = Ignition.GetClient();
+
+                client1.Dispose();
+                client2.Dispose();
+                client3.Dispose();
+            }
+        }
+
+        /// <summary>
+        /// Tests custom connector and client configuration.
+        /// </summary>
+        [Test]
+        [Category(TestUtils.CategoryIntensive)]
+        public void TestCustomConfig()
+        {
+            var servCfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
+            {
+                SqlConnectorConfiguration = new SqlConnectorConfiguration
+                {
+                    Host = "localhost",
+                    Port = 2000,
+                    PortRange = 1
+                }
+            };
+
+            var clientCfg = new IgniteClientConfiguration
+            {
+                Host = "localhost",
+                Port = 2000
+            };
+
+            using (Ignition.Start(servCfg))
+            using (Ignition.GetClient(clientCfg))
+            {
+                // No-op.
+            }
+        }
+
+        /// <summary>
+        /// Tests the incorrect protocol version error.
+        /// </summary>
+        [Test]
+        [Category(TestUtils.CategoryIntensive)]
+        public void TestIncorrectProtocolVersionError()
+        {
+            using (Ignition.Start(TestUtils.GetTestConfiguration()))
+            {
+                // ReSharper disable once ObjectCreationAsStatement
+                var ex = Assert.Throws<IgniteException>(() => new ClientSocket(new IgniteClientConfiguration(),
+                    new ClientProtocolVersion(-1, -1, -1)));
+
+                Assert.AreEqual("Client handhsake failed: 'Unsupported version.'. " +
+                                "Client version: -1.-1.-1. Server version: 2.1.5", ex.Message);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/IgniteClientConfigurationTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/IgniteClientConfigurationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/IgniteClientConfigurationTest.cs
new file mode 100644
index 0000000..0734f42
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/IgniteClientConfigurationTest.cs
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Tests.Client
+{
+    using Apache.Ignite.Core.Client;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests for <see cref="IgniteClientConfiguration"/>.
+    /// </summary>
+    public class IgniteClientConfigurationTest
+    {
+        /// <summary>
+        /// Tests the defaults.
+        /// </summary>
+        [Test]
+        public void TestDefaults()
+        {
+            var cfg = new IgniteClientConfiguration();
+
+            Assert.AreEqual(IgniteClientConfiguration.DefaultPort, cfg.Port);
+            Assert.AreEqual(IgniteClientConfiguration.DefaultSocketBufferSize, cfg.SocketReceiveBufferSize);
+            Assert.AreEqual(IgniteClientConfiguration.DefaultSocketBufferSize, cfg.SocketSendBufferSize);
+            Assert.AreEqual(IgniteClientConfiguration.DefaultTcpNoDelay, cfg.TcpNoDelay);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs
index 93d6af3..950f36d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs
@@ -26,6 +26,7 @@ namespace Apache.Ignite.Core.Tests
     using Apache.Ignite.Core.Cache.Affinity.Rendezvous;
     using Apache.Ignite.Core.Cache.Configuration;
     using Apache.Ignite.Core.Cache.Eviction;
+    using Apache.Ignite.Core.Client;
     using Apache.Ignite.Core.Common;
     using Apache.Ignite.Core.Communication.Tcp;
     using Apache.Ignite.Core.Configuration;
@@ -87,6 +88,7 @@ namespace Apache.Ignite.Core.Tests
             CheckDefaultValueAttributes(new MemoryPolicyConfiguration());
             CheckDefaultValueAttributes(new SqlConnectorConfiguration());
             CheckDefaultValueAttributes(new PersistentStoreConfiguration());
+            CheckDefaultValueAttributes(new IgniteClientConfiguration());
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/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 c444ed0..8a384fd 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -97,8 +97,14 @@
     <Compile Include="Cache\Configuration\MemoryPolicyConfiguration.cs" />
     <Compile Include="Cache\Configuration\PartitionLossPolicy.cs" />
     <Compile Include="Cache\IMemoryMetrics.cs" />
+    <Compile Include="Client\IgniteClientConfiguration.cs" />
     <Compile Include="Common\ExceptionFactory.cs" />
     <Compile Include="Configuration\Package-Info.cs" />
+    <Compile Include="Impl\Cache\CacheClient.cs" />
+    <Compile Include="Impl\Client\ClientOp.cs" />
+    <Compile Include="Impl\Client\ClientProtocolVersion.cs" />
+    <Compile Include="Impl\Client\ClientSocket.cs" />
+    <Compile Include="Impl\Client\IgniteClient.cs" />
     <Compile Include="Impl\IPlatformTargetInternal.cs" />
     <Compile Include="Impl\PersistentStore\PersistentStoreMetrics.cs" />
     <Compile Include="Impl\PlatformDisposableTargetAdapter.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/modules/platforms/dotnet/Apache.Ignite.Core/Client/IgniteClientConfiguration.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Client/IgniteClientConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Client/IgniteClientConfiguration.cs
new file mode 100644
index 0000000..0cd9be2
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Client/IgniteClientConfiguration.cs
@@ -0,0 +1,92 @@
+/*
+ * 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.Client
+{
+    using System.ComponentModel;
+
+    /// <summary>
+    /// Ignite thin client configuration.
+    /// <para />
+    /// Ignite thin client connects to a specific Ignite node with a socket and does not start JVM in process.
+    /// This configuration should correspond to <see cref="IgniteConfiguration.SqlConnectorConfiguration"/>
+    /// on a target node.
+    /// </summary>
+    public class IgniteClientConfiguration
+    {
+        /// <summary>
+        /// Default port.
+        /// </summary>
+        public const int DefaultPort = 10800;
+
+        /// <summary>
+        /// Default socket buffer size.
+        /// </summary>
+        public const int DefaultSocketBufferSize = 0;
+
+        /// <summary>
+        /// Default value of <see cref="TcpNoDelay" /> property.
+        /// </summary>
+        public const bool DefaultTcpNoDelay = true;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="IgniteClientConfiguration"/> class.
+        /// </summary>
+        public IgniteClientConfiguration()
+        {
+            Port = DefaultPort;
+            SocketSendBufferSize = DefaultSocketBufferSize;
+            SocketReceiveBufferSize = DefaultSocketBufferSize;
+            TcpNoDelay = DefaultTcpNoDelay;
+        }
+
+        /// <summary>
+        /// Gets or sets the host. Null for loopback.
+        /// </summary>
+        public string Host { get; set; }
+
+        /// <summary>
+        /// Gets or sets the port.
+        /// </summary>
+        [DefaultValue(DefaultPort)]
+        public int Port { get; set; }
+
+        /// <summary>
+        /// Gets or sets the size of the socket send buffer. When set to 0, operating system default is used.
+        /// </summary>
+        [DefaultValue(DefaultSocketBufferSize)]
+        public int SocketSendBufferSize { get; set; }
+
+        /// <summary>
+        /// Gets or sets the size of the socket receive buffer. When set to 0, operating system default is used.
+        /// </summary>
+        [DefaultValue(DefaultSocketBufferSize)]
+        public int SocketReceiveBufferSize { get; set; }
+
+        /// <summary>
+        /// Gets or sets the value for <c>TCP_NODELAY</c> socket option. Each
+        /// socket will be opened using provided value.
+        /// <para />
+        /// Setting this option to <c>true</c> disables Nagle's algorithm
+        /// for socket decreasing latency and delivery time for small messages.
+        /// <para />
+        /// For systems that work under heavy network load it is advisable to set this value to <c>false</c>.
+        /// </summary>
+        [DefaultValue(DefaultTcpNoDelay)]
+        public bool TcpNoDelay { get; set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/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 568eea7..9ee7c26 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
@@ -28,11 +28,13 @@ namespace Apache.Ignite.Core
     using System.Threading;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cache.Affinity;
+    using Apache.Ignite.Core.Client;
     using Apache.Ignite.Core.Common;
     using Apache.Ignite.Core.Impl;
     using Apache.Ignite.Core.Impl.Binary;
     using Apache.Ignite.Core.Impl.Binary.IO;
     using Apache.Ignite.Core.Impl.Cache.Affinity;
+    using Apache.Ignite.Core.Impl.Client;
     using Apache.Ignite.Core.Impl.Common;
     using Apache.Ignite.Core.Impl.Handle;
     using Apache.Ignite.Core.Impl.Log;
@@ -730,6 +732,29 @@ namespace Apache.Ignite.Core
         }
 
         /// <summary>
+        /// Connects Ignite lightweight (thin) client to a local Ignite node.
+        /// <para />
+        /// Thin client connects to an existing Ignite node with a socket and does not start JVM in process.
+        /// </summary>
+        /// <returns>Ignite instance.</returns>
+        public static IIgnite GetClient()
+        {
+            return new IgniteClient(new IgniteClientConfiguration());
+        }
+
+        /// <summary>
+        /// Connects Ignite lightweight (thin) client to an Ignite node.
+        /// <para />
+        /// Thin client connects to an existing Ignite node with a socket and does not start JVM in process.
+        /// </summary>
+        /// <param name="clientConfiguration">The client configuration.</param>
+        /// <returns>Ignite instance.</returns>
+        public static IIgnite GetClient(IgniteClientConfiguration clientConfiguration)
+        {
+            return new IgniteClient(clientConfiguration);
+        }
+
+        /// <summary>
         /// Handles the DomainUnload event of the CurrentDomain control.
         /// </summary>
         /// <param name="sender">The source of the event.</param>

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/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 91a536e..412a3cc 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
@@ -1471,11 +1471,9 @@ namespace Apache.Ignite.Core.Impl.Binary
             return res;
         }
 
-        /**
-         * <summary>Get string hash code.</summary>
-         * <param name="val">Value.</param>
-         * <returns>Hash code.</returns>
-         */
+        /// <summary>
+        /// Gets the string hash code using Java algorithm.
+        /// </summary>
         public static int GetStringHashCode(string val)
         {
             if (val == null)
@@ -1494,6 +1492,14 @@ namespace Apache.Ignite.Core.Impl.Binary
         }
 
         /// <summary>
+        /// Gets the cache identifier.
+        /// </summary>
+        public static int GetCacheId(string cacheName)
+        {
+            return string.IsNullOrEmpty(cacheName) ? 1 : GetStringHashCode(cacheName);
+        }
+
+        /// <summary>
         /// Cleans the name of the field.
         /// </summary>
         public static string CleanFieldName(string fieldName)

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheClient.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheClient.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheClient.cs
new file mode 100644
index 0000000..b8bf95e
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheClient.cs
@@ -0,0 +1,639 @@
+/*
+ * 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.Impl.Cache
+{
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using System.IO;
+    using System.Threading.Tasks;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Cache.Configuration;
+    using Apache.Ignite.Core.Cache.Expiry;
+    using Apache.Ignite.Core.Cache.Query;
+    using Apache.Ignite.Core.Cache.Query.Continuous;
+    using Apache.Ignite.Core.Cluster;
+    using Apache.Ignite.Core.Impl.Binary;
+    using Apache.Ignite.Core.Impl.Binary.IO;
+    using Apache.Ignite.Core.Impl.Client;
+    using Apache.Ignite.Core.Impl.Common;
+
+    /// <summary>
+    /// Client cache implementation.
+    /// </summary>
+    internal class CacheClient<TK, TV> : ICache<TK, TV>
+    {
+        /** Socket. */
+        private readonly ClientSocket _socket;
+
+        /** Cache name. */
+        private readonly string _name;
+
+        /** Cache id. */
+        private readonly int _id;
+
+        /** Marshaller */
+        private readonly Marshaller _marsh = BinaryUtils.Marshaller;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CacheClient{TK, TV}" /> class.
+        /// </summary>
+        /// <param name="socket">The socket.</param>
+        /// <param name="name">Cache name.</param>
+        public CacheClient(ClientSocket socket, string name)
+        {
+            Debug.Assert(socket != null);
+            Debug.Assert(name != null);
+
+            _socket = socket;
+            _name = name;
+            _id = BinaryUtils.GetCacheId(name);
+        }
+
+        /** <inheritDoc /> */
+        public IEnumerator<ICacheEntry<TK, TV>> GetEnumerator()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+
+        /** <inheritDoc /> */
+        public string Name
+        {
+            get { return _name; }
+        }
+
+        /** <inheritDoc /> */
+        public IIgnite Ignite
+        {
+            get { throw new NotImplementedException(); }
+        }
+
+        /** <inheritDoc /> */
+        public CacheConfiguration GetConfiguration()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool IsEmpty()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool IsKeepBinary
+        {
+            get { throw new NotImplementedException(); }
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> WithSkipStore()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> WithExpiryPolicy(IExpiryPolicy plc)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK1, TV1> WithKeepBinary<TK1, TV1>()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void LoadCache(ICacheEntryFilter<TK, TV> p, params object[] args)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task LoadCacheAsync(ICacheEntryFilter<TK, TV> p, params object[] args)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void LocalLoadCache(ICacheEntryFilter<TK, TV> p, params object[] args)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task LocalLoadCacheAsync(ICacheEntryFilter<TK, TV> p, params object[] args)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void LoadAll(IEnumerable<TK> keys, bool replaceExistingValues)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task LoadAllAsync(IEnumerable<TK> keys, bool replaceExistingValues)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool ContainsKey(TK key)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<bool> ContainsKeyAsync(TK key)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool ContainsKeys(IEnumerable<TK> keys)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<bool> ContainsKeysAsync(IEnumerable<TK> keys)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public TV LocalPeek(TK key, params CachePeekMode[] modes)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool TryLocalPeek(TK key, out TV value, params CachePeekMode[] modes)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public TV this[TK key]
+        {
+            get
+            {
+                return Get(key);
+            }
+            set
+            {
+                Put(key, value);
+            }
+        }
+
+        /** <inheritDoc /> */
+        public TV Get(TK key)
+        {
+            return DoOutInOp(ClientOp.CacheGet, w => w.WriteObject(key), UnmarshalNotNull<TV>);
+        }
+
+        /** <inheritDoc /> */
+        public Task<TV> GetAsync(TK key)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool TryGet(TK key, out TV value)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<CacheResult<TV>> TryGetAsync(TK key)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICollection<ICacheEntry<TK, TV>> GetAll(IEnumerable<TK> keys)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<ICollection<ICacheEntry<TK, TV>>> GetAllAsync(IEnumerable<TK> keys)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void Put(TK key, TV val)
+        {
+            IgniteArgumentCheck.NotNull(key, "key");
+            IgniteArgumentCheck.NotNull(val, "val");
+
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task PutAsync(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public CacheResult<TV> GetAndPut(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<CacheResult<TV>> GetAndPutAsync(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public CacheResult<TV> GetAndReplace(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<CacheResult<TV>> GetAndReplaceAsync(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public CacheResult<TV> GetAndRemove(TK key)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<CacheResult<TV>> GetAndRemoveAsync(TK key)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool PutIfAbsent(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<bool> PutIfAbsentAsync(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public CacheResult<TV> GetAndPutIfAbsent(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<CacheResult<TV>> GetAndPutIfAbsentAsync(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool Replace(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<bool> ReplaceAsync(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool Replace(TK key, TV oldVal, TV newVal)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<bool> ReplaceAsync(TK key, TV oldVal, TV newVal)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void PutAll(IEnumerable<KeyValuePair<TK, TV>> vals)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task PutAllAsync(IEnumerable<KeyValuePair<TK, TV>> vals)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void LocalEvict(IEnumerable<TK> keys)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void Clear()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task ClearAsync()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void Clear(TK key)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task ClearAsync(TK key)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void ClearAll(IEnumerable<TK> keys)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task ClearAllAsync(IEnumerable<TK> keys)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void LocalClear(TK key)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void LocalClearAll(IEnumerable<TK> keys)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool Remove(TK key)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<bool> RemoveAsync(TK key)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool Remove(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<bool> RemoveAsync(TK key, TV val)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void RemoveAll(IEnumerable<TK> keys)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task RemoveAllAsync(IEnumerable<TK> keys)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void RemoveAll()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task RemoveAllAsync()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public int GetLocalSize(params CachePeekMode[] modes)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public int GetSize(params CachePeekMode[] modes)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<int> GetSizeAsync(params CachePeekMode[] modes)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IQueryCursor<ICacheEntry<TK, TV>> Query(QueryBase qry)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IQueryCursor<IList> QueryFields(SqlFieldsQuery qry)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IContinuousQueryHandle QueryContinuous(ContinuousQuery<TK, TV> qry)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IContinuousQueryHandle<ICacheEntry<TK, TV>> QueryContinuous(ContinuousQuery<TK, TV> qry, QueryBase initialQry)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IEnumerable<ICacheEntry<TK, TV>> GetLocalEntries(params CachePeekMode[] peekModes)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public TRes Invoke<TArg, TRes>(TK key, ICacheEntryProcessor<TK, TV, TArg, TRes> processor, TArg arg)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<TRes> InvokeAsync<TArg, TRes>(TK key, ICacheEntryProcessor<TK, TV, TArg, TRes> processor, TArg arg)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICollection<ICacheEntryProcessorResult<TK, TRes>> InvokeAll<TArg, TRes>(IEnumerable<TK> keys, ICacheEntryProcessor<TK, TV, TArg, TRes> processor, TArg arg)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task<ICollection<ICacheEntryProcessorResult<TK, TRes>>> InvokeAllAsync<TArg, TRes>(IEnumerable<TK> keys, ICacheEntryProcessor<TK, TV, TArg, TRes> processor, TArg arg)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICacheLock Lock(TK key)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICacheLock LockAll(IEnumerable<TK> keys)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool IsLocalLocked(TK key, bool byCurrentThread)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICacheMetrics GetMetrics()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICacheMetrics GetMetrics(IClusterGroup clusterGroup)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICacheMetrics GetLocalMetrics()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public Task Rebalance()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> WithNoRetries()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> WithPartitionRecover()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICollection<int> GetLostPartitions()
+        {
+            throw new NotImplementedException();
+        }
+
+        /// <summary>
+        /// Does the out in op.
+        /// </summary>
+        private T DoOutInOp<T>(ClientOp opId, Action<IBinaryRawWriter> writeAction,
+            Func<IBinaryStream, T> readFunc)
+        {
+            return _socket.DoOutInOp(opId, stream =>
+            {
+                stream.WriteInt(_id);
+                stream.WriteByte(0);  // Flags (skipStore, etc).
+
+                if (writeAction != null)
+                {
+                    writeAction(_marsh.StartMarshal(stream));
+                }
+            }, readFunc);
+        }
+
+        /// <summary>
+        /// Unmarshals the value, throwing an exception for nulls.
+        /// </summary>
+        private T UnmarshalNotNull<T>(IBinaryStream stream)
+        {
+            var hdr = stream.ReadByte();
+
+            if (hdr == BinaryUtils.HdrNull)
+            {
+                throw GetKeyNotFoundException();
+            }
+
+            stream.Seek(-1, SeekOrigin.Current);
+
+            return _marsh.Unmarshal<T>(stream);
+        }
+
+        /// <summary>
+        /// Gets the key not found exception.
+        /// </summary>
+        private static KeyNotFoundException GetKeyNotFoundException()
+        {
+            return new KeyNotFoundException("The given key was not present in the cache.");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientOp.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientOp.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientOp.cs
new file mode 100644
index 0000000..0039085
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientOp.cs
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Client
+{
+    /// <summary>
+    /// Client op code.
+    /// </summary>
+    internal enum ClientOp : short
+    {
+        CacheGet = 1
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientProtocolVersion.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientProtocolVersion.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientProtocolVersion.cs
new file mode 100644
index 0000000..d06b97d
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientProtocolVersion.cs
@@ -0,0 +1,107 @@
+/*
+ * 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.Impl.Client
+{
+    using System;
+
+    /// <summary>
+    /// Client protocol version.
+    /// </summary>
+    internal struct ClientProtocolVersion : IEquatable<ClientProtocolVersion>
+    {
+        /** */
+        private readonly short _major;
+
+        /** */
+        private readonly short _minor;
+
+        /** */
+        private readonly short _maintenance;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ClientProtocolVersion"/> struct.
+        /// </summary>
+        public ClientProtocolVersion(short major, short minor, short maintenance)
+        {
+            _major = major;
+            _minor = minor;
+            _maintenance = maintenance;
+        }
+
+        /// <summary>
+        /// Gets the major part.
+        /// </summary>
+        public short Major
+        {
+            get { return _major; }
+        }
+
+        /// <summary>
+        /// Gets the minor part.
+        /// </summary>
+        public short Minor
+        {
+            get { return _minor; }
+        }
+
+        /// <summary>
+        /// Gets the maintenance part.
+        /// </summary>
+        public short Maintenance
+        {
+            get { return _maintenance; }
+        }
+
+        /// <summary>
+        /// Returns a value indicating whether specified instance equals to current.
+        /// </summary>
+        public bool Equals(ClientProtocolVersion other)
+        {
+            return _major == other._major && _minor == other._minor && _maintenance == other._maintenance;
+        }
+
+        /** <inheritdoc /> */
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj))
+            {
+                return false;
+            }
+
+            return obj is ClientProtocolVersion && Equals((ClientProtocolVersion) obj);
+        }
+
+        /** <inheritdoc /> */
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                var hashCode = _major.GetHashCode();
+                hashCode = (hashCode * 397) ^ _minor.GetHashCode();
+                hashCode = (hashCode * 397) ^ _maintenance.GetHashCode();
+                return hashCode;
+            }
+        }
+
+        /** <inheritdoc /> */
+        public override string ToString()
+        {
+            return string.Format("{0}.{1}.{2}", Major, Minor, Maintenance);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/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
new file mode 100644
index 0000000..886e454
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientSocket.cs
@@ -0,0 +1,254 @@
+/*
+ * 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.Impl.Client
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using System.Net;
+    using System.Net.Sockets;
+    using System.Threading;
+    using Apache.Ignite.Core.Client;
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Impl.Binary;
+    using Apache.Ignite.Core.Impl.Binary.IO;
+
+    /// <summary>
+    /// Wrapper over framework socket for Ignite thin client operations.
+    /// </summary>
+    internal class ClientSocket : IDisposable
+    {
+        /** Current version. */
+        private static readonly ClientProtocolVersion CurrentProtocolVersion = new ClientProtocolVersion(2, 1, 5);
+
+        /** Handshake opcode. */
+        private const byte OpHandshake = 1;
+
+        /** Client type code. */
+        private const byte ClientType = 2;
+
+        /** Unerlying socket. */
+        private readonly Socket _socket;
+
+        /** */
+        private int _requestId;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ClientSocket" /> class.
+        /// </summary>
+        /// <param name="clientConfiguration">The client configuration.</param>
+        /// <param name="version">Protocol version.</param>
+        public ClientSocket(IgniteClientConfiguration clientConfiguration, ClientProtocolVersion? version = null)
+        {
+            Debug.Assert(clientConfiguration != null);
+
+            _socket = Connect(clientConfiguration);
+
+            Handshake(_socket, version ?? CurrentProtocolVersion);
+        }
+
+        /// <summary>
+        /// Performs a send-receive operation.
+        /// </summary>
+        public T DoOutInOp<T>(ClientOp opId, Action<IBinaryStream> writeAction,
+            Func<IBinaryStream, T> readFunc)
+        {
+            var requestId = Interlocked.Increment(ref _requestId);
+
+            var resBytes = SendReceive(_socket, stream =>
+            {
+                stream.WriteShort((short) opId);
+                stream.WriteByte(0); // Flags (compression, etc)
+                stream.WriteInt(requestId);
+
+                if (writeAction != null)
+                {
+                    writeAction(stream);
+                }
+            });
+
+            using (var stream = new BinaryHeapStream(resBytes))
+            {
+                var resRequestId = stream.ReadInt();
+                Debug.Assert(requestId == resRequestId);
+
+                stream.ReadByte(); // Flags
+
+                if (readFunc != null)
+                {
+                    return readFunc(stream);
+                }
+            }
+
+            return default(T);
+        }
+
+        /// <summary>
+        /// Performs client protocol handshake.
+        /// </summary>
+        private static void Handshake(Socket sock, ClientProtocolVersion version)
+        {
+            var res = SendReceive(sock, stream =>
+            {
+                // Handshake.
+                stream.WriteByte(OpHandshake);
+
+                // Protocol version.
+                stream.WriteShort(version.Major);
+                stream.WriteShort(version.Minor);
+                stream.WriteShort(version.Maintenance);
+
+                // Client type: platform.
+                stream.WriteByte(ClientType);
+            }, 20);
+
+            using (var stream = new BinaryHeapStream(res))
+            {
+                var success = stream.ReadBool();
+
+                if (success)
+                {
+                    return;
+                }
+
+                var serverVersion =
+                    new ClientProtocolVersion(stream.ReadShort(), stream.ReadShort(), stream.ReadShort());
+
+                var errMsg = BinaryUtils.Marshaller.Unmarshal<string>(stream);
+
+                throw new IgniteException(string.Format(
+                    "Client handhsake failed: '{0}'. Client version: {1}. Server version: {2}",
+                    errMsg, version, serverVersion));
+            }
+        }
+
+        /// <summary>
+        /// Sends the request and receives a response.
+        /// </summary>
+        private static byte[] SendReceive(Socket sock, Action<IBinaryStream> writeAction, int bufSize = 128)
+        {
+            int messageLen;
+            var buf = WriteMessage(writeAction, bufSize, out messageLen);
+
+            lock (sock)
+            {
+                var sent = sock.Send(buf, messageLen, SocketFlags.None);
+                Debug.Assert(sent == messageLen);
+
+                buf = new byte[4];
+                var received = sock.Receive(buf);
+                Debug.Assert(received == buf.Length);
+
+                using (var stream = new BinaryHeapStream(buf))
+                {
+                    var size = stream.ReadInt();
+                    
+                    buf = new byte[size];
+                    received = sock.Receive(buf);
+                    Debug.Assert(received == buf.Length);
+
+                    return buf;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Writes the message to a byte array.
+        /// </summary>
+        private static byte[] WriteMessage(Action<IBinaryStream> writeAction, int bufSize, out int messageLen)
+        {
+            using (var stream = new BinaryHeapStream(bufSize))
+            {
+                stream.WriteInt(0); // Reserve message size.
+
+                writeAction(stream);
+
+                stream.WriteInt(0, stream.Position - 4); // Write message size.
+
+                messageLen = stream.Position;
+
+                return stream.GetArray();
+            }
+        }
+
+        /// <summary>
+        /// Connects the socket.
+        /// </summary>
+        private static Socket Connect(IgniteClientConfiguration cfg)
+        {
+            List<Exception> errors = null;
+
+            foreach (var ipEndPoint in GetEndPoints(cfg))
+            {
+                try
+                {
+                    var socket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
+                    {
+                        SendBufferSize = cfg.SocketSendBufferSize,
+                        ReceiveBufferSize = cfg.SocketReceiveBufferSize,
+                        NoDelay = cfg.TcpNoDelay
+                    };
+
+                    socket.Connect(ipEndPoint);
+
+                    return socket;
+                }
+                catch (SocketException e)
+                {
+                    if (errors == null)
+                    {
+                        errors = new List<Exception>();
+                    }
+
+                    errors.Add(e);
+                }
+            }
+
+            if (errors == null)
+            {
+                throw new IgniteException("Failed to resolve client host: " + cfg.Host);
+            }
+
+            throw new AggregateException("Failed to establish Ignite thin client connection, " +
+                                         "examine inner exceptions for details.", errors);
+        }
+
+        /// <summary>
+        /// Gets the endpoints: all combinations of IP addresses and ports according to configuration.
+        /// </summary>
+        private static IEnumerable<IPEndPoint> GetEndPoints(IgniteClientConfiguration cfg)
+        {
+            var addressList = cfg.Host != null
+                ? Dns.GetHostEntry(cfg.Host).AddressList
+                : new[] { IPAddress.Loopback };
+
+            foreach (var ipAddress in addressList)
+            {
+                yield return new IPEndPoint(ipAddress, cfg.Port);
+            }
+        }
+
+        /// <summary>
+        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+        /// </summary>
+        public void Dispose()
+        {
+            _socket.Dispose();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/085cc80e/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/IgniteClient.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/IgniteClient.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/IgniteClient.cs
new file mode 100644
index 0000000..4afcdee
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/IgniteClient.cs
@@ -0,0 +1,300 @@
+/*
+ * 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.Impl.Client
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Cache.Configuration;
+    using Apache.Ignite.Core.Client;
+    using Apache.Ignite.Core.Cluster;
+    using Apache.Ignite.Core.Compute;
+    using Apache.Ignite.Core.Datastream;
+    using Apache.Ignite.Core.DataStructures;
+    using Apache.Ignite.Core.Events;
+    using Apache.Ignite.Core.Impl.Cache;
+    using Apache.Ignite.Core.Impl.Common;
+    using Apache.Ignite.Core.Lifecycle;
+    using Apache.Ignite.Core.Log;
+    using Apache.Ignite.Core.Messaging;
+    using Apache.Ignite.Core.PersistentStore;
+    using Apache.Ignite.Core.Services;
+    using Apache.Ignite.Core.Transactions;
+
+    /// <summary>
+    /// Thin client implementation
+    /// </summary>
+    internal class IgniteClient : IIgnite
+    {
+        /** Socket. */
+        private readonly ClientSocket _socket;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="IgniteClient"/> class.
+        /// </summary>
+        /// <param name="clientConfiguration">The client configuration.</param>
+        public IgniteClient(IgniteClientConfiguration clientConfiguration)
+        {
+            Debug.Assert(clientConfiguration != null);
+
+            _socket = new ClientSocket(clientConfiguration);
+        }
+
+        /** <inheritDoc /> */
+        public void Dispose()
+        {
+            _socket.Dispose();
+        }
+
+        /** <inheritDoc /> */
+        public string Name
+        {
+            get { throw new NotImplementedException(); }
+        }
+
+        /** <inheritDoc /> */
+        public ICluster GetCluster()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICompute GetCompute()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> GetCache<TK, TV>(string name)
+        {
+            IgniteArgumentCheck.NotNull(name, "name");
+
+            return new CacheClient<TK, TV>(_socket, name);
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> GetOrCreateCache<TK, TV>(string name)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> GetOrCreateCache<TK, TV>(CacheConfiguration configuration)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> GetOrCreateCache<TK, TV>(CacheConfiguration configuration, NearCacheConfiguration nearConfiguration)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> CreateCache<TK, TV>(string name)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> CreateCache<TK, TV>(CacheConfiguration configuration)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> CreateCache<TK, TV>(CacheConfiguration configuration, NearCacheConfiguration nearConfiguration)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void DestroyCache(string name)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IDataStreamer<TK, TV> GetDataStreamer<TK, TV>(string cacheName)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IBinary GetBinary()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICacheAffinity GetAffinity(string name)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ITransactions GetTransactions()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IMessaging GetMessaging()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IEvents GetEvents()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IServices GetServices()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IAtomicLong GetAtomicLong(string name, long initialValue, bool create)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IAtomicSequence GetAtomicSequence(string name, long initialValue, bool create)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IAtomicReference<T> GetAtomicReference<T>(string name, T initialValue, bool create)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IgniteConfiguration GetConfiguration()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> CreateNearCache<TK, TV>(string name, NearCacheConfiguration configuration)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> GetOrCreateNearCache<TK, TV>(string name, NearCacheConfiguration configuration)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICollection<string> GetCacheNames()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ILogger Logger
+        {
+            get { throw new NotImplementedException(); }
+        }
+
+        /** <inheritDoc /> */
+        public event EventHandler Stopping
+        {
+            add { throw new NotImplementedException(); }
+            remove { throw new NotImplementedException(); }
+        }
+
+        /** <inheritDoc /> */
+        public event EventHandler Stopped
+        {
+            add { throw new NotImplementedException(); }
+            remove { throw new NotImplementedException(); }
+        }
+
+        /** <inheritDoc /> */
+        public event EventHandler ClientDisconnected
+        {
+            add { throw new NotImplementedException(); }
+            remove { throw new NotImplementedException(); }
+        }
+
+        /** <inheritDoc /> */
+        public event EventHandler<ClientReconnectEventArgs> ClientReconnected
+        {
+            add { throw new NotImplementedException(); }
+            remove { throw new NotImplementedException(); }
+        }
+
+        /** <inheritDoc /> */
+        public T GetPlugin<T>(string name) where T : class
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void ResetLostPartitions(IEnumerable<string> cacheNames)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void ResetLostPartitions(params string[] cacheNames)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public ICollection<IMemoryMetrics> GetMemoryMetrics()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IMemoryMetrics GetMemoryMetrics(string memoryPolicyName)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public void SetActive(bool isActive)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public bool IsActive()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritDoc /> */
+        public IPersistentStoreMetrics GetPersistentStoreMetrics()
+        {
+            throw new NotImplementedException();
+        }
+    }
+}