diff --git a/RabbitMQ.AMQP.Client/IEnvironment.cs b/RabbitMQ.AMQP.Client/IEnvironment.cs
index 6993868..258b9be 100644
--- a/RabbitMQ.AMQP.Client/IEnvironment.cs
+++ b/RabbitMQ.AMQP.Client/IEnvironment.cs
@@ -2,38 +2,42 @@
// 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.Collections.ObjectModel;
using System.Threading.Tasks;
namespace RabbitMQ.AMQP.Client
{
///
- /// Interface to create IConnections and manage them.
+ ///
+ /// The is the main entry point to a node or a cluster of nodes.
+ ///
+ ///
+ /// The method allows creating instances.
+ /// An application is expected to maintain a single instance and to close that instance
+ /// upon application exit.
+ ///
+ ///
+ /// instances are expected to be thread-safe.
+ ///
///
public interface IEnvironment
{
///
- /// Create a new connection with the given connection settings.
+ /// Create a new with the given connection settings.
///
///
- /// IConnection
+ /// instance.
public Task CreateConnectionAsync(ConnectionSettings connectionSettings);
///
- /// Create a new connection with the default connection settings.
+ /// Create a new with the default connection settings.
///
- /// IConnection
+ /// instance.
public Task CreateConnectionAsync();
///
- /// Get all connections.
+ /// Close this environment and its resources.
///
- public ReadOnlyCollection GetConnections();
-
- ///
- /// Close all connections.
- ///
- ///
+ ///
// TODO cancellation token
Task CloseAsync();
}
diff --git a/RabbitMQ.AMQP.Client/Impl/AmqpEnvironment.cs b/RabbitMQ.AMQP.Client/Impl/AmqpEnvironment.cs
index c3c3e72..df358a1 100644
--- a/RabbitMQ.AMQP.Client/Impl/AmqpEnvironment.cs
+++ b/RabbitMQ.AMQP.Client/Impl/AmqpEnvironment.cs
@@ -3,13 +3,21 @@
// Copyright (c) 2017-2024 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
using System.Collections.Concurrent;
-using System.Collections.ObjectModel;
+using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace RabbitMQ.AMQP.Client.Impl
{
+ ///
+ ///
+ /// is the implementation of .
+ ///
+ ///
+ /// The method allows creating instances.
+ ///
+ ///
public class AmqpEnvironment : IEnvironment
{
private ConnectionSettings ConnectionSettings { get; }
@@ -23,12 +31,24 @@ private AmqpEnvironment(ConnectionSettings connectionSettings, IMetricsReporter?
_metricsReporter = metricsReporter;
}
- // TODO to play nicely with IoC containers, we should not have static Create methods
+ ///
+ /// Create a new instance, using the provided
+ /// and optional
+ ///
+ ///
+ ///
+ /// instance.
public static IEnvironment Create(ConnectionSettings connectionSettings, IMetricsReporter? metricsReporter = default)
{
+ // TODO to play nicely with IoC containers, we should not have static Create methods
return new AmqpEnvironment(connectionSettings, metricsReporter);
}
+ ///
+ /// Create a new instance, using the provided .
+ ///
+ ///
+ /// instance.
public async Task CreateConnectionAsync(ConnectionSettings connectionSettings)
{
IConnection c = await AmqpConnection.CreateAsync(connectionSettings, _metricsReporter).ConfigureAwait(false);
@@ -49,6 +69,10 @@ public async Task CreateConnectionAsync(ConnectionSettings connecti
return c;
}
+ ///
+ /// Create a new instance, using the .
+ ///
+ /// instance.
public Task CreateConnectionAsync()
{
if (ConnectionSettings is null)
@@ -59,13 +83,16 @@ public Task CreateConnectionAsync()
return CreateConnectionAsync(ConnectionSettings);
}
- public ReadOnlyCollection GetConnections() =>
- new(_connections.Values.ToList());
-
+ ///
+ /// Close this environment and its resources.
+ ///
+ ///
// TODO cancellation token
public Task CloseAsync()
{
return Task.WhenAll(_connections.Values.Select(c => c.CloseAsync()));
}
+
+ internal IList Connections => _connections.Values.ToList();
}
}
diff --git a/RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt b/RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt
index 7b38b66..51477cf 100644
--- a/RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt
+++ b/RabbitMQ.AMQP.Client/PublicAPI.Unshipped.txt
@@ -214,7 +214,6 @@ RabbitMQ.AMQP.Client.IEnvironment
RabbitMQ.AMQP.Client.IEnvironment.CloseAsync() -> System.Threading.Tasks.Task!
RabbitMQ.AMQP.Client.IEnvironment.CreateConnectionAsync() -> System.Threading.Tasks.Task!
RabbitMQ.AMQP.Client.IEnvironment.CreateConnectionAsync(RabbitMQ.AMQP.Client.ConnectionSettings! connectionSettings) -> System.Threading.Tasks.Task!
-RabbitMQ.AMQP.Client.IEnvironment.GetConnections() -> System.Collections.ObjectModel.ReadOnlyCollection!
RabbitMQ.AMQP.Client.IExchangeSpecification
RabbitMQ.AMQP.Client.IExchangeSpecification.Argument(string! key, object! value) -> RabbitMQ.AMQP.Client.IExchangeSpecification!
RabbitMQ.AMQP.Client.IExchangeSpecification.Arguments(System.Collections.Generic.Dictionary! arguments) -> RabbitMQ.AMQP.Client.IExchangeSpecification!
@@ -361,7 +360,6 @@ RabbitMQ.AMQP.Client.Impl.AmqpEnvironment
RabbitMQ.AMQP.Client.Impl.AmqpEnvironment.CloseAsync() -> System.Threading.Tasks.Task!
RabbitMQ.AMQP.Client.Impl.AmqpEnvironment.CreateConnectionAsync() -> System.Threading.Tasks.Task!
RabbitMQ.AMQP.Client.Impl.AmqpEnvironment.CreateConnectionAsync(RabbitMQ.AMQP.Client.ConnectionSettings! connectionSettings) -> System.Threading.Tasks.Task!
-RabbitMQ.AMQP.Client.Impl.AmqpEnvironment.GetConnections() -> System.Collections.ObjectModel.ReadOnlyCollection!
RabbitMQ.AMQP.Client.Impl.AmqpExchangeSpecification
RabbitMQ.AMQP.Client.Impl.AmqpExchangeSpecification.AmqpExchangeSpecification(RabbitMQ.AMQP.Client.Impl.AmqpManagement! management) -> void
RabbitMQ.AMQP.Client.Impl.AmqpExchangeSpecification.Argument(string! key, object! value) -> RabbitMQ.AMQP.Client.IExchangeSpecification!
diff --git a/Tests/ClusterTests.cs b/Tests/ClusterTests.cs
index 1a073a3..8513e6e 100644
--- a/Tests/ClusterTests.cs
+++ b/Tests/ClusterTests.cs
@@ -33,15 +33,17 @@ public async Task CreateConnectionWithEnvironmentAndMultipleUris()
ConnectionSettings connectionSettings = connectionSettingBuilder.Build();
IEnvironment env = AmqpEnvironment.Create(connectionSettings);
+ var amqpEnv = (AmqpEnvironment)env;
// Note: by using _connection, the test will dispose the object on teardown
_connection = await env.CreateConnectionAsync();
Assert.NotNull(_connection);
- Assert.NotEmpty(env.GetConnections());
+
+ Assert.NotEmpty(amqpEnv.Connections);
await env.CloseAsync();
Assert.Equal(State.Closed, _connection.State);
- Assert.Empty(env.GetConnections());
+ Assert.Empty(amqpEnv.Connections);
}
}
diff --git a/Tests/EnvironmentTests.cs b/Tests/EnvironmentTests.cs
index 786da93..5f10beb 100644
--- a/Tests/EnvironmentTests.cs
+++ b/Tests/EnvironmentTests.cs
@@ -18,82 +18,92 @@ public class EnvironmentTests(ITestOutputHelper testOutputHelper)
public async Task CreateAConnectionWithEnvironment()
{
IEnvironment env = AmqpEnvironment.Create(ConnectionSettingsBuilder.Create().Build());
+ var amqpEnv = (AmqpEnvironment)env;
+
IConnection connection = await env.CreateConnectionAsync();
+
Assert.NotNull(connection);
- Assert.NotEmpty(env.GetConnections());
+ Assert.NotEmpty(amqpEnv.Connections);
await env.CloseAsync();
Assert.Equal(State.Closed, connection.State);
- Assert.Empty(env.GetConnections());
+ Assert.Empty(amqpEnv.Connections);
}
[Fact]
public async Task CreateMoreConnectionsWithDifferentParametersEnvironment()
{
string envConnectionName = "EnvironmentConnection_" + Guid.NewGuid();
+
IEnvironment env = AmqpEnvironment.Create(
ConnectionSettingsBuilder.Create().ContainerId(envConnectionName).Build());
+ var amqpEnv = (AmqpEnvironment)env;
IConnection connection = await env.CreateConnectionAsync();
+
Assert.NotNull(connection);
await WaitUntilConnectionIsOpen(envConnectionName);
- Assert.NotEmpty(env.GetConnections());
- Assert.Single(env.GetConnections());
+ Assert.NotEmpty(amqpEnv.Connections);
+ Assert.Single(amqpEnv.Connections);
string envConnectionName2 = "EnvironmentConnection2_" + Guid.NewGuid();
IConnection connection2 = await env.CreateConnectionAsync(
ConnectionSettingsBuilder.Create().ContainerId(envConnectionName2).Build());
Assert.NotNull(connection2);
- Assert.Equal(2, env.GetConnections().Count);
+ Assert.Equal(2, amqpEnv.Connections.Count);
await WaitUntilConnectionIsOpen(envConnectionName2);
await env.CloseAsync();
Assert.Equal(State.Closed, connection.State);
Assert.Equal(State.Closed, connection2.State);
- Assert.Empty(env.GetConnections());
+ Assert.Empty(amqpEnv.Connections);
}
[Fact]
public async Task CloseConnectionsIndividually()
{
string envConnectionName = "EnvironmentConnection_" + Guid.NewGuid();
+
IEnvironment env = AmqpEnvironment.Create(
ConnectionSettingsBuilder.Create().ContainerId(envConnectionName).Build());
+ var amqpEnv = (AmqpEnvironment)env;
+
IConnection connection = await env.CreateConnectionAsync();
+
await WaitUntilConnectionIsOpen(envConnectionName);
- Assert.Single(env.GetConnections());
- Assert.Equal(1, env.GetConnections()[0].Id);
+ Assert.Single(amqpEnv.Connections);
+ Assert.Equal(1, amqpEnv.Connections[0].Id);
string envConnectionName2 = "EnvironmentConnection2_" + Guid.NewGuid().ToString();
IConnection connection2 = await env.CreateConnectionAsync(
ConnectionSettingsBuilder.Create().ContainerId(envConnectionName2).Build());
- Assert.Equal(2, env.GetConnections().Count);
- Assert.Equal(2, env.GetConnections()[1].Id);
+ Assert.Equal(2, amqpEnv.Connections.Count);
+ Assert.Equal(2, amqpEnv.Connections[1].Id);
await WaitUntilConnectionIsOpen(envConnectionName2);
string envConnectionName3 = "EnvironmentConnection3_" + Guid.NewGuid().ToString();
IConnection connection3 = await env.CreateConnectionAsync(
ConnectionSettingsBuilder.Create().ContainerId(envConnectionName3).Build());
- Assert.Equal(3, env.GetConnections().Count);
- Assert.Equal(3, env.GetConnections()[2].Id);
+ Assert.Equal(3, amqpEnv.Connections.Count);
+ Assert.Equal(3, amqpEnv.Connections[2].Id);
await WaitUntilConnectionIsOpen(envConnectionName3);
// closing
await connection.CloseAsync();
Assert.Equal(State.Closed, connection.State);
- Assert.Equal(2, env.GetConnections().Count);
+ Assert.Equal(2, amqpEnv.Connections.Count);
await WaitUntilConnectionIsClosed(envConnectionName);
await connection2.CloseAsync();
Assert.Equal(State.Closed, connection2.State);
- Assert.Single(env.GetConnections());
+ Assert.Single(amqpEnv.Connections);
await WaitUntilConnectionIsClosed(envConnectionName2);
await connection3.CloseAsync();
Assert.Equal(State.Closed, connection3.State);
await WaitUntilConnectionIsClosed(envConnectionName3);
- Assert.Empty(env.GetConnections());
+ Assert.Empty(amqpEnv.Connections);
await env.CloseAsync();
}
}