/// <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); }
/// <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); }
/// <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)); } }
/// <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); }
/// <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; }
/// <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); }
/// <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)); } }
/// <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); } } }
/// <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); } }
/// <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. }
/// <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()); }
/// <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); }