IGNITE-6236 .NET: Thin client: cache.Get and Put for user types

This closes #2580


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

Branch: refs/heads/ignite-5896
Commit: 50f6bdcb264654d38570ac547948b52f9bde92b6
Parents: 4241f5d
Author: Pavel Tupitsyn <[email protected]>
Authored: Mon Sep 4 17:38:38 2017 +0300
Committer: Pavel Tupitsyn <[email protected]>
Committed: Mon Sep 4 17:38:38 2017 +0300

----------------------------------------------------------------------
 .../platform/PlatformContextImpl.java           |  88 +---------
 .../platform/client/ClientBooleanResponse.java  |  46 ++++++
 .../platform/client/ClientCacheRequest.java     |  54 ------
 .../platform/client/ClientGetRequest.java       |  48 ------
 .../platform/client/ClientGetResponse.java      |  46 ------
 .../platform/client/ClientMessageParser.java    |  40 ++++-
 .../platform/client/ClientObjectResponse.java   |  46 ++++++
 .../client/ClientPutBinaryTypesRequest.java     |  57 +++++++
 .../platform/client/ClientRequest.java          |   5 +-
 .../platform/client/ClientResponse.java         |   5 +-
 .../binary/ClientGetBinaryTypeNameRequest.java  |  59 +++++++
 .../binary/ClientGetBinaryTypeNameResponse.java |  47 ++++++
 .../ClientGetBinaryTypeSchemaRequest.java       |  55 +++++++
 .../ClientGetBinaryTypeSchemaResponse.java      |  47 ++++++
 .../ClientRegisterBinaryTypeNameRequest.java    |  64 ++++++++
 .../client/cache/ClientCacheGetRequest.java     |  50 ++++++
 .../client/cache/ClientCachePutRequest.java     |  53 ++++++
 .../client/cache/ClientCacheRequest.java        |  55 +++++++
 .../platform/utils/PlatformUtils.java           | 139 ++++++++++++++--
 .../Apache.Ignite.Core.Tests.csproj             |   2 +
 .../Client/CacheTest.cs                         |  94 +++++++++--
 .../Client/CacheTestNoMeta.cs                   | 157 ++++++++++++++++++
 .../Apache.Ignite.Core.Tests/Client/Person.cs   |  48 ++++++
 .../Client/RawSocketTest.cs                     |   3 -
 .../Apache.Ignite.Core.csproj                   |   2 +
 .../Client/IgniteClientConfiguration.cs         |  12 ++
 .../Impl/Binary/BinaryProcessor.cs              | 141 ++++++++--------
 .../Impl/Binary/BinaryProcessorClient.cs        | 110 +++++++++++++
 .../Impl/Binary/IBinaryProcessor.cs             |  73 +++++++++
 .../Impl/Binary/Marshaller.cs                   |   6 +-
 .../Impl/Cache/CacheClient.cs                   |  57 ++++---
 .../Apache.Ignite.Core/Impl/Client/ClientOp.cs  |   7 +-
 .../Impl/Client/ClientProtocolVersion.cs        |  12 ++
 .../Impl/Client/ClientSocket.cs                 |   6 +-
 .../Impl/Client/IgniteClient.cs                 | 164 ++++++++++++++-----
 .../Apache.Ignite.Core/Impl/IIgniteInternal.cs  |   2 +-
 .../dotnet/Apache.Ignite.Core/Impl/Ignite.cs    |   2 +-
 37 files changed, 1487 insertions(+), 415 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
index f115a9c..79f27f5 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
@@ -39,8 +39,6 @@ import org.apache.ignite.internal.binary.BinaryMetadata;
 import org.apache.ignite.internal.binary.BinaryRawReaderEx;
 import org.apache.ignite.internal.binary.BinaryRawWriterEx;
 import org.apache.ignite.internal.binary.BinaryReaderExImpl;
-import org.apache.ignite.internal.binary.BinarySchema;
-import org.apache.ignite.internal.binary.BinarySchemaRegistry;
 import org.apache.ignite.internal.binary.BinaryTypeImpl;
 import org.apache.ignite.internal.binary.GridBinaryMarshaller;
 import 
org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
@@ -69,21 +67,15 @@ import 
org.apache.ignite.internal.processors.platform.memory.PlatformMemoryManag
 import 
org.apache.ignite.internal.processors.platform.memory.PlatformOutputStream;
 import 
org.apache.ignite.internal.processors.platform.message.PlatformMessageFilter;
 import 
org.apache.ignite.internal.processors.platform.messaging.PlatformMessageFilterImpl;
-import 
org.apache.ignite.internal.processors.platform.utils.PlatformReaderBiClosure;
-import 
org.apache.ignite.internal.processors.platform.utils.PlatformReaderClosure;
 import org.apache.ignite.internal.processors.platform.utils.PlatformUtils;
-import org.apache.ignite.lang.IgniteBiTuple;
 import org.jetbrains.annotations.Nullable;
 
 import java.sql.Timestamp;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
@@ -353,62 +345,7 @@ public class PlatformContextImpl implements 
PlatformContext {
     /** {@inheritDoc} */
     @SuppressWarnings("ConstantConditions")
     @Override public void processMetadata(BinaryRawReaderEx reader) {
-        Collection<BinaryMetadata> metas = PlatformUtils.readCollection(reader,
-            new PlatformReaderClosure<BinaryMetadata>() {
-                @Override public BinaryMetadata read(BinaryRawReaderEx reader) 
{
-                    int typeId = reader.readInt();
-                    String typeName = reader.readString();
-                    String affKey = reader.readString();
-
-                    Map<String, BinaryFieldMetadata> fields = 
PlatformUtils.readLinkedMap(reader,
-                        new PlatformReaderBiClosure<String, 
BinaryFieldMetadata>() {
-                            @Override public IgniteBiTuple<String, 
BinaryFieldMetadata> read(BinaryRawReaderEx reader) {
-                                String name = reader.readString();
-                                int typeId = reader.readInt();
-                                int fieldId = reader.readInt();
-
-                                return new IgniteBiTuple<String, 
BinaryFieldMetadata>(name,
-                                        new BinaryFieldMetadata(typeId, 
fieldId));
-                            }
-                        });
-
-                    Map<String, Integer> enumMap = null;
-
-                    boolean isEnum = reader.readBoolean();
-
-                    if (isEnum) {
-                        int size = reader.readInt();
-
-                        enumMap = new LinkedHashMap<>(size);
-
-                        for (int idx = 0; idx < size; idx++)
-                            enumMap.put(reader.readString(), reader.readInt());
-                    }
-
-                    // Read schemas
-                    int schemaCnt = reader.readInt();
-
-                    List<BinarySchema> schemas = null;
-
-                    if (schemaCnt > 0) {
-                        schemas = new ArrayList<>(schemaCnt);
-
-                        for (int i = 0; i < schemaCnt; i++) {
-                            int id = reader.readInt();
-                            int fieldCnt = reader.readInt();
-                            List<Integer> fieldIds = new ArrayList<>(fieldCnt);
-
-                            for (int j = 0; j < fieldCnt; j++)
-                                fieldIds.add(reader.readInt());
-
-                            schemas.add(new BinarySchema(id, fieldIds));
-                        }
-                    }
-
-                    return new BinaryMetadata(typeId, typeName, fields, 
affKey, schemas, isEnum, enumMap);
-                }
-            }
-        );
+        Collection<BinaryMetadata> metas = 
PlatformUtils.readBinaryMetadata(reader);
 
         BinaryContext binCtx = cacheObjProc.binaryContext();
 
@@ -433,28 +370,7 @@ public class PlatformContextImpl implements 
PlatformContext {
 
     /** {@inheritDoc} */
     @Override public void writeSchema(BinaryRawWriterEx writer, int typeId, 
int schemaId) {
-        BinarySchemaRegistry schemaReg = 
cacheObjProc.binaryContext().schemaRegistry(typeId);
-        BinarySchema schema = schemaReg.schema(schemaId);
-
-        if (schema == null) {
-            BinaryTypeImpl meta = 
(BinaryTypeImpl)cacheObjProc.metadata(typeId);
-
-            if (meta != null) {
-                for (BinarySchema typeSchema : meta.metadata().schemas()) {
-                    if (schemaId == typeSchema.schemaId()) {
-                        schema = typeSchema;
-                        break;
-                    }
-                }
-            }
-
-            if (schema != null)
-                schemaReg.addSchema(schemaId, schema);
-        }
-
-        int[] fieldIds = schema == null ? null : schema.fieldIds();
-
-        writer.writeIntArray(fieldIds);
+        writer.writeIntArray(PlatformUtils.getSchema(cacheObjProc, typeId, 
schemaId));
     }
 
     /**

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

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/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
deleted file mode 100644
index 7036853..0000000
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientCacheRequest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.processors.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/50f6bdcb/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
deleted file mode 100644
index 72d3507..0000000
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientGetRequest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.processors.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/50f6bdcb/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
deleted file mode 100644
index 58a3062..0000000
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientGetResponse.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.processors.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/50f6bdcb/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
index 5ad7ba9..2db9bf4 100644
--- 
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
@@ -29,6 +29,11 @@ import 
org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProce
 import org.apache.ignite.internal.processors.odbc.SqlListenerMessageParser;
 import org.apache.ignite.internal.processors.odbc.SqlListenerRequest;
 import org.apache.ignite.internal.processors.odbc.SqlListenerResponse;
+import 
org.apache.ignite.internal.processors.platform.client.binary.ClientGetBinaryTypeNameRequest;
+import 
org.apache.ignite.internal.processors.platform.client.binary.ClientGetBinaryTypeSchemaRequest;
+import 
org.apache.ignite.internal.processors.platform.client.binary.ClientRegisterBinaryTypeNameRequest;
+import 
org.apache.ignite.internal.processors.platform.client.cache.ClientCacheGetRequest;
+import 
org.apache.ignite.internal.processors.platform.client.cache.ClientCachePutRequest;
 
 /**
  * Thin client message parser.
@@ -37,6 +42,21 @@ public class ClientMessageParser implements 
SqlListenerMessageParser {
     /** */
     private static final short OP_CACHE_GET = 1;
 
+    /** */
+    private static final short OP_GET_BINARY_TYPE_NAME = 2;
+
+    /** */
+    private static final short OP_GET_BINARY_TYPE_SCHEMA = 3;
+
+    /** */
+    private static final short OP_CACHE_PUT = 4;
+
+    /** */
+    private static final short OP_REGISTER_BINARY_TYPE_NAME = 5;
+
+    /** */
+    private static final short OP_PUT_BINARY_TYPES = 6;
+
     /** Marshaller. */
     private final GridBinaryMarshaller marsh;
 
@@ -62,9 +82,23 @@ public class ClientMessageParser implements 
SqlListenerMessageParser {
         short opCode = reader.readShort();
 
         switch (opCode) {
-            case OP_CACHE_GET: {
-                return new ClientGetRequest(reader);
-            }
+            case OP_CACHE_GET:
+                return new ClientCacheGetRequest(reader);
+
+            case OP_GET_BINARY_TYPE_NAME:
+                return new ClientGetBinaryTypeNameRequest(reader);
+
+            case OP_GET_BINARY_TYPE_SCHEMA:
+                return new ClientGetBinaryTypeSchemaRequest(reader);
+
+            case OP_CACHE_PUT:
+                return new ClientCachePutRequest(reader);
+
+            case OP_REGISTER_BINARY_TYPE_NAME:
+                return new ClientRegisterBinaryTypeNameRequest(reader);
+
+            case OP_PUT_BINARY_TYPES:
+                return new ClientPutBinaryTypesRequest(reader);
         }
 
         throw new IgniteException("Invalid operation: " + opCode);

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientObjectResponse.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientObjectResponse.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientObjectResponse.java
new file mode 100644
index 0000000..3865e95
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientObjectResponse.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;
+
+/**
+ * Single object response.
+ */
+public class ClientObjectResponse extends ClientResponse {
+    /** */
+    private final Object val;
+
+    /**
+     * Ctor.
+     *
+     * @param requestId Request id.
+     */
+    public ClientObjectResponse(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/50f6bdcb/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientPutBinaryTypesRequest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientPutBinaryTypesRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientPutBinaryTypesRequest.java
new file mode 100644
index 0000000..3fdd020
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientPutBinaryTypesRequest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.platform.client;
+
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.binary.BinaryContext;
+import org.apache.ignite.internal.binary.BinaryMetadata;
+import org.apache.ignite.internal.binary.BinaryRawReaderEx;
+import 
org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
+import org.apache.ignite.internal.processors.platform.utils.PlatformUtils;
+
+import java.util.Collection;
+
+/**
+ * Binary types update request.
+ */
+class ClientPutBinaryTypesRequest extends ClientRequest {
+    /** Metas. */
+    private final Collection<BinaryMetadata> metas;
+
+    /**
+     * Ctor.
+     *
+     * @param reader Reader.
+     */
+    ClientPutBinaryTypesRequest(BinaryRawReaderEx reader) {
+        super(reader);
+
+        metas = PlatformUtils.readBinaryMetadata(reader);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public ClientResponse process(GridKernalContext ctx) {
+        BinaryContext binCtx = ((CacheObjectBinaryProcessorImpl) 
ctx.cacheObjects()).binaryContext();
+
+        for (BinaryMetadata meta : metas)
+            binCtx.updateMetadata(meta.typeId(), meta);
+
+        return super.process(ctx);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/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
index f542850..ce561d7 100644
--- 
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
@@ -24,7 +24,7 @@ import 
org.apache.ignite.internal.processors.odbc.SqlListenerRequest;
 /**
  * Thin client request.
  */
-class ClientRequest extends SqlListenerRequest {
+public class ClientRequest extends SqlListenerRequest {
     /** Request id. */
     private final int requestId;
 
@@ -33,8 +33,7 @@ class ClientRequest extends SqlListenerRequest {
      *
      * @param reader Reader.
      */
-    ClientRequest(BinaryRawReader reader) {
-        reader.readByte();  //  Flags: Compression, etc.
+    public ClientRequest(BinaryRawReader reader) {
         requestId = reader.readInt();
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/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
index 2fe65c7..5bb37af 100644
--- 
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
@@ -24,7 +24,7 @@ import org.jetbrains.annotations.Nullable;
 /**
  * Thin client response.
  */
-class ClientResponse extends SqlListenerResponse {
+public class ClientResponse extends SqlListenerResponse {
     /** Request id. */
     private final int requestId;
 
@@ -33,7 +33,7 @@ class ClientResponse extends SqlListenerResponse {
      *
      * @param requestId Request id.
      */
-    ClientResponse(int requestId) {
+    public ClientResponse(int requestId) {
         super(STATUS_SUCCESS, null);
 
         this.requestId = requestId;
@@ -44,6 +44,5 @@ class ClientResponse extends SqlListenerResponse {
      */
     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/50f6bdcb/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeNameRequest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeNameRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeNameRequest.java
new file mode 100644
index 0000000..d434fe1
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeNameRequest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.binary;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.binary.BinaryRawReader;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.processors.platform.client.ClientRequest;
+import org.apache.ignite.internal.processors.platform.client.ClientResponse;
+
+/**
+ * Gets binary type name by id.
+ */
+public class ClientGetBinaryTypeNameRequest extends ClientRequest {
+    /** Platform ID, see org.apache.ignite.internal.MarshallerPlatformIds. */
+    private final byte platformId;
+
+    /** Type id. */
+    private final int typeId;
+
+    /**
+     * Ctor.
+     *
+     * @param reader Reader.
+     */
+    public ClientGetBinaryTypeNameRequest(BinaryRawReader reader) {
+        super(reader);
+
+        platformId = reader.readByte();
+        typeId = reader.readInt();
+    }
+
+    /** {@inheritDoc} */
+    @Override public ClientResponse process(GridKernalContext ctx) {
+        try {
+            String typeName = ctx.marshallerContext().getClassName(platformId, 
typeId);
+
+            return new ClientGetBinaryTypeNameResponse(getRequestId(), 
typeName);
+        } catch (ClassNotFoundException | IgniteCheckedException e) {
+            throw new BinaryObjectException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeNameResponse.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeNameResponse.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeNameResponse.java
new file mode 100644
index 0000000..d57f0df
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeNameResponse.java
@@ -0,0 +1,47 @@
+/*
+ * 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.binary;
+
+import org.apache.ignite.binary.BinaryRawWriter;
+import org.apache.ignite.internal.processors.platform.client.ClientResponse;
+
+/**
+ * Type name response.
+ */
+public class ClientGetBinaryTypeNameResponse extends ClientResponse {
+    /** Type name. */
+    private final String typeName;
+
+    /**
+     * Ctor.
+     *
+     * @param requestId Request id.
+     */
+    ClientGetBinaryTypeNameResponse(int requestId, String typeName) {
+        super(requestId);
+
+        this.typeName = typeName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void encode(BinaryRawWriter writer) {
+        super.encode(writer);
+
+        writer.writeString(typeName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeSchemaRequest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeSchemaRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeSchemaRequest.java
new file mode 100644
index 0000000..bbde1ba
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeSchemaRequest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.binary;
+
+import org.apache.ignite.binary.BinaryRawReader;
+import org.apache.ignite.internal.GridKernalContext;
+import 
org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
+import org.apache.ignite.internal.processors.platform.client.ClientRequest;
+import org.apache.ignite.internal.processors.platform.client.ClientResponse;
+import org.apache.ignite.internal.processors.platform.utils.PlatformUtils;
+
+/**
+ * Binary type schema request.
+ */
+public class ClientGetBinaryTypeSchemaRequest extends ClientRequest {
+    /** Type id. */
+    private final int typeId;
+
+    /** Schema id. */
+    private final int schemaId;
+
+    /**
+     * Ctor.
+     *
+     * @param reader Reader.
+     */
+    public ClientGetBinaryTypeSchemaRequest(BinaryRawReader reader) {
+        super(reader);
+
+        typeId = reader.readInt();
+        schemaId = reader.readInt();
+    }
+
+    /** {@inheritDoc} */
+    @Override public ClientResponse process(GridKernalContext ctx) {
+        int[] schema = 
PlatformUtils.getSchema((CacheObjectBinaryProcessorImpl)ctx.cacheObjects(), 
typeId, schemaId);
+
+        return new ClientGetBinaryTypeSchemaResponse(getRequestId(), schema);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeSchemaResponse.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeSchemaResponse.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeSchemaResponse.java
new file mode 100644
index 0000000..726096f
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientGetBinaryTypeSchemaResponse.java
@@ -0,0 +1,47 @@
+/*
+ * 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.binary;
+
+import org.apache.ignite.binary.BinaryRawWriter;
+import org.apache.ignite.internal.processors.platform.client.ClientResponse;
+
+/**
+ * Schema response.
+ */
+public class ClientGetBinaryTypeSchemaResponse extends ClientResponse {
+    /** Schema. */
+    private final int[] schema;
+
+    /**
+     * Ctor.
+     *
+     * @param requestId Request id.
+     */
+    ClientGetBinaryTypeSchemaResponse(int requestId, int[] schema) {
+        super(requestId);
+
+        this.schema = schema;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void encode(BinaryRawWriter writer) {
+        super.encode(writer);
+
+        writer.writeIntArray(schema);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientRegisterBinaryTypeNameRequest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientRegisterBinaryTypeNameRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientRegisterBinaryTypeNameRequest.java
new file mode 100644
index 0000000..a3a780b
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/binary/ClientRegisterBinaryTypeNameRequest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.platform.client.binary;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.binary.BinaryRawReader;
+import org.apache.ignite.internal.GridKernalContext;
+import 
org.apache.ignite.internal.processors.platform.client.ClientBooleanResponse;
+import org.apache.ignite.internal.processors.platform.client.ClientRequest;
+import org.apache.ignite.internal.processors.platform.client.ClientResponse;
+
+/**
+ * Gets binary type name by id.
+ */
+public class ClientRegisterBinaryTypeNameRequest extends ClientRequest {
+    /** Platform ID, see org.apache.ignite.internal.MarshallerPlatformIds. */
+    private final byte platformId;
+
+    /** Type id. */
+    private final int typeId;
+
+    /** Type name. */
+    private final String typeName;
+
+    /**
+     * Ctor.
+     *
+     * @param reader Reader.
+     */
+    public ClientRegisterBinaryTypeNameRequest(BinaryRawReader reader) {
+        super(reader);
+
+        platformId = reader.readByte();
+        typeId = reader.readInt();
+        typeName = reader.readString();
+    }
+
+    /** {@inheritDoc} */
+    @Override public ClientResponse process(GridKernalContext ctx) {
+        try {
+            boolean res = 
ctx.marshallerContext().registerClassName(platformId, typeId, typeName);
+
+            return new ClientBooleanResponse(getRequestId(), res);
+        } catch (IgniteCheckedException e) {
+            throw new IgniteException(e);
+        }
+    }
+}

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

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCachePutRequest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCachePutRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCachePutRequest.java
new file mode 100644
index 0000000..0f06650
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCachePutRequest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.cache;
+
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.binary.BinaryRawReaderEx;
+import org.apache.ignite.internal.processors.platform.client.ClientResponse;
+
+/**
+ * Cache put request.
+ */
+public class ClientCachePutRequest extends ClientCacheRequest {
+    /** */
+    private final Object key;
+
+    /** */
+    private final Object val;
+
+    /**
+     * Ctor.
+     *
+     * @param reader Reader.
+     */
+    public ClientCachePutRequest(BinaryRawReaderEx reader) {
+        super(reader);
+
+        key = reader.readObjectDetached();
+        val = reader.readObjectDetached();
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public ClientResponse process(GridKernalContext ctx) {
+        getCache(ctx).put(key, val);
+
+        return super.process(ctx);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRequest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRequest.java
new file mode 100644
index 0000000..9e236aa
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRequest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.cache;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.binary.BinaryRawReader;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.processors.platform.client.ClientRequest;
+
+/**
+ * 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/50f6bdcb/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
index dbd65ed..1a66ea3 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
@@ -17,22 +17,6 @@
 
 package org.apache.ignite.internal.processors.platform.utils;
 
-import java.lang.reflect.Field;
-import java.math.BigDecimal;
-import java.security.Timestamp;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import javax.cache.CacheException;
-import javax.cache.event.CacheEntryEvent;
-import javax.cache.event.CacheEntryListenerException;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
@@ -44,12 +28,18 @@ import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.MarshallerContextImpl;
 import org.apache.ignite.internal.binary.BinaryContext;
+import org.apache.ignite.internal.binary.BinaryFieldMetadata;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
+import org.apache.ignite.internal.binary.BinaryMetadata;
 import org.apache.ignite.internal.binary.BinaryNoopMetadataHandler;
 import org.apache.ignite.internal.binary.BinaryRawReaderEx;
 import org.apache.ignite.internal.binary.BinaryRawWriterEx;
+import org.apache.ignite.internal.binary.BinarySchema;
+import org.apache.ignite.internal.binary.BinarySchemaRegistry;
+import org.apache.ignite.internal.binary.BinaryTypeImpl;
 import org.apache.ignite.internal.binary.BinaryUtils;
 import org.apache.ignite.internal.binary.GridBinaryMarshaller;
+import 
org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
 import org.apache.ignite.internal.processors.platform.PlatformContext;
 import 
org.apache.ignite.internal.processors.platform.PlatformExtendedException;
 import org.apache.ignite.internal.processors.platform.PlatformNativeException;
@@ -68,6 +58,23 @@ import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.logger.NullLogger;
 import org.jetbrains.annotations.Nullable;
 
+import javax.cache.CacheException;
+import javax.cache.event.CacheEntryEvent;
+import javax.cache.event.CacheEntryListenerException;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.security.Timestamp;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_PREFIX;
 
 /**
@@ -1053,6 +1060,106 @@ public class PlatformUtils {
     }
 
     /**
+     * Gets the schema.
+     *
+     * @param cacheObjProc Cache object processor.
+     * @param typeId Type id.
+     * @param schemaId Schema id.
+     */
+    public static int[] getSchema(CacheObjectBinaryProcessorImpl cacheObjProc, 
int typeId, int schemaId) {
+        assert cacheObjProc != null;
+
+        BinarySchemaRegistry schemaReg = 
cacheObjProc.binaryContext().schemaRegistry(typeId);
+        BinarySchema schema = schemaReg.schema(schemaId);
+
+        if (schema == null) {
+            BinaryTypeImpl meta = 
(BinaryTypeImpl)cacheObjProc.metadata(typeId);
+
+            if (meta != null) {
+                for (BinarySchema typeSchema : meta.metadata().schemas()) {
+                    if (schemaId == typeSchema.schemaId()) {
+                        schema = typeSchema;
+                        break;
+                    }
+                }
+            }
+
+            if (schema != null) {
+                schemaReg.addSchema(schemaId, schema);
+            }
+        }
+
+        return schema == null ? null : schema.fieldIds();
+    }
+
+    /**
+     * Reads the binary metadata.
+     *
+     * @param reader Reader.
+     * @return Collection of metas.
+     */
+    public static Collection<BinaryMetadata> 
readBinaryMetadata(BinaryRawReaderEx reader) {
+        return readCollection(reader,
+                new PlatformReaderClosure<BinaryMetadata>() {
+                    @Override
+                    public BinaryMetadata read(BinaryRawReaderEx reader) {
+                        int typeId = reader.readInt();
+                        String typeName = reader.readString();
+                        String affKey = reader.readString();
+
+                        Map<String, BinaryFieldMetadata> fields = 
readLinkedMap(reader,
+                                new PlatformReaderBiClosure<String, 
BinaryFieldMetadata>() {
+                                    @Override
+                                    public IgniteBiTuple<String, 
BinaryFieldMetadata> read(BinaryRawReaderEx reader) {
+                                        String name = reader.readString();
+                                        int typeId = reader.readInt();
+                                        int fieldId = reader.readInt();
+
+                                        return new IgniteBiTuple<String, 
BinaryFieldMetadata>(name,
+                                                new 
BinaryFieldMetadata(typeId, fieldId));
+                                    }
+                                });
+
+                        Map<String, Integer> enumMap = null;
+
+                        boolean isEnum = reader.readBoolean();
+
+                        if (isEnum) {
+                            int size = reader.readInt();
+
+                            enumMap = new LinkedHashMap<>(size);
+
+                            for (int idx = 0; idx < size; idx++)
+                                enumMap.put(reader.readString(), 
reader.readInt());
+                        }
+
+                        // Read schemas
+                        int schemaCnt = reader.readInt();
+
+                        List<BinarySchema> schemas = null;
+
+                        if (schemaCnt > 0) {
+                            schemas = new ArrayList<>(schemaCnt);
+
+                            for (int i = 0; i < schemaCnt; i++) {
+                                int id = reader.readInt();
+                                int fieldCnt = reader.readInt();
+                                List<Integer> fieldIds = new 
ArrayList<>(fieldCnt);
+
+                                for (int j = 0; j < fieldCnt; j++)
+                                    fieldIds.add(reader.readInt());
+
+                                schemas.add(new BinarySchema(id, fieldIds));
+                            }
+                        }
+
+                        return new BinaryMetadata(typeId, typeName, fields, 
affKey, schemas, isEnum, enumMap);
+                    }
+                }
+        );
+    }
+
+    /**
      * Private constructor.
      */
     private PlatformUtils() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/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 c9942ca..31e95fb 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,8 @@
     <Compile Include="Cache\Query\Linq\CacheLinqTest.Contains.cs" />
     <Compile Include="Cache\Store\CacheStoreSessionTestCodeConfig.cs" />
     <Compile Include="Cache\Store\CacheStoreSessionTestSharedFactory.cs" />
+    <Compile Include="Client\CacheTestNoMeta.cs" />
+    <Compile Include="Client\Person.cs" />
     <Compile Include="Client\RawSocketTest.cs" />
     <Compile Include="Client\CacheTest.cs" />
     <Compile Include="Client\ClientConnectionTest.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/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
index 53cffd0..1c8624c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTest.cs
@@ -22,13 +22,15 @@ namespace Apache.Ignite.Core.Tests.Client
     using System.Collections.Generic;
     using System.Linq;
     using System.Threading;
+    using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Client;
     using NUnit.Framework;
 
     /// <summary>
     /// Thin client cache test.
     /// </summary>
-    public class CacheTest
+    public sealed class CacheTest
     {
         /** Cache name. */
         private const string CacheName = "cache";
@@ -57,18 +59,72 @@ namespace Apache.Ignite.Core.Tests.Client
         [Test]
         public void TestPutGetPrimitives()
         {
-            using (var client = Ignition.GetClient())
+            using (var client = GetClient())
             {
-                GetCache().Put(1, "foo");
+                GetCache<string>().Put(1, "foo");
 
-                var clientCache = client.GetCache<int, string>(CacheName);
+                var clientCache = client.GetCache<int?, string>(CacheName);
+
+                clientCache.Put(2, "bar");
+                clientCache[3] = "baz";
 
                 // Existing key.
                 Assert.AreEqual("foo", clientCache.Get(1));
                 Assert.AreEqual("foo", clientCache[1]);
+                Assert.AreEqual("bar", clientCache[2]);
+                Assert.AreEqual("baz", clientCache[3]);
 
                 // Missing key.
-                Assert.Throws<KeyNotFoundException>(() => clientCache.Get(2));
+                Assert.Throws<KeyNotFoundException>(() => clientCache.Get(-1));
+
+                // Null key.
+                Assert.Throws<ArgumentNullException>(() => 
clientCache.Get(null));
+            }
+        }
+
+        /// <summary>
+        /// Tests the cache put / get with user data types.
+        /// </summary>
+        [Test]
+        public void TestPutGetUserObjects([Values(true, false)] bool 
compactFooter)
+        {
+            var cfg = GetClientConfiguration();
+
+            cfg.BinaryConfiguration = new BinaryConfiguration
+            {
+                CompactFooter = compactFooter
+            };
+
+            using (var client = Ignition.GetClient(cfg))
+            {
+                var person = new Person {Id = 100, Name = "foo"};
+                var person2 = new Person2 {Id = 200, Name = "bar"};
+                
+                var serverCache = GetCache<Person>();
+                var clientCache = client.GetCache<int?, Person>(CacheName);
+
+                // Put through server cache.
+                serverCache.Put(1, person);
+
+                // Put through client cache.
+                clientCache.Put(2, person2);
+                clientCache[3] = person2;
+
+                // Read from client cache.
+                Assert.AreEqual("foo", clientCache.Get(1).Name);
+                Assert.AreEqual(100, clientCache[1].Id);
+                Assert.AreEqual(200, clientCache[2].Id);
+                Assert.AreEqual(200, clientCache[3].Id);
+
+                // Read from server cache.
+                Assert.AreEqual("foo", serverCache.Get(1).Name);
+                Assert.AreEqual(100, serverCache[1].Id);
+                Assert.AreEqual(200, serverCache[2].Id);
+                Assert.AreEqual(200, serverCache[3].Id);
+
+                // Null key or value.
+                Assert.Throws<ArgumentNullException>(() => clientCache.Put(10, 
null));
+                Assert.Throws<ArgumentNullException>(() => 
clientCache.Put(null, person));
             }
         }
 
@@ -79,9 +135,9 @@ namespace Apache.Ignite.Core.Tests.Client
         [Category(TestUtils.CategoryIntensive)]
         public void TestGetMultithreadedSingleClient()
         {
-            GetCache().Put(1, "foo");
+            GetCache<string>().Put(1, "foo");
 
-            using (var client = Ignition.GetClient())
+            using (var client = GetClient())
             {
                 var clientCache = client.GetCache<int, string>(CacheName);
 
@@ -97,14 +153,14 @@ namespace Apache.Ignite.Core.Tests.Client
         [Category(TestUtils.CategoryIntensive)]
         public void TestGetMultithreadedMultiClient()
         {
-            GetCache().Put(1, "foo");
+            GetCache<string>().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 client = 
clients.GetOrAdd(Thread.CurrentThread.ManagedThreadId, _ => GetClient());
 
                     var clientCache = client.GetCache<int, string>(CacheName);
 
@@ -118,9 +174,25 @@ namespace Apache.Ignite.Core.Tests.Client
         /// <summary>
         /// Gets the cache.
         /// </summary>
-        private static ICache<int, string> GetCache()
+        private static ICache<int, T> GetCache<T>()
+        {
+            return Ignition.GetIgnite().GetOrCreateCache<int, T>(CacheName);
+        }
+
+        /// <summary>
+        /// Gets the client.
+        /// </summary>
+        private static IIgnite GetClient()
+        {
+            return Ignition.GetClient(GetClientConfiguration());
+        }
+
+        /// <summary>
+        /// Gets the client configuration.
+        /// </summary>
+        private static IgniteClientConfiguration GetClientConfiguration()
         {
-            return Ignition.GetIgnite().GetOrCreateCache<int, 
string>(CacheName);
+            return new IgniteClientConfiguration();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTestNoMeta.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTestNoMeta.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTestNoMeta.cs
new file mode 100644
index 0000000..56d2b98
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTestNoMeta.cs
@@ -0,0 +1,157 @@
+/*
+ * 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.Collections.Generic;
+    using System.Linq;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Cache.Configuration;
+    using Apache.Ignite.Core.Cache.Query;
+    using Apache.Ignite.Core.Client;
+    using Apache.Ignite.Core.Impl.Binary;
+    using Apache.Ignite.Core.Impl.Binary.Metadata;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Client cache test without metadata (no-op binary processor).
+    /// </summary>
+    public class CacheTestNoMeta
+    {
+        /** 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 user data types.
+        /// </summary>
+        [Test]
+        public void TestPutGetUserObjects()
+        {
+            var cfg = new IgniteClientConfiguration
+            {
+                BinaryProcessor = new NoopBinaryProcessor(),
+                BinaryConfiguration = new BinaryConfiguration
+                {
+                    CompactFooter = false
+                }
+            };
+
+            using (var client = Ignition.GetClient(cfg))
+            {
+                var serverCache = Ignition.GetIgnite().GetOrCreateCache<int?, 
Person>(
+                    new CacheConfiguration(CacheName, new QueryEntity
+                    {
+                        KeyType = typeof(int),
+                        ValueType = typeof(Person),
+                        Fields = new[]
+                        {
+                            new QueryField("id", typeof(int)),
+                            new QueryField("name", typeof(string))
+                        }
+                    }));
+
+                var clientCache = client.GetCache<int?, Person>(CacheName);
+
+                // Put through client cache.
+                clientCache.Put(1, new Person { Id = 100, Name = "foo" });
+                clientCache[2] = new Person { Id = 200, Name = "bar" };
+
+                // Read from client cache.
+                Assert.AreEqual("foo", clientCache.Get(1).Name);
+                Assert.AreEqual(100, clientCache[1].Id);
+                Assert.AreEqual(200, clientCache[2].Id);
+
+                // Read from server cache.
+                Assert.AreEqual("foo", serverCache.Get(1).Name);
+                Assert.AreEqual(100, serverCache[1].Id);
+                Assert.AreEqual(200, serverCache[2].Id);
+
+                // SQL from server cache.
+                var sqlRes = serverCache.Query(new SqlQuery(typeof(Person), 
"where id = 100")).GetAll().Single();
+                Assert.AreEqual(1, sqlRes.Key);
+                Assert.AreEqual(100, sqlRes.Value.Id);
+                Assert.AreEqual("foo", sqlRes.Value.Name);
+            }
+        }
+
+        /// <summary>
+        /// No-op binary processor (does not send meta to cluster).
+        /// </summary>
+        private class NoopBinaryProcessor : IBinaryProcessor
+        {
+            /** <inheritdoc /> */
+            public BinaryType GetBinaryType(int typeId)
+            {
+                return null;
+            }
+
+            /** <inheritdoc /> */
+            public List<IBinaryType> GetBinaryTypes()
+            {
+                return null;
+            }
+
+            /** <inheritdoc /> */
+            public int[] GetSchema(int typeId, int schemaId)
+            {
+                return null;
+            }
+
+            /** <inheritdoc /> */
+            public void PutBinaryTypes(ICollection<BinaryType> types)
+            {
+                // No-op.
+            }
+
+            /** <inheritdoc /> */
+            public bool RegisterType(int id, string typeName)
+            {
+                return false;
+            }
+
+            /** <inheritdoc /> */
+            public BinaryType RegisterEnum(string typeName, 
IEnumerable<KeyValuePair<string, int>> values)
+            {
+                return null;
+            }
+
+            /** <inheritdoc /> */
+            public string GetTypeName(int id)
+            {
+                return null;
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Person.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Person.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Person.cs
new file mode 100644
index 0000000..7f0309f
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Person.cs
@@ -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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Client
+{
+    /// <summary>
+    /// Test person.
+    /// </summary>
+    public class Person
+    {
+        /// <summary>
+        /// Gets or sets the identifier.
+        /// </summary>
+        public int Id { get; set; }
+
+        /// <summary>
+        /// Gets or sets the name.
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// Gets or sets the parent.
+        /// </summary>
+        public Person Parent { get;set; }
+    }
+
+    /// <summary>
+    /// Test person 2.
+    /// </summary>
+    public class Person2 : Person
+    {
+        // No-op.
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/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
index 9d8c427..e3f163c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSocketTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSocketTest.cs
@@ -62,7 +62,6 @@ namespace Apache.Ignite.Core.Tests.Client
                 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);
@@ -82,8 +81,6 @@ namespace Apache.Ignite.Core.Tests.Client
                     int requestId = reader.ReadInt();
                     Assert.AreEqual(1, requestId);
 
-                    reader.ReadByte(); // Flags
-
                     var res = reader.ReadObject<string>();
                     Assert.AreEqual(cache[1], res);
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/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 6666533..760ea38 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -100,6 +100,8 @@
     <Compile Include="Client\IgniteClientConfiguration.cs" />
     <Compile Include="Common\ExceptionFactory.cs" />
     <Compile Include="Configuration\Package-Info.cs" />
+    <Compile Include="Impl\Binary\BinaryProcessorClient.cs" />
+    <Compile Include="Impl\Binary\IBinaryProcessor.cs" />
     <Compile Include="Impl\IIgniteInternal.cs" />
     <Compile Include="Impl\Cache\CacheClient.cs" />
     <Compile Include="Impl\Client\ClientOp.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/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
index 0cd9be2..16374f4 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core/Client/IgniteClientConfiguration.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Client/IgniteClientConfiguration.cs
@@ -18,6 +18,8 @@
 namespace Apache.Ignite.Core.Client
 {
     using System.ComponentModel;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Impl.Binary;
 
     /// <summary>
     /// Ignite thin client configuration.
@@ -88,5 +90,15 @@ namespace Apache.Ignite.Core.Client
         /// </summary>
         [DefaultValue(DefaultTcpNoDelay)]
         public bool TcpNoDelay { get; set; }
+
+        /// <summary>
+        /// Gets or sets the binary configuration.
+        /// </summary>
+        public BinaryConfiguration BinaryConfiguration { get; set; }
+
+        /// <summary>
+        /// Gets or sets custom binary processor. Internal property for tests.
+        /// </summary>
+        internal IBinaryProcessor BinaryProcessor { get; set; }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
index 69056b3..28dc7b9 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
@@ -25,7 +25,7 @@ namespace Apache.Ignite.Core.Impl.Binary
     /// <summary>
     /// Binary metadata processor, delegates to PlatformBinaryProcessor in 
Java.
     /// </summary>
-    internal class BinaryProcessor : PlatformTargetAdapter
+    internal class BinaryProcessor : PlatformTargetAdapter, IBinaryProcessor
     {
         /// <summary>
         /// Op codes.
@@ -104,74 +104,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <param name="types">Binary types.</param>
         public void PutBinaryTypes(ICollection<BinaryType> types)
         {
-            DoOutOp((int) Op.PutMeta, w =>
-            {
-                w.WriteInt(types.Count);
-
-                foreach (var meta in types)
-                {
-                    w.WriteInt(meta.TypeId);
-                    w.WriteString(meta.TypeName);
-                    w.WriteString(meta.AffinityKeyFieldName);
-
-                    var fields = meta.GetFieldsMap();
-
-                    w.WriteInt(fields.Count);
-
-                    foreach (var field in fields)
-                    {
-                        w.WriteString(field.Key);
-                        w.WriteInt(field.Value.TypeId);
-                        w.WriteInt(field.Value.FieldId);
-                    }
-
-                    // Enum data
-                    w.WriteBoolean(meta.IsEnum);
-
-                    if (meta.IsEnum)
-                    {
-                        if (meta.EnumValuesMap != null)
-                        {
-                            w.WriteInt(meta.EnumValuesMap.Count);
-
-                            foreach (var pair in meta.EnumValuesMap)
-                            {
-                                w.WriteString(pair.Key);
-                                w.WriteInt(pair.Value);
-                            }
-                        }
-                        else
-                        {
-                            w.WriteInt(0);
-                        }
-                    }
-
-                    // Send schemas
-                    var desc = meta.Descriptor;
-                    Debug.Assert(desc != null);
-
-                    var count = 0;
-                    var countPos = w.Stream.Position;
-                    w.WriteInt(0); // Reserve for count
-
-                    foreach (var schema in desc.Schema.GetAll())
-                    {
-                        w.WriteInt(schema.Key);
-
-                        var ids = schema.Value;
-                        w.WriteInt(ids.Length);
-
-                        foreach (var id in ids)
-                            w.WriteInt(id);
-
-                        count++;
-                    }
-
-                    w.Stream.WriteInt(countPos, count);
-                }
-            });
-
-            Marshaller.OnBinaryTypesSent(types);
+            DoOutOp((int) Op.PutMeta, w => WriteBinaryTypes(types, w));
         }
 
         /// <summary>
@@ -238,5 +171,75 @@ namespace Apache.Ignite.Core.Impl.Binary
         {
             return DoOutInOp((int) Op.GetType, w => w.WriteInt(id), r => 
Marshaller.StartUnmarshal(r).ReadString());
         }
+
+        /// <summary>
+        /// Writes the binary types.
+        /// </summary>
+        public static void WriteBinaryTypes(ICollection<BinaryType> types, 
BinaryWriter w)
+        {
+            w.WriteInt(types.Count);
+
+            foreach (var meta in types)
+            {
+                w.WriteInt(meta.TypeId);
+                w.WriteString(meta.TypeName);
+                w.WriteString(meta.AffinityKeyFieldName);
+
+                var fields = meta.GetFieldsMap();
+
+                w.WriteInt(fields.Count);
+
+                foreach (var field in fields)
+                {
+                    w.WriteString(field.Key);
+                    w.WriteInt(field.Value.TypeId);
+                    w.WriteInt(field.Value.FieldId);
+                }
+
+                // Enum data
+                w.WriteBoolean(meta.IsEnum);
+
+                if (meta.IsEnum)
+                {
+                    if (meta.EnumValuesMap != null)
+                    {
+                        w.WriteInt(meta.EnumValuesMap.Count);
+
+                        foreach (var pair in meta.EnumValuesMap)
+                        {
+                            w.WriteString(pair.Key);
+                            w.WriteInt(pair.Value);
+                        }
+                    }
+                    else
+                    {
+                        w.WriteInt(0);
+                    }
+                }
+
+                // Send schemas
+                var desc = meta.Descriptor;
+                Debug.Assert(desc != null);
+
+                var count = 0;
+                var countPos = w.Stream.Position;
+                w.WriteInt(0); // Reserve for count
+
+                foreach (var schema in desc.Schema.GetAll())
+                {
+                    w.WriteInt(schema.Key);
+
+                    var ids = schema.Value;
+                    w.WriteInt(ids.Length);
+
+                    foreach (var id in ids)
+                        w.WriteInt(id);
+
+                    count++;
+                }
+
+                w.Stream.WriteInt(countPos, count);
+            }
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessorClient.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessorClient.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessorClient.cs
new file mode 100644
index 0000000..8a95a75
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessorClient.cs
@@ -0,0 +1,110 @@
+/*
+ * 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.Binary
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Impl.Binary.Metadata;
+    using Apache.Ignite.Core.Impl.Client;
+
+    /// <summary>
+    /// Thin client binary processor.
+    /// </summary>
+    internal class BinaryProcessorClient : IBinaryProcessor
+    {
+        /** Type registry platform id. See 
org.apache.ignite.internal.MarshallerPlatformIds in Java. */
+        private const byte DotNetPlatformId = 1;
+
+        /** Socket. */
+        private readonly ClientSocket _socket;
+
+        /** Marshaller. */
+        private readonly Marshaller _marsh = BinaryUtils.Marshaller;
+
+        /// <summary>
+        /// Initializes a new instance of the <see 
cref="BinaryProcessorClient"/> class.
+        /// </summary>
+        /// <param name="socket">The socket.</param>
+        public BinaryProcessorClient(ClientSocket socket)
+        {
+            Debug.Assert(socket != null);
+
+            _socket = socket;
+        }
+
+        /** <inheritdoc /> */
+        public BinaryType GetBinaryType(int typeId)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritdoc /> */
+        public List<IBinaryType> GetBinaryTypes()
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritdoc /> */
+        public int[] GetSchema(int typeId, int schemaId)
+        {
+            return _socket.DoOutInOp(ClientOp.GetBinaryTypeSchema, s =>
+                {
+                    s.WriteInt(typeId);
+                    s.WriteInt(schemaId);
+                },
+                s => _marsh.StartUnmarshal(s).ReadIntArray());
+        }
+
+        /** <inheritdoc /> */
+        public void PutBinaryTypes(ICollection<BinaryType> types)
+        {
+            _socket.DoOutInOp<object>(ClientOp.PutBinaryTypes,
+                s => BinaryProcessor.WriteBinaryTypes(types, 
_marsh.StartMarshal(s)), null);
+        }
+
+        /** <inheritdoc /> */
+        public bool RegisterType(int id, string typeName)
+        {
+            return _socket.DoOutInOp(ClientOp.RegisterBinaryTypeName, s =>
+            {
+                s.WriteByte(DotNetPlatformId);
+                s.WriteInt(id);
+                _marsh.StartMarshal(s).WriteString(typeName);
+            }, s => s.ReadBool());
+        }
+
+        /** <inheritdoc /> */
+        public BinaryType RegisterEnum(string typeName, 
IEnumerable<KeyValuePair<string, int>> values)
+        {
+            throw new NotImplementedException();
+        }
+
+        /** <inheritdoc /> */
+        public string GetTypeName(int id)
+        {
+            return _socket.DoOutInOp(ClientOp.GetBinaryTypeName, s =>
+                {
+                    s.WriteByte(DotNetPlatformId);
+                    s.WriteInt(id);
+                },
+                s => _marsh.StartUnmarshal(s).ReadString());
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/50f6bdcb/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryProcessor.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryProcessor.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryProcessor.cs
new file mode 100644
index 0000000..c626c76
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/IBinaryProcessor.cs
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Binary
+{
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Impl.Binary.Metadata;
+
+    /// <summary>
+    /// Binary processor.
+    /// </summary>
+    internal interface IBinaryProcessor
+    {
+        /// <summary>
+        /// Gets metadata for specified type.
+        /// </summary>
+        BinaryType GetBinaryType(int typeId);
+
+        /// <summary>
+        /// Gets metadata for all known types.
+        /// </summary>
+        List<IBinaryType> GetBinaryTypes();
+
+        /// <summary>
+        /// Gets the schema.
+        /// </summary>
+        int[] GetSchema(int typeId, int schemaId);
+
+        /// <summary>
+        /// Put binary types to Grid.
+        /// </summary>
+        /// <param name="types">Binary types.</param>
+        void PutBinaryTypes(ICollection<BinaryType> types);
+
+        /// <summary>
+        /// Registers the type.
+        /// </summary>
+        /// <param name="id">The identifier.</param>
+        /// <param name="typeName">The type name.</param>
+        /// <returns>True if registration succeeded; otherwise, 
false.</returns>
+        bool RegisterType(int id, string typeName);
+
+        /// <summary>
+        /// Registers the enum.
+        /// </summary>
+        /// <param name="typeName">Name of the type.</param>
+        /// <param name="values">The values.</param>
+        /// <returns>Resulting binary type.</returns>
+        BinaryType RegisterEnum(string typeName, 
IEnumerable<KeyValuePair<string, int>> values);
+
+        /// <summary>
+        /// Gets the type name by id.
+        /// </summary>
+        /// <param name="id">The identifier.</param>
+        /// <returns>Type or null.</returns>
+        string GetTypeName(int id);
+    }
+}
\ No newline at end of file

Reply via email to