Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions src/AcceptanceTests/When_using_auto_delete_on_idle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
namespace NServiceBus.Transport.AzureServiceBus.AcceptanceTests
{
using System;
using System.Threading.Tasks;
using AcceptanceTesting;
using Azure.Messaging.ServiceBus;
using Azure.Messaging.ServiceBus.Administration;
using NServiceBus.AcceptanceTests;
using NServiceBus.AcceptanceTests.EndpointTemplates;
using NUnit.Framework;

public class When_using_auto_delete_on_idle : NServiceBusAcceptanceTest
{
const string HasAutoDeleteOnIdleEndpointInstanceName = "usingautodeleteonidle.endpointwithautodeleteonidle-12345";
const string NoAutoDeleteOnIdleEndpointInstanceName = "usingautodeleteonidle.endpointwithoutautodeleteonidle";
const string HasAutoDeleteOnIdleButNoInstancesEndpointName = "usingautodeleteonidle.endpointwithautodeleteonidlebutnoinstances";

[SetUp]
public async Task Setup()
{
var adminClient =
new ServiceBusAdministrationClient(
Environment.GetEnvironmentVariable("AzureServiceBus_ConnectionString"));
try
{
// makes sure during local development the topic gets cleared before each test run
await adminClient.DeleteQueueAsync(HasAutoDeleteOnIdleEndpointInstanceName);
await adminClient.DeleteQueueAsync(NoAutoDeleteOnIdleEndpointInstanceName);
await adminClient.DeleteQueueAsync(HasAutoDeleteOnIdleButNoInstancesEndpointName);
}
catch (ServiceBusException ex) when (ex.Reason == ServiceBusFailureReason.MessagingEntityNotFound)
{
}
}

[Test]
public async Task Should_configure_queue_with_auto_delete_on_idle()
{
var instanceId = "12345";
var context = await Scenario.Define<Context>()
.WithEndpoint<EndpointWithAutoDeleteOnIdle>(b =>
{
b.CustomConfig(c =>
{
var transport = c.ConfigureTransport<AzureServiceBusTransport>();
transport.AutoDeleteOnIdle = TimeSpan.FromMinutes(10);
c.MakeInstanceUniquelyAddressable(instanceId);
});
})
.Done(c => c.EndpointsStarted)
.Run();

// Verify that the queue was created with the correct AutoDeleteOnIdle setting
var adminClient = new ServiceBusAdministrationClient(
Environment.GetEnvironmentVariable("AzureServiceBus_ConnectionString"));

var queueProperties = await adminClient.GetQueueAsync(HasAutoDeleteOnIdleEndpointInstanceName);

Assert.That(queueProperties.Value.AutoDeleteOnIdle, Is.EqualTo(TimeSpan.FromMinutes(10)));
}

[Test]
public async Task Should_not_configure_queue_with_auto_delete_on_idle()
{
var context = await Scenario.Define<Context>()
.WithEndpoint<EndpointWithoutAutoDeleteOnIdle>(b =>
{
b.CustomConfig(c =>
{
c.ConfigureTransport<AzureServiceBusTransport>();
});
})
.Done(c => c.EndpointsStarted)
.Run();

// Verify that the queue was created with the correct AutoDeleteOnIdle setting
var adminClient = new ServiceBusAdministrationClient(
Environment.GetEnvironmentVariable("AzureServiceBus_ConnectionString"));

var queueProperties = await adminClient.GetQueueAsync(NoAutoDeleteOnIdleEndpointInstanceName);

Assert.That(queueProperties.Value.AutoDeleteOnIdle, Is.EqualTo(TimeSpan.MaxValue));
}

[Test]
public async Task Should_not_configure_queue_with_auto_delete_on_idle_if_no_unique_instances()
{
var context = await Scenario.Define<Context>()
.WithEndpoint<EndpointWithAutoDeleteOnIdleButNoInstances>(b =>
{
b.CustomConfig(c =>
{
var transport = c.ConfigureTransport<AzureServiceBusTransport>();
transport.AutoDeleteOnIdle = TimeSpan.FromMinutes(10);
});
})
.Done(c => c.EndpointsStarted)
.Run();

// Verify that the queue was created with the correct AutoDeleteOnIdle setting
var adminClient = new ServiceBusAdministrationClient(
Environment.GetEnvironmentVariable("AzureServiceBus_ConnectionString"));

var queueProperties = await adminClient.GetQueueAsync(HasAutoDeleteOnIdleButNoInstancesEndpointName);

Assert.That(queueProperties.Value.AutoDeleteOnIdle, Is.EqualTo(TimeSpan.MaxValue));
}


public class Context : ScenarioContext
{
}

public class EndpointWithAutoDeleteOnIdle : EndpointConfigurationBuilder
{
public EndpointWithAutoDeleteOnIdle()
{
EndpointSetup<DefaultServer>();
}
}

public class EndpointWithoutAutoDeleteOnIdle : EndpointConfigurationBuilder
{
public EndpointWithoutAutoDeleteOnIdle()
{
EndpointSetup<DefaultServer>();
}
}

public class EndpointWithAutoDeleteOnIdleButNoInstances : EndpointConfigurationBuilder
{
public EndpointWithAutoDeleteOnIdleButNoInstances()
{
EndpointSetup<DefaultServer>();
}
}
}
}
103 changes: 103 additions & 0 deletions src/Tests/Administration/QueueCreatorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
namespace NServiceBus.Transport.AzureServiceBus.Tests.Administration;

using System;
using System.Threading.Tasks;
using NUnit.Framework;
using Particular.Approvals;

[TestFixture]
public class QueueCreatorTests
{
[Test]
public async Task Should_set_AutoDeleteOnIdle_when_configured()
{
var transport = new AzureServiceBusTransport("connectionString", TopicTopology.Default)
{
AutoDeleteOnIdle = TimeSpan.FromMinutes(10)
};

var recordingClient = new RecordingServiceBusAdministrationClient();
var creator = new QueueCreator(transport);

await creator.Create(recordingClient, ["test-queue"], "test-queue");

var output = recordingClient.ToString();

Approver.Verify(output);
}

[Test]
public async Task Should_not_set_AutoDeleteOnIdle_when_null()
{
var transport = new AzureServiceBusTransport("connectionString", TopicTopology.Default)
{
AutoDeleteOnIdle = null
};

var recordingClient = new RecordingServiceBusAdministrationClient();
var creator = new QueueCreator(transport);

await creator.Create(recordingClient, ["test-queue"], "test-queue");

var output = recordingClient.ToString(); // AutoDeleteOnIdle should be default - TimeSpan.MaxValue

Approver.Verify(output);
}

[Test]
public async Task Should_only_set_AutoDeleteOnIdle_on_instance_specific_queue()
{
var transport = new AzureServiceBusTransport("connectionString", TopicTopology.Default)
{
AutoDeleteOnIdle = TimeSpan.FromMinutes(10)
};

var recordingClient = new RecordingServiceBusAdministrationClient();
var creator = new QueueCreator(transport);

await creator.Create(recordingClient, ["instance-queue", "error"], "instance-queue");

// AutoDeleteOnIdle should be default for shared queues - TimeSpan.MaxValue
var output = recordingClient.ToString();

Approver.Verify(output);
}

[Test]
public async Task Should_not_set_AutoDeleteOnIdle_when_instance_name_is_null()
{
var transport = new AzureServiceBusTransport("connectionString", TopicTopology.Default)
{
AutoDeleteOnIdle = TimeSpan.FromMinutes(10)
};

var recordingClient = new RecordingServiceBusAdministrationClient();
var creator = new QueueCreator(transport);

// Create queue without specifying an instance name
await creator.Create(recordingClient, ["some-queue"], null);

var output = recordingClient.ToString();

Approver.Verify(output);
}

[Test]
public async Task Should_not_set_AutoDeleteOnIdle_when_queue_name_does_not_match_instance_name()
{
var transport = new AzureServiceBusTransport("connectionString", TopicTopology.Default)
{
AutoDeleteOnIdle = TimeSpan.FromMinutes(10)
};

var recordingClient = new RecordingServiceBusAdministrationClient();
var creator = new QueueCreator(transport);

// Create queue with different instance name
await creator.Create(recordingClient, ["some-queue"], "different-instance");

var output = recordingClient.ToString();

Approver.Verify(output);
}
}
1 change: 1 addition & 0 deletions src/Tests/ApprovalFiles/APIApprovals.Approve.approved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace NServiceBus
"ersion 6.0.0.", true)]
public AzureServiceBusTransport(string fullyQualifiedNamespace, Azure.Core.TokenCredential tokenCredential) { }
public AzureServiceBusTransport(string fullyQualifiedNamespace, Azure.Core.TokenCredential tokenCredential, NServiceBus.TopicTopology topology) { }
public System.TimeSpan? AutoDeleteOnIdle { get; set; }
public bool EnablePartitioning { get; set; }
public int EntityMaximumSize { get; set; }
public System.TimeSpan? MaxAutoLockRenewalDuration { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
CreateQueueOptions: {
"Name": "some-queue",
"LockDuration": "00:05:00",
"MaxSizeInMegabytes": 5120,
"RequiresDuplicateDetection": false,
"RequiresSession": false,
"DefaultMessageTimeToLive": "10675199.02:48:05.4775807",
"AutoDeleteOnIdle": "10675199.02:48:05.4775807",
"DeadLetteringOnMessageExpiration": false,
"DuplicateDetectionHistoryTimeWindow": "00:01:00",
"MaxDeliveryCount": 2147483647,
"EnableBatchedOperations": true,
"AuthorizationRules": [],
"Status": {},
"ForwardTo": null,
"ForwardDeadLetteredMessagesTo": null,
"EnablePartitioning": false,
"UserMetadata": null,
"MaxMessageSizeInKilobytes": null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
CreateQueueOptions: {
"Name": "test-queue",
"LockDuration": "00:05:00",
"MaxSizeInMegabytes": 5120,
"RequiresDuplicateDetection": false,
"RequiresSession": false,
"DefaultMessageTimeToLive": "10675199.02:48:05.4775807",
"AutoDeleteOnIdle": "10675199.02:48:05.4775807",
"DeadLetteringOnMessageExpiration": false,
"DuplicateDetectionHistoryTimeWindow": "00:01:00",
"MaxDeliveryCount": 2147483647,
"EnableBatchedOperations": true,
"AuthorizationRules": [],
"Status": {},
"ForwardTo": null,
"ForwardDeadLetteredMessagesTo": null,
"EnablePartitioning": false,
"UserMetadata": null,
"MaxMessageSizeInKilobytes": null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
CreateQueueOptions: {
"Name": "some-queue",
"LockDuration": "00:05:00",
"MaxSizeInMegabytes": 5120,
"RequiresDuplicateDetection": false,
"RequiresSession": false,
"DefaultMessageTimeToLive": "10675199.02:48:05.4775807",
"AutoDeleteOnIdle": "10675199.02:48:05.4775807",
"DeadLetteringOnMessageExpiration": false,
"DuplicateDetectionHistoryTimeWindow": "00:01:00",
"MaxDeliveryCount": 2147483647,
"EnableBatchedOperations": true,
"AuthorizationRules": [],
"Status": {},
"ForwardTo": null,
"ForwardDeadLetteredMessagesTo": null,
"EnablePartitioning": false,
"UserMetadata": null,
"MaxMessageSizeInKilobytes": null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
CreateQueueOptions: {
"Name": "instance-queue",
"LockDuration": "00:05:00",
"MaxSizeInMegabytes": 5120,
"RequiresDuplicateDetection": false,
"RequiresSession": false,
"DefaultMessageTimeToLive": "10675199.02:48:05.4775807",
"AutoDeleteOnIdle": "00:10:00",
"DeadLetteringOnMessageExpiration": false,
"DuplicateDetectionHistoryTimeWindow": "00:01:00",
"MaxDeliveryCount": 2147483647,
"EnableBatchedOperations": true,
"AuthorizationRules": [],
"Status": {},
"ForwardTo": null,
"ForwardDeadLetteredMessagesTo": null,
"EnablePartitioning": false,
"UserMetadata": null,
"MaxMessageSizeInKilobytes": null
}
CreateQueueOptions: {
"Name": "error",
"LockDuration": "00:05:00",
"MaxSizeInMegabytes": 5120,
"RequiresDuplicateDetection": false,
"RequiresSession": false,
"DefaultMessageTimeToLive": "10675199.02:48:05.4775807",
"AutoDeleteOnIdle": "10675199.02:48:05.4775807",
"DeadLetteringOnMessageExpiration": false,
"DuplicateDetectionHistoryTimeWindow": "00:01:00",
"MaxDeliveryCount": 2147483647,
"EnableBatchedOperations": true,
"AuthorizationRules": [],
"Status": {},
"ForwardTo": null,
"ForwardDeadLetteredMessagesTo": null,
"EnablePartitioning": false,
"UserMetadata": null,
"MaxMessageSizeInKilobytes": null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
CreateQueueOptions: {
"Name": "test-queue",
"LockDuration": "00:05:00",
"MaxSizeInMegabytes": 5120,
"RequiresDuplicateDetection": false,
"RequiresSession": false,
"DefaultMessageTimeToLive": "10675199.02:48:05.4775807",
"AutoDeleteOnIdle": "00:10:00",
"DeadLetteringOnMessageExpiration": false,
"DuplicateDetectionHistoryTimeWindow": "00:01:00",
"MaxDeliveryCount": 2147483647,
"EnableBatchedOperations": true,
"AuthorizationRules": [],
"Status": {},
"ForwardTo": null,
"ForwardDeadLetteredMessagesTo": null,
"EnablePartitioning": false,
"UserMetadata": null,
"MaxMessageSizeInKilobytes": null
}
Loading
Loading