using Microsoft.Extensions.Options; using RabbitMQ.Client; using RabbitMQ.Client.Exceptions; public static class RabbitMqTestHelper { public static void PurgeNotificationQueues(IOptions opts) { var o = opts.Value; var factory = new ConnectionFactory { HostName = o.Host, Port = o.Port, UserName = o.Username, Password = o.Password, }; using var connection = factory.CreateConnection("test-queue-purge"); using var channel = connection.CreateModel(); // x-message-ttl is immutable once the queue exists. A concurrently running dev API // (300000 ms) can recreate the DLQ after the test host provisions 5000 ms, leaving // escalation stuck until the 5-minute TTL expires — far beyond the test poll window. RecreatePagingDlq(channel, o.PagingAckTimeoutMs); foreach (var queue in new[] { "alerts.paging.queue", "alerts.escalation.queue" }) { try { channel.QueuePurge(queue); } catch (OperationInterruptedException) { // Queue may not exist yet on a cold broker. } } } private static void RecreatePagingDlq(IModel channel, int pagingAckTimeoutMs) { const string dlq = "alerts.paging.dlq"; try { channel.QueueDelete(dlq, ifUnused: false, ifEmpty: false); } catch (OperationInterruptedException) { // Queue may not exist yet on a cold broker. } channel.ExchangeDeclare( RabbitMqTopologyProvisioner.Exchange, ExchangeType.Direct, durable: true); channel.QueueDeclare( queue: dlq, durable: true, exclusive: false, autoDelete: false, arguments: new Dictionary { ["x-message-ttl"] = pagingAckTimeoutMs, ["x-dead-letter-exchange"] = RabbitMqTopologyProvisioner.Exchange, ["x-dead-letter-routing-key"] = RabbitMqTopologyProvisioner.EscalKey, }); } }