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/29 15:57:16 UTC
ignite git commit: IGNITE-5899 Thin client: cache.Get for primitives
Repository: ignite
Updated Branches:
refs/heads/ignite-5896 08a831f5d -> 79fc39f7b
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/79fc39f7
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/79fc39f7
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/79fc39f7
Branch: refs/heads/ignite-5896
Commit: 79fc39f7beaeb28d057f7c38b0e37f83b819c5c2
Parents: 08a831f
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Tue Aug 29 18:57:07 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Tue Aug 29 18:57:07 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/79fc39f7/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/79fc39f7/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/79fc39f7/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/79fc39f7/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/79fc39f7/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/79fc39f7/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/79fc39f7/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/79fc39f7/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/79fc39f7/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/79fc39f7/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;
+ }
+ }
+}