Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3e57193
Hack my way through things for now
danielmarbach Oct 15, 2025
66926bb
Cleanup some tests
danielmarbach Oct 15, 2025
06ce795
Spike definition factory
danielmarbach Oct 15, 2025
4198d29
Obsolete some no longer needed APIs
danielmarbach Oct 16, 2025
dbd0a92
Align acceptance tests
danielmarbach Oct 16, 2025
466e581
PersistenceRegistry
danielmarbach Oct 16, 2025
c2be6d8
Fix test
danielmarbach Oct 16, 2025
532c6b3
Fix more support usage
danielmarbach Oct 16, 2025
696ad22
More obsoletes and cleanup
danielmarbach Oct 16, 2025
740eb31
Removing the settings holder for now because it allows us to only app…
danielmarbach Oct 16, 2025
853863f
Approve API changes
danielmarbach Oct 16, 2025
4e712b9
Nullable
danielmarbach Oct 16, 2025
1f494fe
Simplify registry
danielmarbach Oct 16, 2025
c2d64d7
Remove constraint
danielmarbach Oct 16, 2025
b9ffe7d
Static
danielmarbach Oct 16, 2025
b4291ad
Address review feedback
danielmarbach Oct 16, 2025
aefbeb3
Revert "Obsolete some no longer needed APIs" messup
danielmarbach Oct 16, 2025
2182440
Simplify syntax
danielmarbach Oct 17, 2025
3128a82
Use generics instead
danielmarbach Oct 17, 2025
316dc02
Tweaks
andreasohlund Oct 17, 2025
2987592
Explicit implementation because this is not something we have to publ…
danielmarbach Oct 17, 2025
700fe3f
Better data structure to be closer to the previous behavior
danielmarbach Oct 17, 2025
944da11
Small tweak
danielmarbach Oct 17, 2025
f09ecb8
Another hint
danielmarbach Oct 17, 2025
c17fbc8
Simplify deconstruction
danielmarbach Oct 17, 2025
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
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
namespace NServiceBus;

using Features;
using AcceptanceTesting;
using Persistence;

public class AcceptanceTestingPersistence : PersistenceDefinition
public class AcceptanceTestingPersistence : PersistenceDefinition, IPersistenceDefinitionFactory<AcceptanceTestingPersistence>
{
internal AcceptanceTestingPersistence()
AcceptanceTestingPersistence()
{
Supports<StorageType.Sagas>(s => s.EnableFeatureByDefault<AcceptanceTestingSagaPersistence>());
Supports<StorageType.Subscriptions>(s => s.EnableFeatureByDefault<AcceptanceTestingSubscriptionPersistence>());
Supports<StorageType.Outbox>(s => s.EnableFeatureByDefault<AcceptanceTestingOutboxPersistence>());
Supports<StorageType.Sagas, AcceptanceTestingSagaPersistence>();
Supports<StorageType.Subscriptions, AcceptanceTestingSubscriptionPersistence>();
Supports<StorageType.Outbox, AcceptanceTestingOutboxPersistence>();
}

static AcceptanceTestingPersistence IPersistenceDefinitionFactory<AcceptanceTestingPersistence>.Create() => new();
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,21 @@ public void Should_fail_to_start()
Assert.That(exception.Message, Does.Contain("The selected persistence doesn't have support for outbox storage"));
}

public class Context : ScenarioContext
{
}
public class Context : ScenarioContext;

public class Endpoint : EndpointConfigurationBuilder
{
public Endpoint()
{
public Endpoint() =>
EndpointSetup<ServerWithNoDefaultPersistenceDefinitions>(c =>
{
c.EnableOutbox();
c.ConfigureTransport().TransportTransactionMode = TransportTransactionMode.ReceiveOnly;
c.UsePersistence<FakeNoOutboxSupportPersistence>();
});
}
}

class FakeNoOutboxSupportPersistence : PersistenceDefinition
class FakeNoOutboxSupportPersistence : PersistenceDefinition, IPersistenceDefinitionFactory<FakeNoOutboxSupportPersistence>
{
public static FakeNoOutboxSupportPersistence Create() => new();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using AcceptanceTesting;
using EndpointTemplates;
using Extensibility;
using Features;
using Microsoft.Extensions.DependencyInjection;
using NServiceBus.Persistence;
using NUnit.Framework;
Expand All @@ -18,69 +19,58 @@ public class When_a_persistence_does_not_provide_synchronized_storage_session :
// is not altered by Fody to throw an ObjectDisposedException if it was disposed
[Test]
[Repeat(2)]
public async Task ReceiveFeature_should_work_without_ISynchronizedStorage()
{
public async Task ReceiveFeature_should_work_without_ISynchronizedStorage() =>
await Scenario.Define<Context>()
.WithEndpoint<NoSyncEndpoint>(e => e.When(b => b.SendLocal(new MyMessage())))
.Done(c => c.MessageReceived)
.Run();
}

class FakeNoSynchronizedStorageSupportPersistence : PersistenceDefinition
class FakeNoSynchronizedStorageSupportPersistence : PersistenceDefinition, IPersistenceDefinitionFactory<FakeNoSynchronizedStorageSupportPersistence>
{
public FakeNoSynchronizedStorageSupportPersistence()
FakeNoSynchronizedStorageSupportPersistence()
{
Supports<StorageType.Sagas, FakeStorage>();
Supports<StorageType.Subscriptions, FakeStorage>();
}

public static FakeNoSynchronizedStorageSupportPersistence Create() => new();

sealed class FakeStorage : Feature
{
Supports<StorageType.Sagas>(s => { });
Supports<StorageType.Subscriptions>(s => { });
protected override void Setup(FeatureConfigurationContext context)
{
}
}
}

class NoOpISubscriptionStorage : ISubscriptionStorage
{
public Task<IEnumerable<Subscriber>> GetSubscriberAddressesForMessage(IEnumerable<MessageType> messageTypes, ContextBag context, CancellationToken cancellationToken = default)
{
return Task.FromResult<IEnumerable<Subscriber>>(null);
}
public Task<IEnumerable<Subscriber>> GetSubscriberAddressesForMessage(IEnumerable<MessageType> messageTypes, ContextBag context, CancellationToken cancellationToken = default) => Task.FromResult<IEnumerable<Subscriber>>(null);

public Task Subscribe(Subscriber subscriber, MessageType messageType, ContextBag context, CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public Task Subscribe(Subscriber subscriber, MessageType messageType, ContextBag context, CancellationToken cancellationToken = default) => Task.CompletedTask;

public Task Unsubscribe(Subscriber subscriber, MessageType messageType, ContextBag context, CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public Task Unsubscribe(Subscriber subscriber, MessageType messageType, ContextBag context, CancellationToken cancellationToken = default) => Task.CompletedTask;
}

class NoSyncEndpoint : EndpointConfigurationBuilder
{
public NoSyncEndpoint()
{
public NoSyncEndpoint() =>
EndpointSetup<ServerWithNoDefaultPersistenceDefinitions>(c =>
{
// The subscription storage is needed because at this stage we have no way of DisablingPublishing on the non-generic version of ConfigureTransport
c.RegisterComponents(container => container.AddSingleton<ISubscriptionStorage, NoOpISubscriptionStorage>());
c.UsePersistence<FakeNoSynchronizedStorageSupportPersistence>();
});
}
}

public class MyMessageHandler : IHandleMessages<MyMessage>
public class MyMessageHandler(Context testContext) : IHandleMessages<MyMessage>
{
public MyMessageHandler(Context context)
{
testContext = context;
}

public Task Handle(MyMessage message, IMessageHandlerContext context)
{
testContext.MessageReceived = true;

return Task.CompletedTask;
}

Context testContext;
}

public class Context : ScenarioContext
Expand All @@ -89,7 +79,5 @@ public class Context : ScenarioContext
public bool MessageReceived { get; set; }
}

public class MyMessage : ICommand
{
}
public class MyMessage : ICommand;
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,38 +100,25 @@ public PublisherWithAuthorizer()
}
class StorageAccessor : FeatureStartupTask
{
public StorageAccessor(ISubscriptionStorage subscriptionStorage, Context testContext)
{
testContext.SubscriptionStorage = (FakePersistence.FakeSubscriptionStorage)subscriptionStorage;
}
public StorageAccessor(ISubscriptionStorage subscriptionStorage, Context testContext) => testContext.SubscriptionStorage = (FakePersistence.FakeSubscriptionStorage)subscriptionStorage;

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

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

public class AllowedEvent : IEvent
{
}
public class AllowedEvent : IEvent;

public class ForbiddenEvent : IEvent
{
}
public class ForbiddenEvent : IEvent;

class FakePersistence : PersistenceDefinition
class FakePersistence : PersistenceDefinition, IPersistenceDefinitionFactory<FakePersistence>
{
public FakePersistence()
{
Supports<StorageType.Subscriptions>(s => s.EnableFeatureByDefault(typeof(SubscriptionStorageFeature)));
}
FakePersistence() => Supports<StorageType.Subscriptions, SubscriptionStorageFeature>();

class SubscriptionStorageFeature : Feature
{
protected override void Setup(FeatureConfigurationContext context)
{
context.Services.AddSingleton<ISubscriptionStorage>(new FakeSubscriptionStorage());
}
protected override void Setup(FeatureConfigurationContext context) => context.Services.AddSingleton<ISubscriptionStorage>(new FakeSubscriptionStorage());
}

public class FakeSubscriptionStorage : ISubscriptionStorage
Expand All @@ -148,5 +135,7 @@ public Task Subscribe(Unicast.Subscriptions.MessageDrivenSubscriptions.Subscribe

public Task<IEnumerable<Unicast.Subscriptions.MessageDrivenSubscriptions.Subscriber>> GetSubscriberAddressesForMessage(IEnumerable<MessageType> messageTypes, ContextBag context, CancellationToken cancellationToken = default) => throw new NotImplementedException();
}

public static FakePersistence Create() => new();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using NServiceBus;
using NServiceBus.AcceptanceTesting;
using NServiceBus.AcceptanceTests.EndpointTemplates;
using NServiceBus.Extensibility;
using NServiceBus.Features;
using AcceptanceTesting;
using EndpointTemplates;
using Extensibility;
using Features;
using NServiceBus.Persistence;
using NServiceBus.Unicast.Subscriptions;
using Unicast.Subscriptions;
using NServiceBus.Unicast.Subscriptions.MessageDrivenSubscriptions;
using NUnit.Framework;
using Settings;
using Conventions = AcceptanceTesting.Customization.Conventions;

public class Pub_from_sendonly : NServiceBusAcceptanceTest
Expand All @@ -39,88 +40,65 @@ public class Context : ScenarioContext

public class SendOnlyPublisher : EndpointConfigurationBuilder
{
public SendOnlyPublisher()
{
public SendOnlyPublisher() =>
EndpointSetup<DefaultPublisher>(b =>
{
b.SendOnly();
b.UsePersistence(typeof(HardCodedPersistence));
b.UsePersistence<HardCodedPersistence>();
b.DisableFeature<AutoSubscribe>();
}, metadata => metadata.RegisterSelfAsPublisherFor<MyEvent>(this));
}
}

public class Subscriber : EndpointConfigurationBuilder
{
public Subscriber()
{
EndpointSetup<DefaultServer>(c => c.DisableFeature<AutoSubscribe>());
}
public Subscriber() => EndpointSetup<DefaultServer>(c => c.DisableFeature<AutoSubscribe>());

public class MyHandler : IHandleMessages<MyEvent>
public class MyHandler(Context testContext) : IHandleMessages<MyEvent>
{
public MyHandler(Context context)
{
testContext = context;
}

public Task Handle(MyEvent messageThatIsEnlisted, IMessageHandlerContext context)
{
testContext.SubscriberGotTheEvent = true;

return Task.CompletedTask;
}

Context testContext;
}
}


public class MyEvent : IEvent
{
}
public class MyEvent : IEvent;

public class HardCodedPersistence : PersistenceDefinition
public class HardCodedPersistence : PersistenceDefinition, IPersistenceDefinitionFactory<HardCodedPersistence>
{
internal HardCodedPersistence()
{
Supports<StorageType.Subscriptions>(s => s.EnableFeatureByDefault<HardCodedPersistenceFeature>());
}
HardCodedPersistence() => Supports<StorageType.Subscriptions, HardCodedPersistenceFeature>();

public static HardCodedPersistence Create() => new();
}

public class HardCodedPersistenceFeature : Feature
class HardCodedPersistenceFeature : Feature
{
protected override void Setup(FeatureConfigurationContext context)
{
context.Services.AddSingleton(typeof(ISubscriptionStorage), typeof(HardcodedSubscriptionManager));
}
protected override void Setup(FeatureConfigurationContext context) =>
context.Services.AddSingleton<ISubscriptionStorage, HardcodedSubscriptionManager>();
}

public class HardcodedSubscriptionManager : ISubscriptionStorage
class HardcodedSubscriptionManager : ISubscriptionStorage
{
public HardcodedSubscriptionManager()
{
addressTask = Task.FromResult(new[]
{
new Unicast.Subscriptions.MessageDrivenSubscriptions.Subscriber(Conventions.EndpointNamingConvention(typeof(Subscriber)), null)
}.AsEnumerable());
}

public Task Subscribe(Unicast.Subscriptions.MessageDrivenSubscriptions.Subscriber subscriber, MessageType messageType, ContextBag context, CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public Task Subscribe(Unicast.Subscriptions.MessageDrivenSubscriptions.Subscriber subscriber,
MessageType messageType, ContextBag context, CancellationToken cancellationToken = default) =>
Task.CompletedTask;

public Task Unsubscribe(Unicast.Subscriptions.MessageDrivenSubscriptions.Subscriber subscriber, MessageType messageType, ContextBag context, CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public Task Unsubscribe(Unicast.Subscriptions.MessageDrivenSubscriptions.Subscriber subscriber,
MessageType messageType, ContextBag context, CancellationToken cancellationToken = default) =>
Task.CompletedTask;

public Task<IEnumerable<Unicast.Subscriptions.MessageDrivenSubscriptions.Subscriber>> GetSubscriberAddressesForMessage(IEnumerable<MessageType> messageTypes, ContextBag context, CancellationToken cancellationToken = default)
{
return addressTask;
}
public Task<IEnumerable<Unicast.Subscriptions.MessageDrivenSubscriptions.Subscriber>>
GetSubscriberAddressesForMessage(IEnumerable<MessageType> messageTypes, ContextBag context,
CancellationToken cancellationToken = default) => addressTask;

Task<IEnumerable<Unicast.Subscriptions.MessageDrivenSubscriptions.Subscriber>> addressTask;
readonly Task<IEnumerable<Unicast.Subscriptions.MessageDrivenSubscriptions.Subscriber>> addressTask =
Task.FromResult(new[]
{
new Unicast.Subscriptions.MessageDrivenSubscriptions.Subscriber(
Conventions.EndpointNamingConvention(typeof(Subscriber)), null)
}.AsEnumerable());
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace NServiceBus.AcceptanceTests.Recoverability;

using System;
using System.Linq;
using System.Threading.Tasks;
using AcceptanceTesting;
using AcceptanceTesting.Customization;
Expand Down
Loading