From f7ebd0e42436a3c92b2f5fa79f16eeb76c37435f Mon Sep 17 00:00:00 2001 From: Luke Bakken Date: Wed, 20 Nov 2024 15:45:57 -0800 Subject: [PATCH] Implement support for connecting to ClusterTests Fixes #95 * Start adding Uris to ConnectionSettings. * Add ClusterTests file. --- RabbitMQ.AMQP.Client/ConnectionSettings.cs | 21 ++++++--- RabbitMQ.AMQP.Client/IConnectionSettings.cs | 2 + RabbitMQ.AMQP.Client/Impl/AmqpConnection.cs | 3 ++ RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt | 5 ++- Tests/ClusterTests.cs | 46 ++++++++++++++++++++ 5 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 Tests/ClusterTests.cs diff --git a/RabbitMQ.AMQP.Client/ConnectionSettings.cs b/RabbitMQ.AMQP.Client/ConnectionSettings.cs index 081d400..df44277 100644 --- a/RabbitMQ.AMQP.Client/ConnectionSettings.cs +++ b/RabbitMQ.AMQP.Client/ConnectionSettings.cs @@ -3,6 +3,8 @@ // Copyright (c) 2017-2024 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. using System; +using System.Collections.Generic; +using System.Linq; using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; @@ -10,6 +12,7 @@ namespace RabbitMQ.AMQP.Client { + // TODO rename to ConnectionSettingsBuilder public class ConnectionSettingBuilder { // TODO: maybe add the event "LifeCycle" to the builder @@ -23,10 +26,7 @@ public class ConnectionSettingBuilder private uint _maxFrameSize = Consts.DefaultMaxFrameSize; private SaslMechanism _saslMechanism = Client.SaslMechanism.Anonymous; private IRecoveryConfiguration _recoveryConfiguration = Impl.RecoveryConfiguration.Create(); - - private ConnectionSettingBuilder() - { - } + private IList? _uris; public static ConnectionSettingBuilder Create() { @@ -105,8 +105,15 @@ public ConnectionSettingBuilder RecoveryConfiguration(IRecoveryConfiguration rec return this; } + public ConnectionSettingBuilder Uris(IEnumerable uris) + { + _uris = uris.ToList(); + return this; + } + public ConnectionSettings Build() { + // TODO this should do something similar to consolidate in the Java code var c = new ConnectionSettings(_scheme, _host, _port, _user, _password, _virtualHost, _containerId, _saslMechanism, @@ -129,9 +136,9 @@ public class ConnectionSettings : IEquatable private readonly SaslMechanism _saslMechanism = SaslMechanism.Plain; private readonly IRecoveryConfiguration _recoveryConfiguration = Impl.RecoveryConfiguration.Create(); - public ConnectionSettings(string address, TlsSettings? tlsSettings = null) + public ConnectionSettings(string uri, TlsSettings? tlsSettings = null) { - _address = new Address(address); + _address = new Address(uri); _tlsSettings = tlsSettings; if (_address.UseSsl && _tlsSettings == null) @@ -252,6 +259,8 @@ bool IEquatable.Equals(ConnectionSettings? other) internal Address Address => _address; + public IEnumerable? Uris => throw new NotImplementedException(); + // public RecoveryConfiguration RecoveryConfiguration { get; set; } = RecoveryConfiguration.Create(); } diff --git a/RabbitMQ.AMQP.Client/IConnectionSettings.cs b/RabbitMQ.AMQP.Client/IConnectionSettings.cs index c8e6c0c..e91b227 100644 --- a/RabbitMQ.AMQP.Client/IConnectionSettings.cs +++ b/RabbitMQ.AMQP.Client/IConnectionSettings.cs @@ -4,6 +4,7 @@ #if TOOMANYINTERFACES using System; +using System.Collections.Generic; using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; @@ -25,6 +26,7 @@ public interface ConnectionSettings : IEquatable SaslMechanism SaslMechanism { get; } TlsSettings? TlsSettings { get; } IRecoveryConfiguration Recovery { get; } + IEnumerable? Uris { get; } } /// diff --git a/RabbitMQ.AMQP.Client/Impl/AmqpConnection.cs b/RabbitMQ.AMQP.Client/Impl/AmqpConnection.cs index 15afa2a..ce00927 100644 --- a/RabbitMQ.AMQP.Client/Impl/AmqpConnection.cs +++ b/RabbitMQ.AMQP.Client/Impl/AmqpConnection.cs @@ -359,6 +359,9 @@ void OnOpened(Amqp.IConnection connection, Open openOnOpened) } else { + // TODO + // There is absolutely NO POINT in having an interface if this + // is what will be done! connectionSettings = (ConnectionSettings)_connectionSettings; Address address = connectionSettings.Address; _nativeConnection = await cf.CreateAsync(address: address, open: open, onOpened: OnOpened) diff --git a/RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt b/RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt index fa302c8..09e160c 100644 --- a/RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt +++ b/RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt @@ -51,6 +51,7 @@ RabbitMQ.AMQP.Client.ConnectionException.ConnectionException(string! message) -> RabbitMQ.AMQP.Client.ConnectionException.ConnectionException(string! message, System.Exception! innerException) -> void RabbitMQ.AMQP.Client.ConnectionSettingBuilder RabbitMQ.AMQP.Client.ConnectionSettingBuilder.Build() -> RabbitMQ.AMQP.Client.ConnectionSettings! +RabbitMQ.AMQP.Client.ConnectionSettingBuilder.ConnectionSettingBuilder() -> void RabbitMQ.AMQP.Client.ConnectionSettingBuilder.ContainerId(string! containerId) -> RabbitMQ.AMQP.Client.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.ConnectionSettingBuilder.Host(string! host) -> RabbitMQ.AMQP.Client.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.ConnectionSettingBuilder.MaxFrameSize(uint maxFrameSize) -> RabbitMQ.AMQP.Client.ConnectionSettingBuilder! @@ -59,11 +60,12 @@ RabbitMQ.AMQP.Client.ConnectionSettingBuilder.Port(int port) -> RabbitMQ.AMQP.Cl RabbitMQ.AMQP.Client.ConnectionSettingBuilder.RecoveryConfiguration(RabbitMQ.AMQP.Client.IRecoveryConfiguration! recoveryConfiguration) -> RabbitMQ.AMQP.Client.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.ConnectionSettingBuilder.SaslMechanism(RabbitMQ.AMQP.Client.SaslMechanism! saslMechanism) -> RabbitMQ.AMQP.Client.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.ConnectionSettingBuilder.Scheme(string! scheme) -> RabbitMQ.AMQP.Client.ConnectionSettingBuilder! +RabbitMQ.AMQP.Client.ConnectionSettingBuilder.Uris(System.Collections.Generic.IEnumerable! uris) -> RabbitMQ.AMQP.Client.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.ConnectionSettingBuilder.User(string! user) -> RabbitMQ.AMQP.Client.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.ConnectionSettingBuilder.VirtualHost(string! virtualHost) -> RabbitMQ.AMQP.Client.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.ConnectionSettings -RabbitMQ.AMQP.Client.ConnectionSettings.ConnectionSettings(string! address, RabbitMQ.AMQP.Client.TlsSettings? tlsSettings = null) -> void RabbitMQ.AMQP.Client.ConnectionSettings.ConnectionSettings(string! scheme, string! host, int port, string? user, string? password, string! virtualHost, string! containerId, RabbitMQ.AMQP.Client.SaslMechanism! saslMechanism, RabbitMQ.AMQP.Client.IRecoveryConfiguration! recoveryConfiguration, uint maxFrameSize = 0, RabbitMQ.AMQP.Client.TlsSettings? tlsSettings = null) -> void +RabbitMQ.AMQP.Client.ConnectionSettings.ConnectionSettings(string! uri, RabbitMQ.AMQP.Client.TlsSettings? tlsSettings = null) -> void RabbitMQ.AMQP.Client.ConnectionSettings.ContainerId.get -> string! RabbitMQ.AMQP.Client.ConnectionSettings.Equals(RabbitMQ.AMQP.Client.ConnectionSettings! other) -> bool RabbitMQ.AMQP.Client.ConnectionSettings.Host.get -> string! @@ -75,6 +77,7 @@ RabbitMQ.AMQP.Client.ConnectionSettings.Recovery.get -> RabbitMQ.AMQP.Client.IRe RabbitMQ.AMQP.Client.ConnectionSettings.SaslMechanism.get -> RabbitMQ.AMQP.Client.SaslMechanism! RabbitMQ.AMQP.Client.ConnectionSettings.Scheme.get -> string! RabbitMQ.AMQP.Client.ConnectionSettings.TlsSettings.get -> RabbitMQ.AMQP.Client.TlsSettings? +RabbitMQ.AMQP.Client.ConnectionSettings.Uris.get -> System.Collections.Generic.IEnumerable? RabbitMQ.AMQP.Client.ConnectionSettings.User.get -> string? RabbitMQ.AMQP.Client.ConnectionSettings.UseSsl.get -> bool RabbitMQ.AMQP.Client.ConnectionSettings.VirtualHost.get -> string! diff --git a/Tests/ClusterTests.cs b/Tests/ClusterTests.cs new file mode 100644 index 0000000..db744e8 --- /dev/null +++ b/Tests/ClusterTests.cs @@ -0,0 +1,46 @@ +// This source code is dual-licensed under the Apache License, version 2.0, +// and the Mozilla Public License, version 2.0. +// Copyright (c) 2017-2024 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using RabbitMQ.AMQP.Client; +using Xunit; +using Xunit.Abstractions; + +namespace Tests; + +public class ClusterTests(ITestOutputHelper testOutputHelper) + : IntegrationTest(testOutputHelper, setupConnectionAndManagement: false) +{ + [SkippableFact] + public Task CreateConnectionWithEnvironmentAndMultipleUris() + { + Skip.IfNot(SystemUtils.IsCluster); + + Assert.Null(_connection); + Assert.Null(_management); + + Uri uri0 = new("amqp://localhost:5672"); + Uri uri1 = new("amqp://localhost:5673"); + Uri uri2 = new("amqp://localhost:5674"); + List uris = [uri0, uri1, uri2]; + + ConnectionSettingBuilder connectionSettingBuilder = new(); + connectionSettingBuilder.Uris(uris); + ConnectionSettings connectionSettings = connectionSettingBuilder.Build(); + + /* + IEnvironment env = AmqpEnvironment.Create(ConnectionSettingBuilder.Create().Build()); + IConnection connection = await env.CreateConnectionAsync(); + Assert.NotNull(connection); + Assert.NotEmpty(env.GetConnections()); + await env.CloseAsync(); + Assert.Equal(State.Closed, connection.State); + Assert.Empty(env.GetConnections()); + */ + + return Task.CompletedTask; + } +}