Skip to content

Add new configuration API for Transactional Session v3.3.0 #1282

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"NServiceBus.NHibernate.PersistenceTests, PublicKey=00240000048000009400000006020000002400005253413100040000010001007f16e21368ff041183fab592d9e8ed37e7be355e93323147a1d29983d6e591b04282e4da0c9e18bd901e112c0033925eb7d7872c2f1706655891c5c9d57297994f707d16ee9a8f40d978f064ee1ffc73c0db3f4712691b23bf596f75130f4ec978cf78757ec034625a5f27e6bb50c618931ea49f6f628fd74271c32959efb1c5")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"NServiceBus.NHibernate.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001007f16e21368ff041183fab592d9e8ed37e7be355e93323147a1d29983d6e591b04282e4da0c9e18bd901e112c0033925eb7d7872c2f1706655891c5c9d57297994f707d16ee9a8f40d978f064ee1ffc73c0db3f4712691b23bf596f75130f4ec978cf78757ec034625a5f27e6bb50c618931ea49f6f628fd74271c32959efb1c5")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"NServiceBus.NHibernate.TransactionalSession, PublicKey=0024000004800000940000000602000000240000525341310004000001000100dde965e6172e019ac82c2639ffe494dd2e7dd16347c34762a05732b492e110f2e4e2e1b5ef2d85c848ccfb671ee20a47c8d1376276708dc30a90ff1121b647ba3b7259a6bc383b2034938ef0e275b58b920375ac605076178123693c6c4f1331661a62eba28c249386855637780e3ff5f23a6d854700eaa6803ef48907513b92")]
[assembly: System.Runtime.InteropServices.ComVisible(false)]
namespace NServiceBus.Features
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
namespace NServiceBus.TransactionalSession.AcceptanceTests
{
using System;
using System.Threading;
using System.Threading.Tasks;
using NServiceBus.AcceptanceTesting;
using NServiceBus.Features;
namespace NServiceBus.TransactionalSession.AcceptanceTests;

using System;
using System.Threading;
using System.Threading.Tasks;
using Features;

public class CaptureServiceProviderStartupTask : FeatureStartupTask
{
public CaptureServiceProviderStartupTask(IServiceProvider serviceProvider, ScenarioContext context)
{
if (context is IInjectServiceProvider c)
{
c.ServiceProvider = serviceProvider;
}
}
public class CaptureServiceProviderStartupTask : FeatureStartupTask
{
public CaptureServiceProviderStartupTask(IServiceProvider serviceProvider, TransactionalSessionTestContext context, string endpointName) => context.RegisterServiceProvider(serviceProvider, endpointName);

protected override Task OnStart(IMessageSession session, CancellationToken cancellationToken = default) => Task.CompletedTask;
protected override Task OnStart(IMessageSession session, CancellationToken cancellationToken = default) => Task.CompletedTask;

protected override Task OnStop(IMessageSession session, CancellationToken cancellationToken = default) => Task.CompletedTask;
}
protected override Task OnStop(IMessageSession session, CancellationToken cancellationToken = default) => Task.CompletedTask;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
namespace NServiceBus.TransactionalSession.AcceptanceTests;

using System;
using System.Collections.Specialized;
using System.IO;
using System.Threading.Tasks;
using AcceptanceTesting;
using AcceptanceTesting.Customization;
using AcceptanceTesting.Support;
using global::NHibernate.Driver;
using NServiceBus.Configuration.AdvancedExtensibility;
using NUnit.Framework;
using Persistence.NHibernate;
using Persistence;

public class DefaultServer : IEndpointSetupTemplate
{
const string DefaultConnStr = @"Server=localhost\SqlExpress;Database=nservicebus;Trusted_Connection=True;";

public static string ConnectionString
{
get
{
string env = Environment.GetEnvironmentVariable("SQLServerConnectionString");
return string.IsNullOrEmpty(env) ? DefaultConnStr : env;
}
}

public virtual async Task<EndpointConfiguration> GetConfiguration(RunDescriptor runDescriptor, EndpointCustomizationConfiguration endpointCustomization,
Func<EndpointConfiguration, Task> configurationBuilderCustomization)
{
NHibernateSettingRetriever.AppSettings = () => new NameValueCollection
{
{ "NServiceBus/Persistence/NHibernate/show_sql", "true" },
{
"NServiceBus/Persistence/NHibernate/connection.driver_class",
typeof(MicrosoftDataSqlClientDriver).FullName
}
};

var endpointConfiguration = new EndpointConfiguration(endpointCustomization.EndpointName);

endpointConfiguration.EnableInstallers();
endpointConfiguration.UseSerialization<SystemJsonSerializer>();
endpointConfiguration.Recoverability()
.Delayed(delayed => delayed.NumberOfRetries(0))
.Immediate(immediate => immediate.NumberOfRetries(0));
endpointConfiguration.SendFailedMessagesTo("error");

var storageDir = Path.Combine(Path.GetTempPath(), "learn", TestContext.CurrentContext.Test.ID);

endpointConfiguration.UseTransport(new AcceptanceTestingTransport { StorageLocation = storageDir });

var persistence = endpointConfiguration.UsePersistence<NHibernatePersistence>();
persistence.ConnectionString(ConnectionString);

endpointConfiguration.GetSettings().Set(persistence);

if (runDescriptor.ScenarioContext is TransactionalSessionTestContext testContext)
{
endpointConfiguration.RegisterStartupTask(sp => new CaptureServiceProviderStartupTask(sp, testContext, endpointCustomization.EndpointName));
}

await configurationBuilderCustomization(endpointConfiguration).ConfigureAwait(false);

// scan types at the end so that all types used by the configuration have been loaded into the AppDomain
endpointConfiguration.TypesToIncludeInScan(endpointCustomization.GetTypesScopedByTestClass());

return endpointConfiguration;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,69 +1,18 @@
namespace NServiceBus.TransactionalSession.AcceptanceTests
{
using System;
using System.Collections.Specialized;
using System.IO;
using System.Threading.Tasks;
using AcceptanceTesting;
using AcceptanceTesting.Customization;
using AcceptanceTesting.Support;
using global::NHibernate.Driver;
using NUnit.Framework;
using Persistence;
using Persistence.NHibernate;

public class TransactionSessionDefaultServer : IEndpointSetupTemplate
{
public virtual async Task<EndpointConfiguration> GetConfiguration(RunDescriptor runDescriptor,
EndpointCustomizationConfiguration endpointConfiguration,
Func<EndpointConfiguration, Task> configurationBuilderCustomization)
{
NHibernateSettingRetriever.AppSettings = () => new NameValueCollection
{
{"NServiceBus/Persistence/NHibernate/show_sql", "true"},
{"NServiceBus/Persistence/NHibernate/connection.driver_class", typeof(MicrosoftDataSqlClientDriver).FullName}
};

var builder = new EndpointConfiguration(endpointConfiguration.EndpointName);
builder.UseSerialization<SystemJsonSerializer>();
builder.EnableInstallers();

builder.Recoverability()
.Delayed(delayed => delayed.NumberOfRetries(0))
.Immediate(immediate => immediate.NumberOfRetries(0));
builder.SendFailedMessagesTo("error");

var storageDir = Path.Combine(Path.GetTempPath(), "learn", TestContext.CurrentContext.Test.ID);

builder.UseTransport(new AcceptanceTestingTransport
{
StorageLocation = storageDir
});
namespace NServiceBus.TransactionalSession.AcceptanceTests;

var persistence = builder.UsePersistence<NHibernatePersistence>();
persistence.ConnectionString(ConnectionString);
persistence.EnableTransactionalSession();
using System;
using System.Threading.Tasks;
using AcceptanceTesting.Support;
using Configuration.AdvancedExtensibility;

builder.RegisterStartupTask(provider =>
new CaptureServiceProviderStartupTask(provider, runDescriptor.ScenarioContext));

await configurationBuilderCustomization(builder).ConfigureAwait(false);

// scan types at the end so that all types used by the configuration have been loaded into the AppDomain
builder.TypesToIncludeInScan(endpointConfiguration.GetTypesScopedByTestClass());

return builder;
}

const string DefaultConnStr = @"Server=localhost\SqlExpress;Database=nservicebus;Trusted_Connection=True;";

public static string ConnectionString
public class TransactionSessionDefaultServer : DefaultServer
{
public override async Task<EndpointConfiguration> GetConfiguration(RunDescriptor runDescriptor, EndpointCustomizationConfiguration endpointConfiguration,
Func<EndpointConfiguration, Task> configurationBuilderCustomization) =>
await base.GetConfiguration(runDescriptor, endpointConfiguration, async configuration =>
{
get
{
var env = Environment.GetEnvironmentVariable("SQLServerConnectionString");
return string.IsNullOrEmpty(env) ? DefaultConnStr : env;
}
}
}
configuration.GetSettings().Get<PersistenceExtensions<NHibernatePersistence>>().EnableTransactionalSession();

await configurationBuilderCustomization(configuration);
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace NServiceBus.TransactionalSession.AcceptanceTests;

using System;
using System.Collections.Concurrent;
using System.Reflection;
using AcceptanceTesting;

public class TransactionalSessionTestContext : ScenarioContext
{
public IServiceProvider ServiceProvider
{
get
{
var property = typeof(ScenarioContext).GetProperty("CurrentEndpoint", BindingFlags.NonPublic | BindingFlags.Static);

if (property!.GetValue(this) is not string endpointName)
{
throw new InvalidOperationException("Access to the service provider of the endpoint is only possible with in a When statement.");
}

if (!serviceProviders.TryGetValue(endpointName, out var serviceProvider))
{
throw new InvalidOperationException("Could not find service provider for endpoint " + endpointName);
}

return serviceProvider;
}
}

public void RegisterServiceProvider(IServiceProvider serviceProvider, string endpointName) => serviceProviders[endpointName] = serviceProvider;

readonly ConcurrentDictionary<string, IServiceProvider> serviceProviders = new();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
namespace NServiceBus.TransactionalSession.AcceptanceTests;

using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using AcceptanceTesting;
using AcceptanceTesting.Customization;
using Configuration.AdvancedExtensibility;
using NUnit.Framework;

public class When_using_outbox_send_only : NServiceBusAcceptanceTest
{
[Test()]
public async Task Should_send_messages_on_transactional_session_commit()
{
var context = await Scenario.Define<Context>()
.WithEndpoint<SendOnlyEndpoint>(s => s.When(async (_, ctx) =>
{
using var scope = ctx.ServiceProvider.CreateScope();
using var transactionalSession = scope.ServiceProvider.GetRequiredService<ITransactionalSession>();
await transactionalSession.Open(new NHibernateOpenSessionOptions());

var options = new SendOptions();

options.SetDestination(Conventions.EndpointNamingConvention.Invoke(typeof(AnotherEndpoint)));

await transactionalSession.Send(new SampleMessage(), options);

await transactionalSession.Commit(CancellationToken.None);
}))
.WithEndpoint<AnotherEndpoint>()
.WithEndpoint<ProcessorEndpoint>()
.Done(c => c.MessageReceived)
.Run();

Assert.That(context.MessageReceived, Is.True);
}

class Context : TransactionalSessionTestContext
{
public bool MessageReceived { get; set; }
}

class SendOnlyEndpoint : EndpointConfigurationBuilder
{
public SendOnlyEndpoint() => EndpointSetup<DefaultServer>(c =>
{
var persistence = c.GetSettings().Get<PersistenceExtensions<NHibernatePersistence>>();

var options = new TransactionalSessionOptions { ProcessorEndpoint = Conventions.EndpointNamingConvention.Invoke(typeof(ProcessorEndpoint)) };

persistence.EnableTransactionalSession(options);

c.EnableOutbox();
c.SendOnly();
});
}

class AnotherEndpoint : EndpointConfigurationBuilder
{
public AnotherEndpoint() => EndpointSetup<DefaultServer>();

class SampleHandler(Context testContext) : IHandleMessages<SampleMessage>
{
public Task Handle(SampleMessage message, IMessageHandlerContext context)
{
testContext.MessageReceived = true;

return Task.CompletedTask;
}
}
}

class ProcessorEndpoint : EndpointConfigurationBuilder
{
public ProcessorEndpoint() => EndpointSetup<TransactionSessionWithOutboxEndpoint>(c =>
{

});
}

class SampleMessage : ICommand
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,10 @@ CREATE TABLE [dbo].[SomeTable]([Id] [nvarchar](50) NOT NULL)
Assert.That(result, Is.EqualTo(rowId));
}

class Context : ScenarioContext, IInjectServiceProvider
class Context : TransactionalSessionTestContext
{
public bool MessageReceived { get; set; }
public bool CompleteMessageReceived { get; set; }
public IServiceProvider ServiceProvider { get; set; }
}

class AnEndpoint : EndpointConfigurationBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,10 @@ CREATE TABLE [dbo].[SomeTable]([Id] [nvarchar](50) NOT NULL)
Assert.That(result, Is.EqualTo(rowId));
}

class Context : ScenarioContext, IInjectServiceProvider
class Context : TransactionalSessionTestContext
{
public bool MessageReceived { get; set; }
public bool CompleteMessageReceived { get; set; }
public IServiceProvider ServiceProvider { get; set; }
}

class AnEndpoint : EndpointConfigurationBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace NServiceBus.TransactionalSession
public static class NHibernateTransactionalSessionExtensions
{
public static NServiceBus.PersistenceExtensions<NServiceBus.NHibernatePersistence> EnableTransactionalSession(this NServiceBus.PersistenceExtensions<NServiceBus.NHibernatePersistence> persistenceExtensions) { }
public static NServiceBus.PersistenceExtensions<NServiceBus.NHibernatePersistence> EnableTransactionalSession(this NServiceBus.PersistenceExtensions<NServiceBus.NHibernatePersistence> persistenceExtensions, NServiceBus.TransactionalSession.TransactionalSessionOptions transactionalSessionOptions) { }
public static System.Threading.Tasks.Task Open(this NServiceBus.TransactionalSession.ITransactionalSession transactionalSession, System.Threading.CancellationToken cancellationToken = default) { }
}
}
Loading