diff --git a/Source/EasyNetQ.Management.Client.ApprovalTests/EasyNetQ.Management.Client.approved.txt b/Source/EasyNetQ.Management.Client.ApprovalTests/EasyNetQ.Management.Client.approved.txt index cf685570..c6e39840 100644 --- a/Source/EasyNetQ.Management.Client.ApprovalTests/EasyNetQ.Management.Client.approved.txt +++ b/Source/EasyNetQ.Management.Client.ApprovalTests/EasyNetQ.Management.Client.approved.txt @@ -1,10 +1,27 @@ namespace EasyNetQ.Management.Client { + public class DeleteExchangeCriteria : System.IEquatable + { + public System.Collections.Generic.IEnumerable>? QueryParameters; + public static readonly EasyNetQ.Management.Client.DeleteExchangeCriteria IfUnused; + public DeleteExchangeCriteria(bool ifUnused) { } + public bool ifUnused { get; init; } + } + public class DeleteQueueCriteria : System.IEquatable + { + public readonly System.Collections.Generic.IEnumerable>? QueryParameters; + public static readonly EasyNetQ.Management.Client.DeleteQueueCriteria IfEmpty; + public static readonly EasyNetQ.Management.Client.DeleteQueueCriteria IfUnused; + public static readonly EasyNetQ.Management.Client.DeleteQueueCriteria IfUnusedAndEmpty; + public DeleteQueueCriteria(bool ifUnused, bool ifEmpty) { } + public bool ifEmpty { get; init; } + public bool ifUnused { get; init; } + } public interface IManagementClient : System.IDisposable { System.Uri Endpoint { get; } System.Threading.Tasks.Task CheckAsync(EasyNetQ.Management.Client.RelativePath path, System.Threading.CancellationToken cancellationToken = default); - System.Threading.Tasks.Task DeleteAsync(EasyNetQ.Management.Client.RelativePath path, System.Threading.CancellationToken cancellationToken = default); + System.Threading.Tasks.Task DeleteAsync(EasyNetQ.Management.Client.RelativePath path, System.Collections.Generic.IEnumerable>? queryParameters, System.Threading.CancellationToken cancellationToken = default); System.Threading.Tasks.Task GetAsync(EasyNetQ.Management.Client.RelativePath path, System.Collections.Generic.IEnumerable>? queryParameters, System.Threading.CancellationToken cancellationToken = default); System.Threading.Tasks.Task PostAsync(EasyNetQ.Management.Client.RelativePath path, System.Threading.CancellationToken cancellationToken = default); System.Threading.Tasks.Task PostAsync(EasyNetQ.Management.Client.RelativePath path, TBody item, System.Threading.CancellationToken cancellationToken = default); @@ -98,14 +115,16 @@ namespace EasyNetQ.Management.Client public static System.Threading.Tasks.Task CreateVhostAsync(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Vhost vhost, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.Task CreateVhostAsync(this EasyNetQ.Management.Client.IManagementClient client, string vhostName, System.Threading.CancellationToken cancellationToken = default) { } public static void Delete(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.RelativePath path, System.Threading.CancellationToken cancellationToken = default) { } + public static void Delete(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.RelativePath path, System.Collections.Generic.IEnumerable>? queryParameters, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.Task DeleteAsync(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.RelativePath path, System.Threading.CancellationToken cancellationToken = default) { } public static void DeleteBinding(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Binding binding, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.Task DeleteBindingAsync(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Binding binding, System.Threading.CancellationToken cancellationToken = default) { } - public static void DeleteExchange(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.ExchangeName exchange, System.Threading.CancellationToken cancellationToken = default) { } - public static void DeleteExchange(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Vhost vhost, string exchangeName, System.Threading.CancellationToken cancellationToken = default) { } - public static void DeleteExchange(this EasyNetQ.Management.Client.IManagementClient client, string vhostName, string exchangeName, System.Threading.CancellationToken cancellationToken = default) { } - public static System.Threading.Tasks.Task DeleteExchangeAsync(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.ExchangeName exchange, System.Threading.CancellationToken cancellationToken = default) { } - public static System.Threading.Tasks.Task DeleteExchangeAsync(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Vhost vhost, string exchangeName, System.Threading.CancellationToken cancellationToken = default) { } - public static System.Threading.Tasks.Task DeleteExchangeAsync(this EasyNetQ.Management.Client.IManagementClient client, string vhostName, string exchangeName, System.Threading.CancellationToken cancellationToken = default) { } + public static void DeleteExchange(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.ExchangeName exchange, EasyNetQ.Management.Client.DeleteExchangeCriteria? deleteExchangeCriteria = null, System.Threading.CancellationToken cancellationToken = default) { } + public static void DeleteExchange(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Vhost vhost, string exchangeName, EasyNetQ.Management.Client.DeleteExchangeCriteria? deleteExchangeCriteria = null, System.Threading.CancellationToken cancellationToken = default) { } + public static void DeleteExchange(this EasyNetQ.Management.Client.IManagementClient client, string vhostName, string exchangeName, EasyNetQ.Management.Client.DeleteExchangeCriteria? deleteExchangeCriteria = null, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.Task DeleteExchangeAsync(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.ExchangeName exchange, EasyNetQ.Management.Client.DeleteExchangeCriteria? deleteExchangeCriteria = null, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.Task DeleteExchangeAsync(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Vhost vhost, string exchangeName, EasyNetQ.Management.Client.DeleteExchangeCriteria? deleteExchangeCriteria = null, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.Task DeleteExchangeAsync(this EasyNetQ.Management.Client.IManagementClient client, string vhostName, string exchangeName, EasyNetQ.Management.Client.DeleteExchangeCriteria? deleteExchangeCriteria = null, System.Threading.CancellationToken cancellationToken = default) { } public static void DeleteExchangeBinding(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.ExchangeName sourceExchange, EasyNetQ.Management.Client.Model.ExchangeName destinationExchange, string propertiesKey, System.Threading.CancellationToken cancellationToken = default) { } public static void DeleteExchangeBinding(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Vhost vhost, string sourceExchangeName, string destinationExchangeName, string propertiesKey, System.Threading.CancellationToken cancellationToken = default) { } public static void DeleteExchangeBinding(this EasyNetQ.Management.Client.IManagementClient client, string vhostName, string sourceExchangeName, string destinationExchangeName, string propertiesKey, System.Threading.CancellationToken cancellationToken = default) { } @@ -132,12 +151,12 @@ namespace EasyNetQ.Management.Client public static void DeletePolicy(this EasyNetQ.Management.Client.IManagementClient client, string vhostName, string policyName, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.Task DeletePolicyAsync(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Vhost vhost, string policyName, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.Task DeletePolicyAsync(this EasyNetQ.Management.Client.IManagementClient client, string vhostName, string policyName, System.Threading.CancellationToken cancellationToken = default) { } - public static void DeleteQueue(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.QueueName queue, System.Threading.CancellationToken cancellationToken = default) { } - public static void DeleteQueue(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Vhost vhost, string queueName, System.Threading.CancellationToken cancellationToken = default) { } - public static void DeleteQueue(this EasyNetQ.Management.Client.IManagementClient client, string vhostName, string queueName, System.Threading.CancellationToken cancellationToken = default) { } - public static System.Threading.Tasks.Task DeleteQueueAsync(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.QueueName queue, System.Threading.CancellationToken cancellationToken = default) { } - public static System.Threading.Tasks.Task DeleteQueueAsync(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Vhost vhost, string queueName, System.Threading.CancellationToken cancellationToken = default) { } - public static System.Threading.Tasks.Task DeleteQueueAsync(this EasyNetQ.Management.Client.IManagementClient client, string vhostName, string queueName, System.Threading.CancellationToken cancellationToken = default) { } + public static void DeleteQueue(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.QueueName queue, EasyNetQ.Management.Client.DeleteQueueCriteria? deleteQueueCriteria = null, System.Threading.CancellationToken cancellationToken = default) { } + public static void DeleteQueue(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Vhost vhost, string queueName, EasyNetQ.Management.Client.DeleteQueueCriteria? deleteQueueCriteria = null, System.Threading.CancellationToken cancellationToken = default) { } + public static void DeleteQueue(this EasyNetQ.Management.Client.IManagementClient client, string vhostName, string queueName, EasyNetQ.Management.Client.DeleteQueueCriteria? deleteQueueCriteria = null, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.Task DeleteQueueAsync(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.QueueName queue, EasyNetQ.Management.Client.DeleteQueueCriteria? deleteQueueCriteria = null, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.Task DeleteQueueAsync(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.Vhost vhost, string queueName, EasyNetQ.Management.Client.DeleteQueueCriteria? deleteQueueCriteria = null, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.Task DeleteQueueAsync(this EasyNetQ.Management.Client.IManagementClient client, string vhostName, string queueName, EasyNetQ.Management.Client.DeleteQueueCriteria? deleteQueueCriteria = null, System.Threading.CancellationToken cancellationToken = default) { } public static void DeleteQueueBinding(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.ExchangeName exchange, EasyNetQ.Management.Client.Model.QueueName queue, string propertiesKey, System.Threading.CancellationToken cancellationToken = default) { } public static void DeleteQueueBinding(this EasyNetQ.Management.Client.IManagementClient client, EasyNetQ.Management.Client.Model.ExchangeName exchange, string queueName, string propertiesKey, System.Threading.CancellationToken cancellationToken = default) { } public static void DeleteQueueBinding(this EasyNetQ.Management.Client.IManagementClient client, string exchangeName, EasyNetQ.Management.Client.Model.QueueName queue, string propertiesKey, System.Threading.CancellationToken cancellationToken = default) { } @@ -380,7 +399,7 @@ namespace EasyNetQ.Management.Client public ManagementClient(string hostUrl, string username, string password, int portNumber = 15672, System.TimeSpan? timeout = default, System.Action? configureHttpRequestMessage = null, bool ssl = false, System.Action? configureHttpHandler = null) { } public System.Uri Endpoint { get; } public System.Threading.Tasks.Task CheckAsync(EasyNetQ.Management.Client.RelativePath path, System.Threading.CancellationToken cancellationToken = default) { } - public System.Threading.Tasks.Task DeleteAsync(EasyNetQ.Management.Client.RelativePath path, System.Threading.CancellationToken cancellationToken = default) { } + public System.Threading.Tasks.Task DeleteAsync(EasyNetQ.Management.Client.RelativePath path, System.Collections.Generic.IEnumerable>? queryParameters, System.Threading.CancellationToken cancellationToken = default) { } public void Dispose() { } public System.Threading.Tasks.Task GetAsync(EasyNetQ.Management.Client.RelativePath path, System.Collections.Generic.IEnumerable>? queryParameters, System.Threading.CancellationToken cancellationToken = default) { } public System.Threading.Tasks.Task PostAsync(EasyNetQ.Management.Client.RelativePath path, System.Threading.CancellationToken cancellationToken = default) { } diff --git a/Source/EasyNetQ.Management.Client.IntegrationTests/ManagementClientTests.cs b/Source/EasyNetQ.Management.Client.IntegrationTests/ManagementClientTests.cs index d65d6b3a..b5aa794e 100644 --- a/Source/EasyNetQ.Management.Client.IntegrationTests/ManagementClientTests.cs +++ b/Source/EasyNetQ.Management.Client.IntegrationTests/ManagementClientTests.cs @@ -1,4 +1,5 @@ using EasyNetQ.Management.Client.Model; +using FluentAssertions.Extensions; using System.Text.Json; namespace EasyNetQ.Management.Client.IntegrationTests; @@ -653,6 +654,60 @@ public async Task Should_be_able_to_delete_a_queue() await fixture.ManagementClient.DeleteQueueAsync(queue); } + [Fact] + public async Task Should_not_be_able_to_delete_a_non_empty_queue() + { + var queue = await CreateTestQueue(TestQueue); + + var publishInfo = new PublishInfo( + TestQueue, + "Hello World", + PayloadEncoding.String, + new Dictionary + { + { "app_id", "management-test" } + } + ); + + await fixture.ManagementClient.PublishAsync("/", "amq.default", publishInfo); + + var expectedMessage = $"*\"reason\":\"queue '{TestQueue}' in vhost '{Vhost.Name}' not empty\"*"; + { + var act = async () => await fixture.ManagementClient.DeleteQueueAsync(queue, DeleteQueueCriteria.IfEmpty); + await act.Should().ThrowAsync() + .Where(e => e.StatusCode == System.Net.HttpStatusCode.BadRequest) + .WithMessage(expectedMessage); + } + { + var act = async () => await fixture.ManagementClient.DeleteQueueAsync(queue, DeleteQueueCriteria.IfUnusedAndEmpty); + await act.Should().ThrowAsync() + .Where(e => e.StatusCode == System.Net.HttpStatusCode.BadRequest) + .WithMessage(expectedMessage); + } + } + + [Fact(Skip = "Requires at least a consumer")] + public async Task Should_not_be_able_to_delete_a_non_unused_queue() + { + var queue = await CreateTestQueue(TestQueue); + + // Create consumer + + var expectedMessage = $"*\"reason\":\"queue '{TestQueue}' in vhost '{Vhost.Name}' not empty\"*"; + { + var act = async () => await fixture.ManagementClient.DeleteQueueAsync(queue, DeleteQueueCriteria.IfUnused); + await act.Should().ThrowAsync() + .Where(e => e.StatusCode == System.Net.HttpStatusCode.BadRequest) + .WithMessage(expectedMessage); + } + { + var act = async () => await fixture.ManagementClient.DeleteQueueAsync(queue, DeleteQueueCriteria.IfUnusedAndEmpty); + await act.Should().ThrowAsync() + .Where(e => e.StatusCode == System.Net.HttpStatusCode.BadRequest) + .WithMessage(expectedMessage); + } + } + [Fact] public async Task Should_be_able_to_delete_a_user() { @@ -676,6 +731,25 @@ public async Task Should_be_able_to_delete_an_exchange_with_pluses() await fixture.ManagementClient.DeleteExchangeAsync(exchange); } + [Fact] + public async Task Should_not_be_able_to_delete_a_non_unused_exchange() + { + var queue = await CreateTestQueue(TestQueue); + var exchange = await CreateExchange(TestExchange); + + var bindingInfo = new BindingInfo(RoutingKey: TestQueue); + + await fixture.ManagementClient.CreateQueueBindingAsync(exchange, queue, bindingInfo); + + var expectedMessage = $"*\"reason\":\"exchange '{TestExchange}' in vhost '{Vhost.Name}' in use\"*"; + { + var act = async () => await fixture.ManagementClient.DeleteExchangeAsync(exchange, DeleteExchangeCriteria.IfUnused); + await act.Should().ThrowAsync() + .Where(e => e.StatusCode == System.Net.HttpStatusCode.BadRequest) + .WithMessage(expectedMessage); + } + } + [Fact] public async Task Should_be_able_to_delete_permissions() { @@ -1202,16 +1276,21 @@ public async Task Should_get_permissions() public async Task Should_get_queues() { await CreateTestQueue(TestQueue); - while (true) - { - var queues = await fixture.ManagementClient.GetQueuesAsync(); - queues.Should().NotBeNullOrEmpty(); - if (queues[0].State != null) + var act = async () => { - queues[0].ExtensionData.Should().NotBeNullOrEmpty(); - break; - } - } + var queues = await fixture.ManagementClient.GetQueuesAsync(); + queues.Should().NotBeNullOrEmpty() + .And.AllSatisfy(q => + { + q.State.Should().Be("running"); + // Should be not null only because some keys in response aren't mapped to Queue's properties. + // E.g. message_bytes_ready or operator_policy + q.ExtensionData.Should().NotBeNull(); + }) + .And.ContainEquivalentOf(new QueueName(TestQueue, Vhost.Name)); + }; + + await act.Should().NotThrowAfterAsync(10.Seconds(), TimeSpan.Zero); } [Fact] @@ -1304,14 +1383,10 @@ public async Task Should_purge_a_queue() [Fact] public async Task Should_throw_when_trying_to_close_unknown_connection() { - try - { - await fixture.ManagementClient.CloseConnectionAsync("unknown"); - } - catch (Exception e) - { - Assert.IsType(e); - } + var act = async () => await fixture.ManagementClient.CloseConnectionAsync("unknown"); + + await act.Should().ThrowAsync() + .Where(e => e.StatusCode == System.Net.HttpStatusCode.NotFound); } [Fact] @@ -1368,7 +1443,8 @@ await fixture.ManagementClient.DeleteParameterAsync( shovelName ); - await act.Should().ThrowAsync().Where(e => e.StatusCode == System.Net.HttpStatusCode.NotFound); + await act.Should().ThrowAsync() + .Where(e => e.StatusCode == System.Net.HttpStatusCode.NotFound); } [Fact] @@ -1416,8 +1492,10 @@ await fixture.ManagementClient.CreateShovelAsync( [Fact] public async Task Should_be_able_to_throw_on_non_existant_shovel() { - await Assert.ThrowsAsync(async () - => await fixture.ManagementClient.GetShovelAsync(Vhost.Name, "non-existant-shovel")); + var act = async () => await fixture.ManagementClient.GetShovelAsync(Vhost.Name, "non-existant-shovel"); + + await act.Should().ThrowAsync() + .Where(e => e.StatusCode == System.Net.HttpStatusCode.NotFound); } [Fact] diff --git a/Source/EasyNetQ.Management.Client.IntegrationTests/RabbitMQFixture.cs b/Source/EasyNetQ.Management.Client.IntegrationTests/RabbitMQFixture.cs index e9fa79f2..0d96becc 100644 --- a/Source/EasyNetQ.Management.Client.IntegrationTests/RabbitMQFixture.cs +++ b/Source/EasyNetQ.Management.Client.IntegrationTests/RabbitMQFixture.cs @@ -19,7 +19,7 @@ public sealed class RabbitMqFixture : IAsyncLifetime, IDisposable public RabbitMqFixture() { dockerProxy = new DockerProxy(); - tag = $"{Environment.GetEnvironmentVariable("RABBITMQ_VERSION") ?? "3.12"}-management"; + tag = $"{Environment.GetEnvironmentVariable("RABBITMQ_VERSION") ?? "3.13"}-management"; } public Uri Endpoint { get; private set; } = new("http://localhost:15672"); diff --git a/Source/EasyNetQ.Management.Client/DeleteExchangeCriteria.cs b/Source/EasyNetQ.Management.Client/DeleteExchangeCriteria.cs new file mode 100644 index 00000000..84cde3cc --- /dev/null +++ b/Source/EasyNetQ.Management.Client/DeleteExchangeCriteria.cs @@ -0,0 +1,15 @@ +namespace EasyNetQ.Management.Client; + +public record DeleteExchangeCriteria(bool ifUnused) +{ + public IEnumerable>? QueryParameters = + ifUnused switch + { + false => null, + true => [ + new KeyValuePair("if-unused", "true") + ] + }; + + public static readonly DeleteExchangeCriteria IfUnused = new DeleteExchangeCriteria(ifUnused: true); +} diff --git a/Source/EasyNetQ.Management.Client/DeleteQueueCriteria.cs b/Source/EasyNetQ.Management.Client/DeleteQueueCriteria.cs new file mode 100644 index 00000000..46eb19dd --- /dev/null +++ b/Source/EasyNetQ.Management.Client/DeleteQueueCriteria.cs @@ -0,0 +1,24 @@ +namespace EasyNetQ.Management.Client; + +public record DeleteQueueCriteria(bool ifUnused, bool ifEmpty) +{ + public readonly IEnumerable>? QueryParameters = + (ifUnused, ifEmpty) switch + { + (false, false) => null, + (false, true) => [ + new KeyValuePair("if-empty", "true") + ], + (true, false) => [ + new KeyValuePair("if-unused", "true") + ], + (true, true) => [ + new KeyValuePair("if-unused", "true"), + new KeyValuePair("if-empty", "true") + ] + }; + + public static readonly DeleteQueueCriteria IfUnused = new DeleteQueueCriteria(ifUnused: true, ifEmpty: false); + public static readonly DeleteQueueCriteria IfEmpty = new DeleteQueueCriteria(ifUnused: false, ifEmpty: true); + public static readonly DeleteQueueCriteria IfUnusedAndEmpty = new DeleteQueueCriteria(ifUnused: true, ifEmpty: true); +} diff --git a/Source/EasyNetQ.Management.Client/IManagementClient.cs b/Source/EasyNetQ.Management.Client/IManagementClient.cs index 00b07667..9af07965 100755 --- a/Source/EasyNetQ.Management.Client/IManagementClient.cs +++ b/Source/EasyNetQ.Management.Client/IManagementClient.cs @@ -28,6 +28,7 @@ Task PutAsync( Task DeleteAsync( RelativePath path, + IEnumerable>? queryParameters, CancellationToken cancellationToken = default); Task PostAsync( @@ -89,7 +90,16 @@ public static Task GetAsync( CancellationToken cancellationToken = default ) { - return client.GetAsync(path, null, cancellationToken); + return client.GetAsync(path, queryParameters: null, cancellationToken); + } + + public static Task DeleteAsync( + this IManagementClient client, + RelativePath path, + CancellationToken cancellationToken = default + ) + { + return client.DeleteAsync(path, queryParameters: null, cancellationToken); } /// @@ -432,13 +442,15 @@ public static Task CreateExchangeAsync( /// /// /// + /// /// public static Task DeleteExchangeAsync( this IManagementClient client, string vhostName, string exchangeName, + DeleteExchangeCriteria? deleteExchangeCriteria = null, CancellationToken cancellationToken = default - ) => client.DeleteAsync(Exchanges / vhostName / exchangeName, cancellationToken); + ) => client.DeleteAsync(Exchanges / vhostName / exchangeName, deleteExchangeCriteria?.QueryParameters, cancellationToken); /// /// A list of all bindings in which a given exchange is the source. @@ -512,13 +524,15 @@ public static Task CreateQueueAsync( /// /// /// + /// /// public static Task DeleteQueueAsync( this IManagementClient client, string vhostName, string queueName, + DeleteQueueCriteria? deleteQueueCriteria = null, CancellationToken cancellationToken = default - ) => client.DeleteAsync(Queues / vhostName / queueName, cancellationToken); + ) => client.DeleteAsync(Queues / vhostName / queueName, deleteQueueCriteria?.QueryParameters, cancellationToken); /// /// A list of all bindings on a given queue. diff --git a/Source/EasyNetQ.Management.Client/LengthsCriteria.cs b/Source/EasyNetQ.Management.Client/LengthsCriteria.cs index 2f6e133a..344b4dd6 100644 --- a/Source/EasyNetQ.Management.Client/LengthsCriteria.cs +++ b/Source/EasyNetQ.Management.Client/LengthsCriteria.cs @@ -3,9 +3,8 @@ public record LengthsCriteria(int LengthsAge, int LengthsIncr) { public readonly IEnumerable> QueryParameters = - new KeyValuePair[] - { + [ new KeyValuePair("lengths_age", LengthsAge.ToString()), new KeyValuePair("lengths_incr", LengthsIncr.ToString()) - }; + ]; } diff --git a/Source/EasyNetQ.Management.Client/ManagementClient.cs b/Source/EasyNetQ.Management.Client/ManagementClient.cs index 10be193e..14b5d320 100644 --- a/Source/EasyNetQ.Management.Client/ManagementClient.cs +++ b/Source/EasyNetQ.Management.Client/ManagementClient.cs @@ -7,7 +7,7 @@ using EasyNetQ.Management.Client.Internals; using EasyNetQ.Management.Client.Serialization; -#if NET6_0 +#if NET5_0_OR_GREATER using HttpHandler = System.Net.Http.SocketsHttpHandler; #else using System.Collections.Concurrent; @@ -20,7 +20,11 @@ namespace EasyNetQ.Management.Client; public class ManagementClient : IManagementClient { +#if NET5_0_OR_GREATER + private static readonly MediaTypeWithQualityHeaderValue JsonMediaTypeHeaderValue = new(System.Net.Mime.MediaTypeNames.Application.Json); +#else private static readonly MediaTypeWithQualityHeaderValue JsonMediaTypeHeaderValue = new("application/json"); +#endif private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(20); internal static readonly JsonSerializerOptions SerializerOptions; @@ -254,9 +258,12 @@ public async Task PostAsync( await response.EnsureExpectedStatusCodeAsync(statusCode => statusCode is HttpStatusCode.OK or HttpStatusCode.Created or HttpStatusCode.NoContent, cancellationToken).ConfigureAwait(false); } - public async Task DeleteAsync(RelativePath path, CancellationToken cancellationToken = default) + public async Task DeleteAsync( + RelativePath path, + IEnumerable>? queryParameters, + CancellationToken cancellationToken = default) { - using var request = CreateRequest(HttpMethod.Delete, path); + using var request = CreateRequest(HttpMethod.Delete, path, queryParameters); using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); await response.EnsureExpectedStatusCodeAsync(statusCode => statusCode == HttpStatusCode.NoContent, cancellationToken).ConfigureAwait(false); diff --git a/Source/EasyNetQ.Management.Client/PageCriteria.cs b/Source/EasyNetQ.Management.Client/PageCriteria.cs index 7fa78595..0f42562c 100644 --- a/Source/EasyNetQ.Management.Client/PageCriteria.cs +++ b/Source/EasyNetQ.Management.Client/PageCriteria.cs @@ -3,12 +3,11 @@ namespace EasyNetQ.Management.Client; public record PageCriteria(int Page, int PageSize, string? Name = null, bool UseRegex = false) { public readonly IEnumerable> QueryParameters = - new KeyValuePair[] - { + [ new KeyValuePair("page", Page.ToString()), new KeyValuePair("page_size", PageSize.ToString()), new KeyValuePair("name", Name ?? ""), new KeyValuePair("use_regex", UseRegex.ToString().ToLower()), new KeyValuePair("pagination", "true") - }; + ]; } diff --git a/Source/EasyNetQ.Management.Client/RatesCriteria.cs b/Source/EasyNetQ.Management.Client/RatesCriteria.cs index cca53d1e..ef0a30e8 100644 --- a/Source/EasyNetQ.Management.Client/RatesCriteria.cs +++ b/Source/EasyNetQ.Management.Client/RatesCriteria.cs @@ -3,9 +3,8 @@ public record RatesCriteria(int MsgRatesAge, int MsgRatesIncr) { public readonly IEnumerable> QueryParameters = - new KeyValuePair[] - { + [ new KeyValuePair("msg_rates_age", MsgRatesAge.ToString()), new KeyValuePair("msg_rates_incr", MsgRatesIncr.ToString()) - }; + ]; } diff --git a/Source/EasyNetQ.Management.Client/Serialization/JsonExtensionDataExtensions.cs b/Source/EasyNetQ.Management.Client/Serialization/JsonExtensionDataExtensions.cs index b91c82b2..33f7f8eb 100644 --- a/Source/EasyNetQ.Management.Client/Serialization/JsonExtensionDataExtensions.cs +++ b/Source/EasyNetQ.Management.Client/Serialization/JsonExtensionDataExtensions.cs @@ -21,12 +21,7 @@ internal static class JsonExtensionDataExtensions var jsonExtensionData = new Dictionary(extensionData.Count); foreach (var property in extensionData) { -#if NET6_0_OR_GREATER jsonExtensionData.Add(property.Key, JsonSerializer.SerializeToElement(property.Value)); -#else - var bytes = JsonSerializer.SerializeToUtf8Bytes(property.Value); - jsonExtensionData.Add(property.Key, JsonDocument.Parse(bytes).RootElement.Clone()); -#endif } return jsonExtensionData; } diff --git a/Source/EasyNetQ.Management.Client/StatsCriteria.cs b/Source/EasyNetQ.Management.Client/StatsCriteria.cs index 41e60a4b..25abb3d9 100644 --- a/Source/EasyNetQ.Management.Client/StatsCriteria.cs +++ b/Source/EasyNetQ.Management.Client/StatsCriteria.cs @@ -3,15 +3,15 @@ public record StatsCriteria(bool DisableStats, bool EnableQueueTotals) { public readonly IEnumerable>? QueryParameters = - ((DisableStats, EnableQueueTotals)) switch + (DisableStats, EnableQueueTotals) switch { - (true, false) => new KeyValuePair[] { + (true, false) => [ new KeyValuePair("disable_stats", "true") - }, - (true, true) => new KeyValuePair[] { + ], + (true, true) => [ new KeyValuePair("disable_stats", "true"), new KeyValuePair("enable_queue_totals", "true") - }, + ], (false, false) => null, (false, true) => throw new NotSupportedException() };