Skip to content
Draft
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
7 changes: 5 additions & 2 deletions src/TestHelper/TestHelper.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.6.0" />
<PackageReference Include="NUnit" Version="4.6.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.13.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<!-- Workaround to prevent VS test discovery error -->
Expand Down
5 changes: 2 additions & 3 deletions src/TimeoutMigrationTool.ASQ.FakeTarget/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,10 @@ static void SetupEndpointConfig(EndpointConfiguration endpointConfig)
endpointConfig.SendFailedMessagesTo("error");
endpointConfig.AuditProcessedMessagesTo("audit");
var transport = endpointConfig.UseTransport<AzureStorageQueueTransport>();
transport.DisablePublishing();
transport.Routing().DisablePublishing();
transport.ConnectionString("UseDevelopmentStorage=true;");
endpointConfig.EnableInstallers();
endpointConfig.UseSerialization<NewtonsoftJsonSerializer>();
endpointConfig.DisableFeature<TimeoutManager>();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NServiceBus" Version="7.8.6" />
<PackageReference Include="NServiceBus.Newtonsoft.Json" Version="2.4.0" />
<PackageReference Include="NServiceBus.Transport.AzureStorageQueues" Version="10.0.6" />
<PackageReference Include="NServiceBus" Version="10.1.4" />
<PackageReference Include="NServiceBus.Newtonsoft.Json" Version="5.0.1" />
<PackageReference Include="NServiceBus.Transport.AzureStorageQueues" Version="14.0.1" />
</ItemGroup>

<ItemGroup Label="Direct references to transitive dependencies to avoid versions with CVE">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
48 changes: 32 additions & 16 deletions src/TimeoutMigrationTool.Asp.AcceptanceTests/AspAcceptanceTest.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
namespace TimeoutMigrationTool.Asp.AcceptanceTests
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Azure.Storage.Blobs;
using Microsoft.Azure.Cosmos.Table;
using NServiceBus;
using Newtonsoft.Json;
using NUnit.Framework;
using Particular.TimeoutMigrationTool.Asp;
using static Microsoft.Azure.Cosmos.Table.TableQuery;
Expand Down Expand Up @@ -72,26 +74,40 @@ public async Task TearDown()
await blobServiceClient.DeleteBlobContainerAsync(timeoutContainerName);
}

protected void SetupPersistence(EndpointConfiguration endpointConfiguration)
{
var persistence = endpointConfiguration.UsePersistence<AzureStoragePersistence>();
persistence.ConnectionString(connectionString);

var timeoutPersistence = endpointConfiguration.UsePersistence<AzureStoragePersistence, StorageType.Timeouts>();
#pragma warning disable 618
timeoutPersistence.CreateSchema(true);
timeoutPersistence.TimeoutDataTableName(timeoutTableName);
timeoutPersistence.TimeoutStateContainerName(timeoutContainerName);
timeoutPersistence.PartitionKeyScope(PartitionKeyScope);
#pragma warning restore 618
}

protected AspTimeoutsSource CreateTimeoutStorage(string endpointNameToBeListed, int batchSize = 1024)
{
var storage = new AspTimeoutsSource(connectionString, batchSize, timeoutContainerName, endpointNameToBeListed, TimeoutTableName, tablePrefix: tableNamePrefix, partitionKeyScope: PartitionKeyScope);
return storage;
}

protected async Task StoreLegacyTimeout(string sourceEndpoint, string targetEndpoint, Type messageType)
{
var timeoutId = Guid.NewGuid().ToString("N");
var timeoutTime = DateTime.UtcNow.AddSeconds(5);
var stateAddress = $"{timeoutId}.state";
var body = Encoding.UTF8.GetBytes("{}");

var blobContainerClient = blobServiceClient.GetBlobContainerClient(timeoutContainerName);
await blobContainerClient.UploadBlobAsync(stateAddress, new BinaryData(body));

var timeout = new TimeoutDataEntity(timeoutTime.ToString(PartitionKeyScope), timeoutId)
{
Destination = targetEndpoint,
SagaId = Guid.NewGuid(),
StateAddress = stateAddress,
Time = timeoutTime,
OwningTimeoutManager = sourceEndpoint,
Headers = JsonConvert.SerializeObject(new Dictionary<string, string>
{
{ "NServiceBus.ContentType", "application/json" },
{ "NServiceBus.EnclosedMessageTypes", messageType.AssemblyQualifiedName },
{ "NServiceBus.MessageId", timeoutId }
})
};

await timeoutTable.ExecuteAsync(TableOperation.Insert(timeout));
}

protected async Task WaitUntilTheTimeoutsAreSavedInAsp(string endpoint, int numberOfEntriesThatShouldBeThere)
{
var query = new TableQuery<DynamicTableEntity>()
Expand Down Expand Up @@ -152,4 +168,4 @@ public static string StorageRootDir
}
}
}
}
}
39 changes: 6 additions & 33 deletions src/TimeoutMigrationTool.Asp.AcceptanceTests/AspToAsqMqEndToEnd.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace TimeoutMigrationTool.Asp.AcceptanceTests
namespace TimeoutMigrationTool.Asp.AcceptanceTests
{
using NServiceBus.Features;
using NServiceBus;
Expand All @@ -23,30 +23,7 @@ public async Task Can_migrate_timeouts()
var sourceEndpoint = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(AspSource));
var targetEndpoint = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(AsqTarget));

await Scenario.Define<SourceContext>()
.WithEndpoint<AspSource>(b => b.CustomConfig(ec =>
{
SetupPersistence(ec);

ec.UseSerialization<NewtonsoftJsonSerializer>();
})
.When(async (session, c) =>
{
var delayedMessage = new DelayedMessage();

var options = new SendOptions();

options.DelayDeliveryWith(TimeSpan.FromSeconds(15));
options.SetDestination(targetEndpoint);

await session.Send(delayedMessage, options);

await WaitUntilTheTimeoutsAreSavedInAsp(sourceEndpoint, 2);

c.TimeoutSet = true;
}))
.Done(c => c.TimeoutSet)
.Run(TimeSpan.FromSeconds(30));
await StoreLegacyTimeout(sourceEndpoint, targetEndpoint, typeof(DelayedMessage));

var context = await Scenario.Define<TargetContext>()
// Create the legacy endpoint to forward the delayed message to the reporting endpoint
Expand All @@ -56,9 +33,7 @@ await Scenario.Define<SourceContext>()
{
var transportConfig = ec.UseTransport<AzureStorageQueueTransport>();
transportConfig.ConnectionString(asqConnectionString);
transportConfig.DisablePublishing();

transportConfig.DelayedDelivery().DisableTimeoutManager();
transportConfig.Routing().DisablePublishing();

ec.UseSerialization<NewtonsoftJsonSerializer>();
}))
Expand All @@ -67,9 +42,7 @@ await Scenario.Define<SourceContext>()
{
var transportConfig = ec.UseTransport<AzureStorageQueueTransport>();
transportConfig.ConnectionString(asqConnectionString);
transportConfig.DisablePublishing();

transportConfig.DelayedDelivery().DisableTimeoutManager();
transportConfig.Routing().DisablePublishing();

ec.UseSerialization<NewtonsoftJsonSerializer>();
})
Expand All @@ -83,7 +56,7 @@ await Scenario.Define<SourceContext>()
await migrationRunner.Run(DateTime.Now.AddDays(-10), EndpointFilter.SpecificEndpoint(sourceEndpoint), new Dictionary<string, string>());
}))
.Done(c => c.GotTheDelayedMessage)
.Run(TimeSpan.FromSeconds(30));
.Run(new System.Threading.CancellationTokenSource(TimeSpan.FromSeconds(30)).Token);

Assert.That(context.GotTheDelayedMessage, Is.True);
}
Expand Down Expand Up @@ -140,4 +113,4 @@ public class DelayedMessage : IMessage
{
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace TimeoutMigrationTool.Asp.AcceptanceTests
namespace TimeoutMigrationTool.Asp.AcceptanceTests
{
using NServiceBus.Features;
using NServiceBus;
Expand Down Expand Up @@ -27,28 +27,7 @@ public async Task Can_migrate_timeouts()
var sourceEndpoint = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(AspSource));
var targetEndpoint = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(RabbitMqTarget));

await Scenario.Define<SourceContext>()
.WithEndpoint<AspSource>(b => b.CustomConfig(ec =>
{
SetupPersistence(ec);
})
.When(async (session, c) =>
{
var delayedMessage = new DelayedMessage();

var options = new SendOptions();

options.DelayDeliveryWith(TimeSpan.FromSeconds(15));
options.SetDestination(targetEndpoint);

await session.Send(delayedMessage, options);

await WaitUntilTheTimeoutsAreSavedInAsp(sourceEndpoint, 2);

c.TimeoutSet = true;
}))
.Done(c => c.TimeoutSet)
.Run(TimeSpan.FromSeconds(30));
await StoreLegacyTimeout(sourceEndpoint, targetEndpoint, typeof(DelayedMessage));

var context = await Scenario.Define<TargetContext>()
.WithEndpoint<RabbitMqTarget>(b => b.CustomConfig(ec =>
Expand All @@ -66,7 +45,7 @@ await Scenario.Define<SourceContext>()
await migrationRunner.Run(DateTime.Now.AddDays(-10), EndpointFilter.SpecificEndpoint(sourceEndpoint), new Dictionary<string, string>());
}))
.Done(c => c.GotTheDelayedMessage)
.Run(TimeSpan.FromSeconds(30));
.Run(new System.Threading.CancellationTokenSource(TimeSpan.FromSeconds(30)).Token);

Assert.That(context.GotTheDelayedMessage, Is.True);
}
Expand Down Expand Up @@ -125,4 +104,4 @@ public class DelayedMessage : IMessage
{
}
}
}
}
30 changes: 5 additions & 25 deletions src/TimeoutMigrationTool.Asp.AcceptanceTests/AspToSqlTEndToEnd.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace TimeoutMigrationTool.Asp.AcceptanceTests
namespace TimeoutMigrationTool.Asp.AcceptanceTests
{
using NServiceBus.Features;
using NServiceBus;
Expand Down Expand Up @@ -37,27 +37,7 @@ public async Task Can_migrate_timeouts()
var sourceEndpoint = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(AspSource));
var targetEndpoint = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(SqlTTarget));

await Scenario.Define<SourceContext>()
.WithEndpoint<AspSource>(b => b.CustomConfig(ec =>
{
SetupPersistence(ec);
})
.When(async (session, c) =>
{
var delayedMessage = new DelayedMessage();
var options = new SendOptions();

options.DelayDeliveryWith(TimeSpan.FromSeconds(15));
options.SetDestination(targetEndpoint);

await session.Send(delayedMessage, options);

await WaitUntilTheTimeoutsAreSavedInAsp(sourceEndpoint, 2);

c.TimeoutSet = true;
}))
.Done(c => c.TimeoutSet)
.Run(TimeSpan.FromSeconds(30));
await StoreLegacyTimeout(sourceEndpoint, targetEndpoint, typeof(DelayedMessage));

var setupContext = await Scenario.Define<TargetContext>()
.WithEndpoint<SqlTTarget>(b => b.CustomConfig(ec =>
Expand All @@ -68,7 +48,7 @@ await Scenario.Define<SourceContext>()
.ConnectionString(sqlConnectionString);
}))
.Done(c => c.EndpointsStarted)
.Run(TimeSpan.FromSeconds(30));
.Run(new System.Threading.CancellationTokenSource(TimeSpan.FromSeconds(30)).Token);

var logger = new TestLoggingAdapter(setupContext);
var timeoutStorage = CreateTimeoutStorage(sourceEndpoint);
Expand All @@ -86,7 +66,7 @@ await Scenario.Define<SourceContext>()
.ConnectionString(sqlConnectionString);
}))
.Done(c => c.GotTheDelayedMessage)
.Run(TimeSpan.FromSeconds(30));
.Run(new System.Threading.CancellationTokenSource(TimeSpan.FromSeconds(30)).Token);

Assert.That(context.GotTheDelayedMessage, Is.True);
}
Expand Down Expand Up @@ -143,4 +123,4 @@ public class DelayedMessage : IMessage
{
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
using NServiceBus;
using NServiceBus.AcceptanceTesting.Support;
using NServiceBus.ObjectBuilder;
using Microsoft.Extensions.DependencyInjection;

public static class ConfigureExtensions
{
Expand All @@ -11,12 +11,12 @@ public static void RegisterComponentsAndInheritanceHierarchy(this EndpointConfig
builder.RegisterComponents(r => { RegisterInheritanceHierarchyOfContextOnContainer(runDescriptor, r); });
}

static void RegisterInheritanceHierarchyOfContextOnContainer(RunDescriptor runDescriptor, IConfigureComponents r)
static void RegisterInheritanceHierarchyOfContextOnContainer(RunDescriptor runDescriptor, IServiceCollection r)
{
var type = runDescriptor.ScenarioContext.GetType();
while (type != typeof(object))
{
r.RegisterSingleton(type, runDescriptor.ScenarioContext);
r.AddSingleton(type, runDescriptor.ScenarioContext);
type = type.BaseType;
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/TimeoutMigrationTool.Asp.AcceptanceTests/DefaultServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

public class DefaultServer : IEndpointSetupTemplate
{
public virtual Task<EndpointConfiguration> GetConfiguration(RunDescriptor runDescriptor, EndpointCustomizationConfiguration endpointCustomizationConfiguration, Action<EndpointConfiguration> configurationBuilderCustomization)
public virtual async Task<EndpointConfiguration> GetConfiguration(RunDescriptor runDescriptor, EndpointCustomizationConfiguration endpointCustomizationConfiguration, Func<EndpointConfiguration, Task> configurationBuilderCustomization)
{
var endpointConfiguration = new EndpointConfiguration(endpointCustomizationConfiguration.EndpointName);

Expand All @@ -26,9 +26,9 @@ public virtual Task<EndpointConfiguration> GetConfiguration(RunDescriptor runDes

endpointConfiguration.RegisterComponentsAndInheritanceHierarchy(runDescriptor);

configurationBuilderCustomization(endpointConfiguration);
await configurationBuilderCustomization(endpointConfiguration);

return Task.FromResult(endpointConfiguration);
return endpointConfiguration;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace TimeoutMigrationTool.Asp.AcceptanceTests
namespace TimeoutMigrationTool.Asp.AcceptanceTests
{
using System;
using System.Collections.Generic;
Expand All @@ -23,7 +23,13 @@ public static IEnumerable<Type> GetTypesScopedByTestClass(this EndpointCustomiza

types = types.Union(endpointConfiguration.TypesToInclude);

return types.Where(t => !endpointConfiguration.TypesToExclude.Contains(t)).ToList();
return types.Where(t => !IsExcluded(endpointConfiguration, t)).ToList();
}

static bool IsExcluded(EndpointCustomizationConfiguration endpointConfiguration, Type type)
{
var typesToExclude = endpointConfiguration.GetType().GetProperty("TypesToExclude")?.GetValue(endpointConfiguration) as IEnumerable<Type>;
return typesToExclude?.Contains(type) ?? false;
}

static IEnumerable<Type> GetNestedTypeRecursive(Type rootType, Type builderType)
Expand All @@ -46,4 +52,4 @@ static IEnumerable<Type> GetNestedTypeRecursive(Type rootType, Type builderType)
}
}
}
}
}
Loading
Loading