-
Notifications
You must be signed in to change notification settings - Fork 648
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ability to open storage session outside the pipeline (#6467)
* Introduce SynchronizedStorage feature Bring in feature dependency Approve API * Adapter to bridge the old and the new world * Make it possible to retrieve the storage session via DI and also open the completable one from outside the core * Add acceptance test that verifies session can be opened outside the pipeline * Additional checks * Shorter endpoint name * Reregister the CompletableSynchronizedStorageSession properly so that we don't override Co-authored-by: Tomasz Masternak <tomasz.masternak@particular.net> * Fix synchronized storage retrival * Update src/NServiceBus.Core/Pipeline/Incoming/LoadHandlersConnector.cs Co-authored-by: Tim Bussmann <timbussmann@users.noreply.github.com> * make GetAdaptedSession extension public * Session disposal (#6525) * resolve storage session per call * only dispose session once * approve scope change in test * change registration back to same scope as the referenced type * Use GetAdaptedSession consistently * Make the session adapter class public (#6526) * make the session adapter class public * Approve Co-authored-by: Daniel Marbach <daniel.marbach@openplace.net> * Move CompletableSynchronizedStorageSessionAdapter into the persistence namespace * Rename paramater * aligning names Co-authored-by: Tomasz Masternak <tomasz.masternak@particular.net> Co-authored-by: Tim Bussmann <timbussmann@users.noreply.github.com>
- Loading branch information
1 parent
6b37622
commit ede5f8f
Showing
23 changed files
with
454 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
...eBus.AcceptanceTests/Core/Persistence/When_a_persistence_provides_synchronized_session.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
namespace NServiceBus.AcceptanceTests.Core.Persistence | ||
{ | ||
using System.Threading.Tasks; | ||
using AcceptanceTesting; | ||
using EndpointTemplates; | ||
using NServiceBus.Persistence; | ||
using NUnit.Framework; | ||
|
||
public class When_a_persistence_provides_synchronized_session : NServiceBusAcceptanceTest | ||
{ | ||
[Test] | ||
public async Task Synchronized_session_should_be_of_exact_type_provided_by_persistence() | ||
{ | ||
var result = await Scenario.Define<Context>() | ||
.WithEndpoint<Endpoint>(e => e.When(b => b.SendLocal(new MyMessage()))) | ||
.Done(c => c.MessageReceived) | ||
.Run(); | ||
|
||
Assert.IsNotNull(result.SynchronizedStorageSessionInstanceInContainer); | ||
Assert.IsNotNull(result.SynchronizedStorageSessionInstanceInHandlingContext); | ||
Assert.AreSame(result.SynchronizedStorageSessionInstanceInContainer, result.SynchronizedStorageSessionInstanceInHandlingContext); | ||
} | ||
|
||
class Context : ScenarioContext | ||
{ | ||
public SynchronizedStorageSession SynchronizedStorageSessionInstanceInContainer { get; set; } | ||
public SynchronizedStorageSession SynchronizedStorageSessionInstanceInHandlingContext { get; set; } | ||
public bool MessageReceived { get; set; } | ||
} | ||
|
||
class Endpoint : EndpointConfigurationBuilder | ||
{ | ||
public Endpoint() => EndpointSetup<DefaultServer>(); | ||
|
||
class MyMessageHandler : IHandleMessages<MyMessage> | ||
{ | ||
public MyMessageHandler(Context testContext, SynchronizedStorageSession storageSession) | ||
{ | ||
this.testContext = testContext; | ||
testContext.SynchronizedStorageSessionInstanceInContainer = storageSession; | ||
} | ||
|
||
public Task Handle(MyMessage message, IMessageHandlerContext context) | ||
{ | ||
testContext.SynchronizedStorageSessionInstanceInHandlingContext = context.SynchronizedStorageSession; | ||
testContext.MessageReceived = true; | ||
return Task.FromResult(0); | ||
} | ||
|
||
readonly Context testContext; | ||
} | ||
} | ||
|
||
public class MyMessage : IMessage | ||
{ | ||
} | ||
} | ||
} |
95 changes: 95 additions & 0 deletions
95
...sts/Core/Reliability/SynchronizedStorage/When_opening_storage_session_outside_pipeline.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
namespace NServiceBus.AcceptanceTests.Reliability.SynchronizedStorage | ||
{ | ||
using System.Threading.Tasks; | ||
using AcceptanceTesting; | ||
using EndpointTemplates; | ||
using Extensibility; | ||
using Features; | ||
using NUnit.Framework; | ||
using ObjectBuilder; | ||
using Persistence; | ||
|
||
public class When_opening_storage_session_outside_pipeline : NServiceBusAcceptanceTest | ||
{ | ||
[Test] | ||
public async Task Should_provide_adapted_session_with_same_scope() | ||
{ | ||
var context = await Scenario.Define<Context>() | ||
.WithEndpoint<Endpoint>() | ||
.Done(c => c.Done) | ||
.Run(); | ||
|
||
Assert.True(context.AdaptedSessionIsNullBeforeOpening, "The adapted session was not null before opening the session."); | ||
Assert.True(context.AdaptedSessionNotNullAfterOpening, "The adapted session was null after opening the session."); | ||
Assert.True(context.StorageSessionEqual, "The scoped storage session should be equal."); | ||
} | ||
|
||
public class Context : ScenarioContext | ||
{ | ||
public bool StorageSessionEqual { get; set; } | ||
public bool AdaptedSessionIsNullBeforeOpening { get; set; } | ||
public bool AdaptedSessionNotNullAfterOpening { get; set; } | ||
public bool Done { get; set; } | ||
} | ||
|
||
public class Endpoint : EndpointConfigurationBuilder | ||
{ | ||
public Endpoint() | ||
{ | ||
EndpointSetup<DefaultServer>(c => | ||
{ | ||
c.EnableFeature<Bootstrapper>(); | ||
}); | ||
} | ||
|
||
public class Bootstrapper : Feature | ||
{ | ||
public Bootstrapper() => EnableByDefault(); | ||
|
||
protected override void Setup(FeatureConfigurationContext context) | ||
{ | ||
context.RegisterStartupTask(b => new MyTask(b.Build<Context>(), b)); | ||
} | ||
|
||
public class MyTask : FeatureStartupTask | ||
{ | ||
public MyTask(Context scenarioContext, IBuilder provider) | ||
{ | ||
this.provider = provider; | ||
this.scenarioContext = scenarioContext; | ||
} | ||
|
||
protected override async Task OnStart(IMessageSession session) | ||
{ | ||
using (var childBuilder = provider.CreateChildBuilder()) | ||
using (var completableSynchronizedStorageSession = | ||
childBuilder.Build<CompletableSynchronizedStorageSessionAdapter>()) | ||
{ | ||
scenarioContext.AdaptedSessionIsNullBeforeOpening = | ||
completableSynchronizedStorageSession.AdaptedSession == null; | ||
|
||
await completableSynchronizedStorageSession.Open(new ContextBag()); | ||
|
||
scenarioContext.AdaptedSessionNotNullAfterOpening = | ||
completableSynchronizedStorageSession.AdaptedSession != null; | ||
|
||
var synchronizedStorage = childBuilder.Build<SynchronizedStorageSession>(); | ||
|
||
scenarioContext.StorageSessionEqual = | ||
completableSynchronizedStorageSession.AdaptedSession == synchronizedStorage; | ||
|
||
await completableSynchronizedStorageSession.CompleteAsync(); | ||
} | ||
|
||
scenarioContext.Done = true; | ||
} | ||
|
||
protected override Task OnStop(IMessageSession session) => Task.FromResult(0); | ||
|
||
readonly Context scenarioContext; | ||
readonly IBuilder provider; | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
...ests/Reliability/SynchronizedStorage/CompletableSynchronizedStorageSessionAdapterTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
namespace NServiceBus.Core.Tests.Reliability | ||
{ | ||
using System.Threading.Tasks; | ||
using Extensibility; | ||
using NServiceBus.Outbox; | ||
using NServiceBus.Persistence; | ||
using NUnit.Framework; | ||
using Transport; | ||
|
||
[TestFixture] | ||
public class CompletableSynchronizedStorageSessionAdapterTests | ||
{ | ||
[Test] | ||
public async Task Should_dispose_adapted_session_only_once() | ||
{ | ||
var storageAdapter = new FakeStorageAdapter(); | ||
var sessionAdapter = new CompletableSynchronizedStorageSessionAdapter(storageAdapter, null); | ||
await sessionAdapter.TryOpen(new TransportTransaction(), new ContextBag()); | ||
|
||
sessionAdapter.Dispose(); | ||
sessionAdapter.Dispose(); | ||
|
||
Assert.AreEqual(1, storageAdapter.StorageSession.DisposeCounter); | ||
} | ||
} | ||
|
||
public class FakeStorageAdapter : ISynchronizedStorageAdapter | ||
{ | ||
public FakeStorageSession StorageSession { get; } = new FakeStorageSession(); | ||
|
||
public Task<CompletableSynchronizedStorageSession> TryAdapt(OutboxTransaction transaction, ContextBag context) => Task.FromResult<CompletableSynchronizedStorageSession>(StorageSession); | ||
|
||
public Task<CompletableSynchronizedStorageSession> TryAdapt(TransportTransaction transportTransaction, ContextBag context) => Task.FromResult<CompletableSynchronizedStorageSession>(StorageSession); | ||
} | ||
|
||
public class FakeStorageSession : CompletableSynchronizedStorageSession | ||
{ | ||
public int DisposeCounter { get; private set; } | ||
|
||
public void Dispose() => DisposeCounter++; | ||
|
||
public Task CompleteAsync() => Task.FromResult(0); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 0 additions & 17 deletions
17
src/NServiceBus.Core/Pipeline/Incoming/NoOpOutbox/NoOpOutboxTransaction.cs
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.