Beispiel #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ClientSocket" /> class.
        /// </summary>
        /// <param name="clientConfiguration">The client configuration.</param>
        /// <param name="endPoint">The end point to connect to.</param>
        /// <param name="host">The host name (required for SSL).</param>
        /// <param name="version">Protocol version.</param>
        /// <param name="topVerCallback">Topology version update callback.</param>
        public ClientSocket(IgniteClientConfiguration clientConfiguration, EndPoint endPoint, string host,
                            ClientProtocolVersion?version = null,
                            Action <AffinityTopologyVersion> topVerCallback = null)
        {
            Debug.Assert(clientConfiguration != null);

            _topVerCallback = topVerCallback;
            _timeout        = clientConfiguration.SocketTimeout;

            _socket = Connect(clientConfiguration, endPoint);
            _stream = GetSocketStream(_socket, clientConfiguration, host);

            ServerVersion = version ?? CurrentProtocolVersion;

            Validate(clientConfiguration);

            Handshake(clientConfiguration, ServerVersion);

            // Check periodically if any request has timed out.
            if (_timeout > TimeSpan.Zero)
            {
                // Minimum Socket timeout is 500ms.
                _timeoutCheckTimer = new Timer(CheckTimeouts, null, _timeout, TimeSpan.FromMilliseconds(500));
            }

            // Continuously and asynchronously wait for data from server.
            // TaskCreationOptions.LongRunning actually means a new thread.
            TaskRunner.Run(WaitForMessages, TaskCreationOptions.LongRunning);
        }
Beispiel #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ClientSocket" /> class.
        /// </summary>
        /// <param name="clientConfiguration">The client configuration.</param>
        /// <param name="endPoint">The end point to connect to.</param>
        /// <param name="host">The host name (required for SSL).</param>
        /// <param name="onError">Error callback.</param>
        /// <param name="version">Protocol version.</param>
        public ClientSocket(IgniteClientConfiguration clientConfiguration, EndPoint endPoint, string host,
                            Action onError = null, ClientProtocolVersion?version = null)
        {
            Debug.Assert(clientConfiguration != null);

            _onError = onError;
            _timeout = clientConfiguration.SocketTimeout;

            _socket = Connect(clientConfiguration, endPoint);
            _stream = GetSocketStream(_socket, clientConfiguration, host);

            ServerVersion = version ?? CurrentProtocolVersion;

            Validate(clientConfiguration);

            Handshake(clientConfiguration, ServerVersion);

            // Check periodically if any request has timed out.
            if (_timeout > TimeSpan.Zero)
            {
                // Minimum Socket timeout is 500ms.
                _timeoutCheckTimer = new Timer(CheckTimeouts, null, _timeout, TimeSpan.FromMilliseconds(500));
            }

            // Continuously and asynchronously wait for data from server.
            TaskRunner.Run(WaitForMessages);
        }
Beispiel #3
0
        /// <summary>
        /// Performs client protocol handshake.
        /// </summary>
        private static void Handshake(Socket sock, ClientProtocolVersion version)
        {
            var res = SendReceive(sock, stream =>
            {
                // Handshake.
                stream.WriteByte(OpHandshake);

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

                // Client type: platform.
                stream.WriteByte(ClientType);
            }, 20);

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

                if (success)
                {
                    return;
                }

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

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

                throw new IgniteClientException(string.Format(
                                                    "Client handhsake failed: '{0}'. Client version: {1}. Server version: {2}",
                                                    errMsg, version, serverVersion));
            }
        }
Beispiel #4
0
        /// <summary>
        /// Throws minimum version exception.
        /// </summary>
        private void ThrowMinimumVersionException(object operation, ClientProtocolVersion requiredProtocolVersion)
        {
            var message = string.Format("Operation {0} is not supported by protocol version {1}. " +
                                        "Minimum protocol version required is {2}.",
                                        operation, _protocolVersion, requiredProtocolVersion);

            throw new IgniteClientException(message);
        }
Beispiel #5
0
        /// <summary>
        /// Initializes a new instance of <see cref="ClientContextBase"/> class.
        /// </summary>
        /// <param name="stream">Stream.</param>
        /// <param name="marshaller">Marshaller.</param>
        /// <param name="protocolVersion">Protocol version to be used for this request.</param>
        protected ClientContextBase(IBinaryStream stream, Marshaller marshaller, ClientProtocolVersion protocolVersion)
        {
            Debug.Assert(stream != null);
            Debug.Assert(marshaller != null);

            _stream          = stream;
            _marshaller      = marshaller;
            _protocolVersion = protocolVersion;
        }
Beispiel #6
0
        /// <summary>
        /// Validates op code against current protocol version.
        /// </summary>
        /// <param name="operation">Operation.</param>
        /// <param name="protocolVersion">Protocol version.</param>
        /// <param name="requiredProtocolVersion">Required protocol version.</param>
        public static void ValidateOp <T>(T operation, ClientProtocolVersion protocolVersion,
                                          ClientProtocolVersion requiredProtocolVersion)
        {
            if (protocolVersion >= requiredProtocolVersion)
            {
                return;
            }

            var message = string.Format("Operation {0} is not supported by protocol version {1}. " +
                                        "Minimum protocol version required is {2}.",
                                        operation, protocolVersion, requiredProtocolVersion);

            throw new IgniteClientException(message);
        }
Beispiel #7
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));
            }
        }
Beispiel #8
0
        /// <summary>
        /// Performs client protocol handshake.
        /// </summary>
        private void Handshake(IgniteClientConfiguration clientConfiguration, ClientProtocolVersion version)
        {
            bool auth = version.CompareTo(Ver110) >= 0 && clientConfiguration.UserName != null;

            // 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);

                // Authentication data.
                if (auth)
                {
                    var writer = BinaryUtils.Marshaller.StartMarshal(stream);

                    writer.WriteString(clientConfiguration.UserName);
                    writer.WriteString(clientConfiguration.Password);

                    BinaryUtils.Marshaller.FinishMarshal(writer);
                }
            }, 12, out messageLen);

            SocketWrite(buf, messageLen);

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

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

                if (success)
                {
                    if (version.CompareTo(Ver140) >= 0)
                    {
                        ServerNodeId = BinaryUtils.Marshaller.Unmarshal <Guid>(stream);
                    }

                    ServerVersion = version;

                    return;
                }

                ServerVersion =
                    new ClientProtocolVersion(stream.ReadShort(), stream.ReadShort(), stream.ReadShort());

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

                ClientStatusCode errCode = ClientStatusCode.Fail;

                if (stream.Remaining > 0)
                {
                    errCode = (ClientStatusCode)stream.ReadInt();
                }

                // Authentication error is handled immediately.
                if (errCode == ClientStatusCode.AuthenticationFailed)
                {
                    throw new IgniteClientException(errMsg, null, ClientStatusCode.AuthenticationFailed);
                }

                // Re-try if possible.
                bool retry = ServerVersion.CompareTo(version) < 0 && ServerVersion.Equals(Ver100);

                if (retry)
                {
                    Handshake(clientConfiguration, ServerVersion);
                }
                else
                {
                    throw new IgniteClientException(string.Format(
                                                        "Client handshake failed: '{0}'. Client version: {1}. Server version: {2}",
                                                        errMsg, version, ServerVersion), null, errCode);
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Performs client protocol handshake.
        /// </summary>
        private ClientFeatures Handshake(IgniteClientConfiguration clientConfiguration, ClientProtocolVersion version)
        {
            var hasAuth     = version >= Ver110 && clientConfiguration.UserName != null;
            var hasFeatures = version >= Ver170;

            // 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);

                // Writing features.
                if (hasFeatures)
                {
                    BinaryUtils.Marshaller.Marshal(stream,
                                                   w => w.WriteByteArray(ClientFeatures.AllFeatures));
                }

                // Authentication data.
                if (hasAuth)
                {
                    BinaryUtils.Marshaller.Marshal(stream, writer =>
                    {
                        writer.WriteString(clientConfiguration.UserName);
                        writer.WriteString(clientConfiguration.Password);
                    });
                }
            }, 12, out messageLen);

            SocketWrite(buf, messageLen);

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

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

                if (success)
                {
                    BitArray featureBits = null;

                    if (hasFeatures)
                    {
                        featureBits = new BitArray(BinaryUtils.Marshaller.Unmarshal <byte[]>(stream));
                    }

                    if (version >= Ver140)
                    {
                        ServerNodeId = BinaryUtils.Marshaller.Unmarshal <Guid>(stream);
                    }

                    ServerVersion = version;

                    _logger.Debug("Handshake completed on {0}, protocol version = {1}",
                                  _socket.RemoteEndPoint, version);

                    return(new ClientFeatures(version, featureBits));
                }

                ServerVersion =
                    new ClientProtocolVersion(stream.ReadShort(), stream.ReadShort(), stream.ReadShort());

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

                ClientStatusCode errCode = ClientStatusCode.Fail;

                if (stream.Remaining > 0)
                {
                    errCode = (ClientStatusCode)stream.ReadInt();
                }

                _logger.Debug("Handshake failed on {0}, requested protocol version = {1}, " +
                              "server protocol version = {2}, status = {3}, message = {4}",
                              _socket.RemoteEndPoint, version, ServerVersion, errCode, errMsg);

                // Authentication error is handled immediately.
                if (errCode == ClientStatusCode.AuthenticationFailed)
                {
                    throw new IgniteClientException(errMsg, null, ClientStatusCode.AuthenticationFailed);
                }

                // Retry if server version is different and falls within supported version range.
                var retry = ServerVersion != version &&
                            ServerVersion >= Ver100 &&
                            ServerVersion <= CurrentProtocolVersion;

                if (retry)
                {
                    _logger.Debug("Retrying handshake on {0} with protocol version {1}",
                                  _socket.RemoteEndPoint, ServerVersion);

                    return(Handshake(clientConfiguration, ServerVersion));
                }

                throw new IgniteClientException(string.Format(
                                                    "Client handshake failed: '{0}'. Client version: {1}. Server version: {2}",
                                                    errMsg, version, ServerVersion), null, errCode);
            }
        }
Beispiel #10
0
 /// <summary>
 /// Initializes a new instance of <see cref="ClientFeatures"/>.
 /// </summary>
 public ClientFeatures(ClientProtocolVersion protocolVersion, BitArray features)
 {
     _protocolVersion = protocolVersion;
     _features        = features;
 }
 /// <summary>
 /// Initializes a new instance of <see cref="ClientResponseContext"/> class.
 /// </summary>
 /// <param name="stream">Stream.</param>
 /// <param name="marshaller">Marshaller.</param>
 /// <param name="protocolVersion">Protocol version to be used for this response.</param>
 public ClientResponseContext(IBinaryStream stream, Marshaller marshaller, ClientProtocolVersion protocolVersion)
     : base(stream, marshaller, protocolVersion)
 {
     // No-op.
 }
Beispiel #12
0
 /// <summary>
 /// Validates op code against current protocol version.
 /// </summary>
 /// <param name="operation">Operation.</param>
 /// <param name="protocolVersion">Protocol version.</param>
 public static void ValidateOp(ClientOp operation, ClientProtocolVersion protocolVersion)
 {
     ValidateOp(operation, protocolVersion, operation.GetMinVersion());
 }
Beispiel #13
0
 /// <summary>
 /// Initializes a new instance of <see cref="MinVersionAttribute"/> class.
 /// </summary>
 public MinVersionAttribute(short major, short minor, short maintenance)
 {
     _version = new ClientProtocolVersion(major, minor, maintenance);
 }