示例#1
0
        /// <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));
            }
        }
示例#2
0
        /// <summary>
        /// Writes the message to a byte array.
        /// </summary>
        private RequestMessage WriteMessage(Action <IBinaryStream> writeAction, ClientOp opId)
        {
            var requestId = Interlocked.Increment(ref _requestId);
            var stream    = new BinaryHeapStream(256);

            stream.WriteInt(0); // Reserve message size.
            stream.WriteShort((short)opId);
            stream.WriteLong(requestId);
            writeAction(stream);
            stream.WriteInt(0, stream.Position - 4); // Write message size.

            return(new RequestMessage(requestId, stream.GetArray(), stream.Position));
        }
示例#3
0
        /// <summary>
        /// Lazy fields initialization routine.
        /// </summary>
        private void InitializeFields()
        {
            if (_fields != null)
            {
                return;
            }

            var stream = new BinaryHeapStream(_data);

            var hdr = BinaryObjectHeader.Read(stream, _offset);

            _fields = hdr.ReadSchemaAsDictionary(stream, _offset) ?? EmptyFields;
        }
示例#4
0
        /// <summary>
        /// Sends the request.
        /// </summary>
        private static void SendRequest(Stream 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.

                sock.Write(stream.GetArray(), 0, stream.Position);
            }
        }
示例#5
0
        /// <summary>
        /// Create empty binary object from descriptor.
        /// </summary>
        /// <param name="desc">Descriptor.</param>
        /// <returns>Empty binary object.</returns>
        private BinaryObject BinaryFromDescriptor(IBinaryTypeDescriptor desc)
        {
            var len = BinaryObjectHeader.Size;

            var hdr = new BinaryObjectHeader(desc.TypeId, 0, len, 0, len,
                                             desc.UserType ? BinaryObjectHeader.Flag.UserType : BinaryObjectHeader.Flag.None);

            var stream = new BinaryHeapStream(len);

            BinaryObjectHeader.Write(hdr, stream, 0);

            return(new BinaryObject(_marsh, stream.InternalArray, 0, hdr));
        }
        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <param name="obj">The object.</param>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        public static int GetHashCode(IBinaryObject obj)
        {
            if (obj == null)
                return 0;

            var binObj = GetBinaryObject(obj);

            var arg = new KeyValuePair<int, int>(GetDataStart(binObj), GetDataLength(binObj));

            using (var stream = new BinaryHeapStream(binObj.Data))
            {
                return stream.Apply(HashCodeProcessor, arg);
            }
        }
示例#7
0
        /// <summary>
        /// Receives the message.
        /// </summary>
        private static byte[] ReceiveMessage(Stream sock)
        {
            var buf = new byte[4];

            sock.Read(buf, 0, 4);

            using (var stream = new BinaryHeapStream(buf))
            {
                var size = stream.ReadInt();
                buf = new byte[size];
                sock.Read(buf, 0, size);
                return(buf);
            }
        }
        public void TestArrayComparer()
        {
            var cmp = (IBinaryEqualityComparer) new BinaryArrayEqualityComparer();

            var ms = new BinaryHeapStream(10);

            Assert.AreEqual(1, cmp.GetHashCode(ms, 0, 0, null, 0, null, null));

            ms.WriteByte(1);
            Assert.AreEqual(31 + 1, cmp.GetHashCode(ms, 0, 1, null, 0, null, null));

            ms.WriteByte(3);
            Assert.AreEqual((31 + 1) * 31 + 3, cmp.GetHashCode(ms, 0, 2, null, 0, null, null));
        }
示例#9
0
        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.WriteLong(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);

                    var requestId = reader.ReadLong();
                    Assert.AreEqual(1, requestId);

                    var res = reader.ReadObject <string>();
                    Assert.AreEqual(cache[1], res);
                }
            }
        }
示例#10
0
        /// <summary>
        /// Handles the response.
        /// </summary>
        private void HandleResponse(byte[] response)
        {
            var stream    = new BinaryHeapStream(response);
            var requestId = stream.ReadLong();

            Request req;

            if (!_requests.TryRemove(requestId, out req))
            {
                // Response with unknown id.
                throw new IgniteClientException("Invalid thin client response id: " + requestId);
            }

            req.CompletionSource.TrySetResult(stream);
        }
        /// <summary>
        /// Serializes and deserializes back an instance.
        /// </summary>
        private static IgniteSessionStateStoreData SerializeDeserialize(IgniteSessionStateStoreData data)
        {
            var marsh = BinaryUtils.Marshaller;

            using (var stream = new BinaryHeapStream(128))
            {
                var writer = marsh.StartMarshal(stream);

                data.WriteBinary(writer.GetRawWriter(), false);

                stream.Seek(0, SeekOrigin.Begin);

                return(new IgniteSessionStateStoreData(marsh.StartUnmarshal(stream)));
            }
        }
示例#12
0
        /// <summary>
        /// Writes the message to a byte array.
        /// </summary>
        private static byte[] WriteMessage(Action <IBinaryStream> writeAction, int bufSize, out int messageLen)
        {
            using (var stream = new BinaryHeapStream(bufSize))
            {
                stream.WriteInt(0); // Reserve message size.

                writeAction(stream);

                stream.WriteInt(0, stream.Position - 4); // Write message size.

                messageLen = stream.Position;

                return(stream.GetArray());
            }
        }
示例#13
0
        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <param name="obj">The object.</param>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
        /// </returns>
        public int GetHashCode(IBinaryObject obj)
        {
            if (obj == null)
            {
                return(0);
            }

            var binObj = GetBinaryObject(obj);

            var arg = new KeyValuePair <int, int>(GetDataStart(binObj), GetDataLength(binObj));

            using (var stream = new BinaryHeapStream(binObj.Data))
            {
                return(stream.Apply(this, arg));
            }
        }
示例#14
0
        /// <summary>
        /// Serializes and deserializes back an instance.
        /// </summary>
        private static IgniteSessionStateItemCollection SerializeDeserialize(IgniteSessionStateItemCollection data,
                                                                             bool changesOnly = false)
        {
            var marsh = BinaryUtils.Marshaller;

            using (var stream = new BinaryHeapStream(128))
            {
                var writer = marsh.StartMarshal(stream);

                data.WriteBinary(writer.GetRawWriter(), changesOnly);

                stream.Seek(0, SeekOrigin.Begin);

                return(new IgniteSessionStateItemCollection(marsh.StartUnmarshal(stream)));
            }
        }
示例#15
0
        /// <summary>
        /// Lazy fields initialization routine.
        /// </summary>
        private void InitializeFields(IBinaryTypeDescriptor desc = null)
        {
            if (_fields != null)
            {
                return;
            }

            desc = desc ?? _marsh.GetDescriptor(true, _header.TypeId);

            using (var stream = new BinaryHeapStream(_data))
            {
                var hdr = BinaryObjectHeader.Read(stream, _offset);

                _fields = BinaryObjectSchemaSerializer.ReadSchema(stream, _offset, hdr, desc.Schema, _marsh)
                          .ToDictionary() ?? EmptyFields;
            }
        }
示例#16
0
        /// <summary>
        /// Performs client protocol handshake.
        /// </summary>
        private void Handshake(ClientProtocolVersion version)
        {
            // Send request.
            int messageLen;
            var buf = WriteMessage(stream =>
            {
                // Handshake.
                stream.WriteByte(OpHandshake);

                // Protocol version.
                stream.WriteShort(version.Major);
                stream.WriteShort(version.Minor);
                stream.WriteShort(version.Maintenance);

                // Client type: platform.
                stream.WriteByte(ClientType);
            }, 12, out messageLen);

            Debug.Assert(messageLen == 12);

            var sent = _socket.Send(buf, messageLen, SocketFlags.None);

            Debug.Assert(sent == messageLen);

            // Decode response.
            var res = ReceiveMessage();

            using (var stream = new BinaryHeapStream(res))
            {
                var success = stream.ReadBool();

                if (success)
                {
                    return;
                }

                var serverVersion =
                    new ClientProtocolVersion(stream.ReadShort(), stream.ReadShort(), stream.ReadShort());

                var errMsg = BinaryUtils.Marshaller.Unmarshal <string>(stream);

                throw new IgniteClientException(string.Format(
                                                    "Client handshake failed: '{0}'. Client version: {1}. Server version: {2}",
                                                    errMsg, version, serverVersion));
            }
        }
示例#17
0
        /// <summary>
        /// Process child builder.
        /// </summary>
        /// <param name="outStream">Output stream.</param>
        /// <param name="builder">Builder.</param>
        internal void ProcessBuilder(IBinaryStream outStream, BinaryObjectBuilder builder)
        {
            BinaryHeapStream inStream = new BinaryHeapStream(builder._obj.Data);

            inStream.Seek(builder._obj.Offset, SeekOrigin.Begin);

            // Builder parent context might be null only in one case: if we never met this group of
            // builders before. In this case we set context to their parent and track it. Context
            // cleanup will be performed at the very end of build process.
            if (builder._parent._ctx == null || builder._parent._ctx.Closed)
            {
                builder._parent._ctx = new Context(_parent._ctx);
            }

            builder.Mutate(inStream, outStream as BinaryHeapStream, builder._desc,
                           builder._hashCode, builder._vals);
        }
示例#18
0
        public void TestCacheGet()
        {
            var ignite = Ignition.GetIgnite();

            var marsh = ((Ignite)ignite).Marshaller;

            // Create cache.
            var cache = GetCache <string>();

            cache[1] = "bar";

            // Connect socket.
            var sock = GetSocket();

            // Cache get.
            SendRequest(sock, stream =>
            {
                stream.WriteShort(1000); // OP_GET
                stream.WriteLong(1);     // Request id.
                var cacheId = BinaryUtils.GetStringHashCodeLowerCase(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);

                var requestId = reader.ReadLong();
                Assert.AreEqual(1, requestId);

                var status = reader.ReadInt();
                Assert.AreEqual(0, status); // Success.

                var res = reader.ReadObject <string>();
                Assert.AreEqual(cache[1], res);
            }
        }
示例#19
0
        public void TestCustomConfigurationPropagatesToServer()
        {
            var cfg1 = new AtomicClientConfiguration
            {
                AtomicSequenceReserveSize = 32,
                Backups   = 2,
                CacheMode = CacheMode.Partitioned,
                GroupName = "atomics-partitioned"
            };

            var cfg2 = new AtomicClientConfiguration
            {
                AtomicSequenceReserveSize = 33,
                Backups   = 3,
                CacheMode = CacheMode.Replicated,
                GroupName = "atomics-replicated"
            };

            var name = TestUtils.TestName;

            var atomicLong1 = Client.GetAtomicLong(name, cfg1, 1, true);
            var atomicLong2 = Client.GetAtomicLong(name, cfg2, 2, true);
            var atomicLong3 = Client.GetAtomicLong(name, 3, true);

            var cacheConfigBytes = GetIgnite().GetCompute().ExecuteJavaTask <byte[]>(
                "org.apache.ignite.platform.PlatformGetInternalCachesTask", null);

            Assert.IsNotNull(cacheConfigBytes);

            var stream = new BinaryHeapStream(cacheConfigBytes);
            var reader = new BinaryReader(BinaryUtils.Marshaller, stream, BinaryMode.Deserialize, null);

            var caches = Enumerable.Range(0, reader.ReadInt())
                         .Select(_ => new CacheConfiguration(reader))
                         .ToDictionary(c => c.Name);

            Assert.AreEqual(2, caches["ignite-sys-atomic-cache@atomics-partitioned"].Backups);
            Assert.AreEqual(int.MaxValue, caches["ignite-sys-atomic-cache@atomics-replicated"].Backups);
            Assert.AreEqual(1, caches["ignite-sys-atomic-cache@default-ds-group"].Backups);

            Assert.AreEqual(1, atomicLong1.Read());
            Assert.AreEqual(2, atomicLong2.Read());
            Assert.AreEqual(3, atomicLong3.Read());
        }
示例#20
0
        /// <summary>
        /// Decodes the response that we got from <see cref="HandleResponse"/>.
        /// </summary>
        private static T DecodeResponse <T>(BinaryHeapStream stream, Func <IBinaryStream, T> readFunc,
                                            Func <ClientStatusCode, string, T> errorFunc)
        {
            var statusCode = (ClientStatusCode)stream.ReadInt();

            if (statusCode == ClientStatusCode.Success)
            {
                return(readFunc != null?readFunc(stream) : default(T));
            }

            var msg = BinaryUtils.Marshaller.StartUnmarshal(stream).ReadString();

            if (errorFunc != null)
            {
                return(errorFunc(statusCode, msg));
            }

            throw new IgniteClientException(msg, null, statusCode);
        }
示例#21
0
        /// <summary>
        /// Writes the message to a byte array.
        /// </summary>
        private RequestMessage WriteMessage(Action <IBinaryStream> writeAction, ClientOp opId)
        {
            ValidateOp(opId);

            var requestId = Interlocked.Increment(ref _requestId);

            // Potential perf improvements:
            // * ArrayPool<T>
            // * Write to socket stream directly (not trivial because of unknown size)
            var stream = new BinaryHeapStream(256);

            stream.WriteInt(0); // Reserve message size.
            stream.WriteShort((short)opId);
            stream.WriteLong(requestId);
            writeAction(stream);
            stream.WriteInt(0, stream.Position - 4); // Write message size.

            return(new RequestMessage(requestId, stream.GetArray(), stream.Position));
        }
示例#22
0
        /// <summary>
        /// Decodes the response that we got from <see cref="HandleResponse"/>.
        /// </summary>
        private T DecodeResponse <T>(BinaryHeapStream stream, Func <ClientResponseContext, T> readFunc,
                                     Func <ClientStatusCode, string, T> errorFunc)
        {
            ClientStatusCode statusCode;

            if (ServerVersion >= Ver140)
            {
                var flags = (ClientFlags)stream.ReadShort();

                if ((flags & ClientFlags.AffinityTopologyChanged) == ClientFlags.AffinityTopologyChanged)
                {
                    var topVer = new AffinityTopologyVersion(stream.ReadLong(), stream.ReadInt());
                    if (_topVerCallback != null)
                    {
                        _topVerCallback(topVer);
                    }
                }

                statusCode = (flags & ClientFlags.Error) == ClientFlags.Error
                    ? (ClientStatusCode)stream.ReadInt()
                    : ClientStatusCode.Success;
            }
            else
            {
                statusCode = (ClientStatusCode)stream.ReadInt();
            }

            if (statusCode == ClientStatusCode.Success)
            {
                return(readFunc != null
                    ? readFunc(new ClientResponseContext(stream, this))
                    : default(T));
            }

            var msg = BinaryUtils.Marshaller.StartUnmarshal(stream).ReadString();

            if (errorFunc != null)
            {
                return(errorFunc(statusCode, msg));
            }

            throw new IgniteClientException(msg, null, statusCode);
        }
        private IBinaryRawReader SetUpRawBinaryReader(byte[] hash)
        {
            var marsh = BinaryUtils.Marshaller;

            using (var stream = new BinaryHeapStream(128))
            {
                var writer = marsh.StartMarshal(stream);

                writer.WriteByte(_defaultVersion.Major);
                writer.WriteByte(_defaultVersion.Minor);
                writer.WriteByte(_defaultVersion.Maintenance);
                writer.WriteString(_defaultVersion.Stage);
                writer.WriteLong(BinaryUtils.DateTimeToJavaTicks(_defaultVersion.ReleaseDate));
                writer.WriteByteArray(hash);

                stream.Seek(0, SeekOrigin.Begin);

                return(marsh.StartUnmarshal(stream));
            }
        }
示例#24
0
        public void TestCustomPosition()
        {
            var stream = new BinaryHeapStream(16);

            stream.WriteLong(54);

            var marsh = new Marshaller(new BinaryConfiguration());

            var writer = new BinaryWriter(marsh, stream);

            writer.WriteChar('x');

            stream.Seek(0, SeekOrigin.Begin);

            Assert.AreEqual(54, stream.ReadLong());

            var reader = new BinaryReader(marsh, stream, BinaryMode.Deserialize, null);

            Assert.AreEqual('x', reader.ReadChar());
        }
示例#25
0
        /// <summary>
        /// Create empty binary object from descriptor.
        /// </summary>
        /// <param name="desc">Descriptor.</param>
        /// <returns>Empty binary object.</returns>
        private BinaryObject BinaryFromDescriptor(IBinaryTypeDescriptor desc)
        {
            const int len = BinaryObjectHeader.Size;

            var flags = desc.UserType ? BinaryObjectHeader.Flag.UserType : BinaryObjectHeader.Flag.None;

            if (_marsh.CompactFooter && desc.UserType)
            {
                flags |= BinaryObjectHeader.Flag.CompactFooter;
            }

            var hdr = new BinaryObjectHeader(desc.TypeId, 0, len, 0, len, flags);

            using (var stream = new BinaryHeapStream(len))
            {
                BinaryObjectHeader.Write(hdr, stream, 0);

                return(new BinaryObject(_marsh, stream.InternalArray, 0, hdr));
            }
        }
示例#26
0
        /// <summary>
        /// Handles the notification message, if present in the given stream.
        /// </summary>
        private bool HandleNotification(long requestId, BinaryHeapStream stream)
        {
            if (ServerVersion < Ver160)
            {
                return(false);
            }

            var flags = (ClientFlags)stream.ReadShort();

            stream.Seek(-2, SeekOrigin.Current);

            if ((flags & ClientFlags.Notification) != ClientFlags.Notification)
            {
                return(false);
            }

            _notificationListeners.GetOrAdd(requestId, _ => new ClientNotificationHandler(_logger))
            .Handle(stream, null);

            return(true);
        }
示例#27
0
        /// <summary>
        /// Sends the request synchronously.
        /// </summary>
        private BinaryHeapStream SendRequest(ref RequestMessage reqMsg)
        {
            // Do not enter lock when disposed.
            CheckException();

            // If there are no pending async requests, we can execute this operation synchronously,
            // which is more efficient.
            var lockTaken = false;

            try
            {
                Monitor.TryEnter(_sendRequestSyncRoot, 0, ref lockTaken);
                if (lockTaken)
                {
                    CheckException();

                    if (_requests.IsEmpty)
                    {
                        SocketWrite(reqMsg.Buffer, reqMsg.Length);

                        var respMsg    = ReceiveMessage();
                        var response   = new BinaryHeapStream(respMsg);
                        var responseId = response.ReadLong();
                        Debug.Assert(responseId == reqMsg.Id);

                        return(response);
                    }
                }
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(_sendRequestSyncRoot);
                }
            }

            // Fallback to async mechanism.
            return(SendRequestAsync(ref reqMsg).Result);
        }
示例#28
0
        /// <summary>
        /// Internal deserialization routine.
        /// </summary>
        /// <param name="mode">The mode.</param>
        /// <returns>
        /// Deserialized object.
        /// </returns>
        private T Deserialize <T>(BinaryMode mode)
        {
            if (_deserialized == null)
            {
                IBinaryStream stream = new BinaryHeapStream(_data);

                stream.Seek(_offset, SeekOrigin.Begin);

                T res = _marsh.Unmarshal <T>(stream, mode);

                IBinaryTypeDescriptor desc = _marsh.GetDescriptor(true, _header.TypeId);

                if (!desc.KeepDeserialized)
                {
                    return(res);
                }

                _deserialized = res;
            }

            return((T)_deserialized);
        }
示例#29
0
        /// <summary>
        /// Performs a send-receive operation.
        /// </summary>
        public T DoOutInOp <T>(ClientOp opId, Action <IBinaryStream> writeAction,
                               Func <IBinaryStream, T> readFunc, Func <ClientStatus, string, T> errorFunc = null)
        {
            var requestId = Interlocked.Increment(ref _requestId);

            var resBytes = SendReceive(_socket, stream =>
            {
                stream.WriteShort((short)opId);
                stream.WriteLong(requestId);

                if (writeAction != null)
                {
                    writeAction(stream);
                }
            });

            using (var stream = new BinaryHeapStream(resBytes))
            {
                var resRequestId = stream.ReadLong();
                Debug.Assert(requestId == resRequestId);

                var statusCode = (ClientStatus)stream.ReadInt();

                if (statusCode == ClientStatus.Success)
                {
                    return(readFunc != null?readFunc(stream) : default(T));
                }

                var msg = BinaryUtils.Marshaller.StartUnmarshal(stream).ReadString();

                if (errorFunc != null)
                {
                    return(errorFunc(statusCode, msg));
                }

                throw new IgniteClientException(msg, null, (int)statusCode);
            }
        }
示例#30
0
        /// <summary>
        /// Sends the request synchronously.
        /// </summary>
        private BinaryHeapStream SendRequest(ref RequestMessage reqMsg)
        {
            // Do not enter lock when disposed.
            CheckException();

            // If there are no pending async requests, we can execute this operation synchronously,
            // which is more efficient.
            if (_sendRequestLock.TryEnterWriteLock(0))
            {
                try
                {
                    CheckException();

                    if (_requests.IsEmpty)
                    {
                        _socket.Send(reqMsg.Buffer, 0, reqMsg.Length, SocketFlags.None);

                        var respMsg    = ReceiveMessage();
                        var response   = new BinaryHeapStream(respMsg);
                        var responseId = response.ReadLong();
                        Debug.Assert(responseId == reqMsg.Id);

                        return(response);
                    }
                }
                finally
                {
                    if (_sendRequestLock.IsWriteLockHeld)
                    {
                        _sendRequestLock.ExitWriteLock();
                    }
                }
            }

            // Fallback to async mechanism.
            return(SendRequestAsync(ref reqMsg).Result);
        }