diff --git a/RabbitMQ.AMQP.Client/IConnectionSettings.cs b/RabbitMQ.AMQP.Client/IConnectionSettings.cs index 0710bda..f1521a6 100644 --- a/RabbitMQ.AMQP.Client/IConnectionSettings.cs +++ b/RabbitMQ.AMQP.Client/IConnectionSettings.cs @@ -3,6 +3,7 @@ // 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.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; @@ -24,6 +25,7 @@ public interface IConnectionSettings : IEquatable SaslMechanism SaslMechanism { get; } ITlsSettings? 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 78836e1..d6c1788 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/Impl/ConnectionSettings.cs b/RabbitMQ.AMQP.Client/Impl/ConnectionSettings.cs index c54ce8a..685ea4f 100644 --- a/RabbitMQ.AMQP.Client/Impl/ConnectionSettings.cs +++ b/RabbitMQ.AMQP.Client/Impl/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.Impl { + // 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 : IConnectionSettings private readonly SaslMechanism _saslMechanism = SaslMechanism.Plain; private readonly IRecoveryConfiguration _recoveryConfiguration = RecoveryConfiguration.Create(); - public ConnectionSettings(string address, ITlsSettings? tlsSettings = null) + public ConnectionSettings(string uri, ITlsSettings? tlsSettings = null) { - _address = new Address(address); + _address = new Address(uri); _tlsSettings = tlsSettings; if (_address.UseSsl && _tlsSettings == null) @@ -252,6 +259,8 @@ public bool Equals(IConnectionSettings? other) internal Address Address => _address; + public IEnumerable? Uris => throw new NotImplementedException(); + // public RecoveryConfiguration RecoveryConfiguration { get; set; } = RecoveryConfiguration.Create(); } diff --git a/RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt b/RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt index 29a425e..7a781f5 100644 --- a/RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt +++ b/RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt @@ -116,6 +116,7 @@ RabbitMQ.AMQP.Client.IConnectionSettings.Recovery.get -> RabbitMQ.AMQP.Client.IR RabbitMQ.AMQP.Client.IConnectionSettings.SaslMechanism.get -> RabbitMQ.AMQP.Client.SaslMechanism! RabbitMQ.AMQP.Client.IConnectionSettings.Scheme.get -> string! RabbitMQ.AMQP.Client.IConnectionSettings.TlsSettings.get -> RabbitMQ.AMQP.Client.ITlsSettings? +RabbitMQ.AMQP.Client.IConnectionSettings.Uris.get -> System.Collections.Generic.IEnumerable? RabbitMQ.AMQP.Client.IConnectionSettings.User.get -> string? RabbitMQ.AMQP.Client.IConnectionSettings.UseSsl.get -> bool RabbitMQ.AMQP.Client.IConnectionSettings.VirtualHost.get -> string! @@ -475,8 +476,11 @@ RabbitMQ.AMQP.Client.Impl.BindingSpecification._destinationName -> string! RabbitMQ.AMQP.Client.Impl.BindingSpecification._routingKey -> string! RabbitMQ.AMQP.Client.Impl.BindingSpecification._sourceName -> string! RabbitMQ.AMQP.Client.Impl.BindingSpecification._toQueue -> bool +RabbitMQ.AMQP.Client.Impl.ConnectionSettings.ConnectionSettings(string! uri, RabbitMQ.AMQP.Client.ITlsSettings? tlsSettings = null) -> void +RabbitMQ.AMQP.Client.Impl.ConnectionSettings.Uris.get -> System.Collections.Generic.IEnumerable? RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder.Build() -> RabbitMQ.AMQP.Client.Impl.ConnectionSettings! +RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder.ConnectionSettingBuilder() -> void RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder.ContainerId(string! containerId) -> RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder.Host(string! host) -> RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder.MaxFrameSize(uint maxFrameSize) -> RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder! @@ -485,10 +489,10 @@ RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder.Port(int port) -> RabbitMQ.AM RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder.RecoveryConfiguration(RabbitMQ.AMQP.Client.IRecoveryConfiguration! recoveryConfiguration) -> RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder.SaslMechanism(RabbitMQ.AMQP.Client.SaslMechanism! saslMechanism) -> RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder.Scheme(string! scheme) -> RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder! +RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder.Uris(System.Collections.Generic.IEnumerable! uris) -> RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder.User(string! user) -> RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder.VirtualHost(string! virtualHost) -> RabbitMQ.AMQP.Client.Impl.ConnectionSettingBuilder! RabbitMQ.AMQP.Client.Impl.ConnectionSettings -RabbitMQ.AMQP.Client.Impl.ConnectionSettings.ConnectionSettings(string! address, RabbitMQ.AMQP.Client.ITlsSettings? tlsSettings = null) -> void RabbitMQ.AMQP.Client.Impl.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.ITlsSettings? tlsSettings = null) -> void RabbitMQ.AMQP.Client.Impl.ConnectionSettings.ContainerId.get -> string! RabbitMQ.AMQP.Client.Impl.ConnectionSettings.Equals(RabbitMQ.AMQP.Client.IConnectionSettings? other) -> bool diff --git a/Tests/ClusterTests.cs b/Tests/ClusterTests.cs new file mode 100644 index 0000000..eb39919 --- /dev/null +++ b/Tests/ClusterTests.cs @@ -0,0 +1,47 @@ +// 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 RabbitMQ.AMQP.Client.Impl; +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); + IConnectionSettings 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; + } +}