From 56bd2c9cd3030abc18acb2ff4095b0c643950601 Mon Sep 17 00:00:00 2001 From: Luke Bakken Date: Thu, 16 Nov 2023 07:07:14 -0800 Subject: [PATCH] Make TcpClientAdapter public Improve test for SocketFactory Follow-up to: * #1414 * #1415 * #1416 https://groups.google.com/g/rabbitmq-users/c/9_ohuUbX9NY --- .../RabbitMQ.Client/client/api/ITcpClient.cs | 3 +- .../client/{impl => api}/TcpClientAdapter.cs | 28 ++++++++++++------- .../client/impl/SocketFrameHandler.cs | 4 +-- .../client/impl/TcpClientAdapterHelper.cs | 20 ------------- .../Unit/APIApproval.Approve.verified.txt | 14 ++++++++++ projects/Unit/TestConnectionFactory.cs | 18 ++++++++---- projects/Unit/TestTcpClientAdapter.cs | 7 ++--- 7 files changed, 51 insertions(+), 43 deletions(-) rename projects/RabbitMQ.Client/client/{impl => api}/TcpClientAdapter.cs (76%) delete mode 100644 projects/RabbitMQ.Client/client/impl/TcpClientAdapterHelper.cs diff --git a/projects/RabbitMQ.Client/client/api/ITcpClient.cs b/projects/RabbitMQ.Client/client/api/ITcpClient.cs index da8398dd01..6b55246297 100644 --- a/projects/RabbitMQ.Client/client/api/ITcpClient.cs +++ b/projects/RabbitMQ.Client/client/api/ITcpClient.cs @@ -6,7 +6,8 @@ namespace RabbitMQ.Client { /// - /// Wrapper interface for standard TCP-client. Provides socket for socket frame handler class. + /// Wrapper interface for . + /// Provides the socket for socket frame handler class. /// /// Contains all methods that are currently in use in rabbitmq client. public interface ITcpClient : IDisposable diff --git a/projects/RabbitMQ.Client/client/impl/TcpClientAdapter.cs b/projects/RabbitMQ.Client/client/api/TcpClientAdapter.cs similarity index 76% rename from projects/RabbitMQ.Client/client/impl/TcpClientAdapter.cs rename to projects/RabbitMQ.Client/client/api/TcpClientAdapter.cs index 1f85f1967b..faf27dd520 100644 --- a/projects/RabbitMQ.Client/client/impl/TcpClientAdapter.cs +++ b/projects/RabbitMQ.Client/client/api/TcpClientAdapter.cs @@ -1,14 +1,16 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Net; using System.Net.Sockets; using System.Threading.Tasks; -namespace RabbitMQ.Client.Impl +namespace RabbitMQ.Client { /// - /// Simple wrapper around TcpClient. + /// Simple wrapper around . /// - internal class TcpClientAdapter : ITcpClient + public class TcpClientAdapter : ITcpClient { private Socket _sock; @@ -21,7 +23,7 @@ public virtual async Task ConnectAsync(string host, int port) { AssertSocket(); IPAddress[] adds = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false); - IPAddress ep = TcpClientAdapterHelper.GetMatchingHost(adds, _sock.AddressFamily); + IPAddress ep = GetMatchingHost(adds, _sock.AddressFamily); if (ep == default(IPAddress)) { throw new ArgumentException($"No ip address could be resolved for {host}"); @@ -38,12 +40,11 @@ public virtual Task ConnectAsync(IPAddress ep, int port) public virtual void Close() { - _sock?.Dispose(); + _sock.Dispose(); _sock = null; } - [Obsolete("Override Dispose(bool) instead.")] - public virtual void Dispose() + public void Dispose() { Dispose(true); } @@ -52,11 +53,8 @@ protected virtual void Dispose(bool disposing) { if (disposing) { - // dispose managed resources Close(); } - - // dispose unmanaged resources } public virtual NetworkStream GetStream() @@ -106,5 +104,15 @@ private void AssertSocket() throw new InvalidOperationException("Cannot perform operation as socket is null"); } } + + public static IPAddress GetMatchingHost(IReadOnlyCollection addresses, AddressFamily addressFamily) + { + IPAddress ep = addresses.FirstOrDefault(a => a.AddressFamily == addressFamily); + if (ep is null && addresses.Count == 1 && addressFamily == AddressFamily.Unspecified) + { + return addresses.Single(); + } + return ep; + } } } diff --git a/projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs b/projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs index c09bdd1b56..0e91276779 100644 --- a/projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs +++ b/projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs @@ -117,7 +117,7 @@ public SocketFrameHandler(AmqpTcpEndpoint endpoint, // Resolve the hostname to know if it's even possible to even try IPv6 IPAddress[] adds = Dns.GetHostAddresses(endpoint.HostName); - IPAddress ipv6 = TcpClientAdapterHelper.GetMatchingHost(adds, AddressFamily.InterNetworkV6); + IPAddress ipv6 = TcpClientAdapter.GetMatchingHost(adds, AddressFamily.InterNetworkV6); if (ipv6 == default(IPAddress)) { @@ -141,7 +141,7 @@ public SocketFrameHandler(AmqpTcpEndpoint endpoint, if (_socket is null) { - IPAddress ipv4 = TcpClientAdapterHelper.GetMatchingHost(adds, AddressFamily.InterNetwork); + IPAddress ipv4 = TcpClientAdapter.GetMatchingHost(adds, AddressFamily.InterNetwork); if (ipv4 == default(IPAddress)) { throw new ConnectFailureException("Connection failed", new ArgumentException($"No ip address could be resolved for {endpoint.HostName}")); diff --git a/projects/RabbitMQ.Client/client/impl/TcpClientAdapterHelper.cs b/projects/RabbitMQ.Client/client/impl/TcpClientAdapterHelper.cs deleted file mode 100644 index a9a9cf97e1..0000000000 --- a/projects/RabbitMQ.Client/client/impl/TcpClientAdapterHelper.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Sockets; - -namespace RabbitMQ.Client.Impl -{ - internal static class TcpClientAdapterHelper - { - public static IPAddress GetMatchingHost(IReadOnlyCollection addresses, AddressFamily addressFamily) - { - IPAddress ep = addresses.FirstOrDefault(a => a.AddressFamily == addressFamily); - if (ep is null && addresses.Count == 1 && addressFamily == AddressFamily.Unspecified) - { - return addresses.Single(); - } - return ep; - } - } -} diff --git a/projects/Unit/APIApproval.Approve.verified.txt b/projects/Unit/APIApproval.Approve.verified.txt index 8df115691b..d4ccb460b4 100644 --- a/projects/Unit/APIApproval.Approve.verified.txt +++ b/projects/Unit/APIApproval.Approve.verified.txt @@ -765,6 +765,20 @@ namespace RabbitMQ.Client public string ServerName { get; set; } public System.Security.Authentication.SslProtocols Version { get; set; } } + public class TcpClientAdapter : RabbitMQ.Client.ITcpClient, System.IDisposable + { + public TcpClientAdapter(System.Net.Sockets.Socket socket) { } + public virtual System.Net.Sockets.Socket Client { get; } + public virtual bool Connected { get; } + public virtual System.TimeSpan ReceiveTimeout { get; set; } + public virtual void Close() { } + public virtual System.Threading.Tasks.Task ConnectAsync(System.Net.IPAddress ep, int port) { } + public virtual System.Threading.Tasks.Task ConnectAsync(string host, int port) { } + public void Dispose() { } + protected virtual void Dispose(bool disposing) { } + public virtual System.Net.Sockets.NetworkStream GetStream() { } + public static System.Net.IPAddress GetMatchingHost(System.Collections.Generic.IReadOnlyCollection addresses, System.Net.Sockets.AddressFamily addressFamily) { } + } public class TimerBasedCredentialRefresher : RabbitMQ.Client.ICredentialsRefresher { public TimerBasedCredentialRefresher() { } diff --git a/projects/Unit/TestConnectionFactory.cs b/projects/Unit/TestConnectionFactory.cs index 1344a46fd8..2410e60e66 100644 --- a/projects/Unit/TestConnectionFactory.cs +++ b/projects/Unit/TestConnectionFactory.cs @@ -32,7 +32,6 @@ using System.Collections.Generic; using System.Net.Sockets; using RabbitMQ.Client.Exceptions; -using RabbitMQ.Client.Impl; using Xunit; namespace RabbitMQ.Client.Unit @@ -74,7 +73,14 @@ public void TestProperties() [Fact] public void TestConnectionFactoryWithCustomSocketFactory() { - const int bufsz = 1024; + const int testBufsz = 1024; + int defaultReceiveBufsz = 0; + int defaultSendBufsz = 0; + using (var defaultSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP)) + { + defaultReceiveBufsz = defaultSocket.ReceiveBufferSize; + defaultSendBufsz = defaultSocket.SendBufferSize; + } ConnectionFactory cf = new() { @@ -82,8 +88,8 @@ public void TestConnectionFactoryWithCustomSocketFactory() { var socket = new Socket(af, SocketType.Stream, ProtocolType.Tcp) { - SendBufferSize = bufsz, - ReceiveBufferSize = bufsz, + SendBufferSize = testBufsz, + ReceiveBufferSize = testBufsz, NoDelay = false }; return new TcpClientAdapter(socket); @@ -94,8 +100,8 @@ public void TestConnectionFactoryWithCustomSocketFactory() Assert.IsType(c); TcpClientAdapter tcpClientAdapter = (TcpClientAdapter)c; Socket s = tcpClientAdapter.Client; - Assert.Equal(bufsz, s.ReceiveBufferSize); - Assert.Equal(bufsz, s.SendBufferSize); + Assert.NotEqual(defaultReceiveBufsz, s.ReceiveBufferSize); + Assert.NotEqual(defaultSendBufsz, s.SendBufferSize); Assert.False(s.NoDelay); } diff --git a/projects/Unit/TestTcpClientAdapter.cs b/projects/Unit/TestTcpClientAdapter.cs index f3f9009484..1ba197a526 100644 --- a/projects/Unit/TestTcpClientAdapter.cs +++ b/projects/Unit/TestTcpClientAdapter.cs @@ -31,7 +31,6 @@ using System.Net; using System.Net.Sockets; -using RabbitMQ.Client.Impl; using Xunit; namespace RabbitMQ.Client.Unit @@ -42,7 +41,7 @@ public class TestTcpClientAdapter public void TcpClientAdapterHelperGetMatchingHostReturnNoAddressIfFamilyDoesNotMatch() { var address = IPAddress.Parse("127.0.0.1"); - IPAddress matchingAddress = TcpClientAdapterHelper.GetMatchingHost(new[] { address }, AddressFamily.InterNetworkV6); + IPAddress matchingAddress = TcpClientAdapter.GetMatchingHost(new[] { address }, AddressFamily.InterNetworkV6); Assert.Null(matchingAddress); } @@ -50,7 +49,7 @@ public void TcpClientAdapterHelperGetMatchingHostReturnNoAddressIfFamilyDoesNotM public void TcpClientAdapterHelperGetMatchingHostReturnsSingleAddressIfFamilyIsUnspecified() { var address = IPAddress.Parse("1.1.1.1"); - IPAddress matchingAddress = TcpClientAdapterHelper.GetMatchingHost(new[] { address }, AddressFamily.Unspecified); + IPAddress matchingAddress = TcpClientAdapter.GetMatchingHost(new[] { address }, AddressFamily.Unspecified); Assert.Equal(address, matchingAddress); } @@ -59,7 +58,7 @@ public void TcpClientAdapterHelperGetMatchingHostReturnNoAddressIfFamilyIsUnspec { var address = IPAddress.Parse("1.1.1.1"); var address2 = IPAddress.Parse("2.2.2.2"); - IPAddress matchingAddress = TcpClientAdapterHelper.GetMatchingHost(new[] { address, address2 }, AddressFamily.Unspecified); + IPAddress matchingAddress = TcpClientAdapter.GetMatchingHost(new[] { address, address2 }, AddressFamily.Unspecified); Assert.Null(matchingAddress); } }