diff --git a/docs/guide/durability/leadership-and-troubleshooting.md b/docs/guide/durability/leadership-and-troubleshooting.md
index 843eb9db9..7641d41cc 100644
--- a/docs/guide/durability/leadership-and-troubleshooting.md
+++ b/docs/guide/durability/leadership-and-troubleshooting.md
@@ -63,7 +63,7 @@ builder.UseWolverine(opts =>
}
});
-using var host = builder.Build();~~~~
+using var host = builder.Build();
await host.StartAsync();
```
snippet source | anchor
diff --git a/docs/guide/durability/managing.md b/docs/guide/durability/managing.md
index ffae4056c..f3adc5306 100644
--- a/docs/guide/durability/managing.md
+++ b/docs/guide/durability/managing.md
@@ -165,3 +165,25 @@ If you just want to export the SQL to create the necessary database objects, you
dotnet run -- db-dump export.sql
```
where `export.sql` should be a file name.
+
+## Disabling All Persistence
+
+Let's say that you want to use the command line tooling to generate OpenAPI documentation, but do so
+without Wolverine being able to connect to any external databases (or transports, and you'll have to disable both for this to work).
+You can now do that with the option shown below as part of an [Alba](https://jasperfx.github.io/alba) test:
+
+
+
+```cs
+using var host = await AlbaHost.For(builder =>
+{
+ builder.ConfigureServices(services =>
+ {
+ // You probably have to do both
+ services.DisableAllExternalWolverineTransports();
+ services.DisableAllWolverineMessagePersistence();
+ });
+});
+```
+snippet source | anchor
+
diff --git a/docs/guide/extensions.md b/docs/guide/extensions.md
index 8b845e1e9..c81998ef5 100644
--- a/docs/guide/extensions.md
+++ b/docs/guide/extensions.md
@@ -109,7 +109,7 @@ internal class DisableExternalTransports : IWolverineExtension
}
}
```
-snippet source | anchor
+snippet source | anchor
And that extension is just added to the application's IoC container at test bootstrapping time like this:
diff --git a/docs/guide/http/multi-tenancy.md b/docs/guide/http/multi-tenancy.md
index add0bea40..222f40c9d 100644
--- a/docs/guide/http/multi-tenancy.md
+++ b/docs/guide/http/multi-tenancy.md
@@ -265,7 +265,7 @@ public static string NoTenantNoProblem()
return "hey";
}
```
-snippet source | anchor
+snippet source | anchor
If the above usage completely disabled all tenant id detection or validation, in the case of an endpoint that *might* be
@@ -283,7 +283,7 @@ public static string MaybeTenanted(IMessageBus bus)
return bus.TenantId ?? "none";
}
```
-snippet source | anchor
+snippet source | anchor
diff --git a/src/Http/Wolverine.Http.Tests/Wolverine.Http.Tests.csproj b/src/Http/Wolverine.Http.Tests/Wolverine.Http.Tests.csproj
index 72ff061ad..62205bf2b 100644
--- a/src/Http/Wolverine.Http.Tests/Wolverine.Http.Tests.csproj
+++ b/src/Http/Wolverine.Http.Tests/Wolverine.Http.Tests.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/src/Http/Wolverine.Http.Tests/bootstrap_with_no_persistence.cs b/src/Http/Wolverine.Http.Tests/bootstrap_with_no_persistence.cs
new file mode 100644
index 000000000..58cfa0842
--- /dev/null
+++ b/src/Http/Wolverine.Http.Tests/bootstrap_with_no_persistence.cs
@@ -0,0 +1,31 @@
+using Alba;
+using Microsoft.Extensions.DependencyInjection;
+using Shouldly;
+using Wolverine.Persistence.Durability;
+using Wolverine.Tracking;
+
+namespace Wolverine.Http.Tests;
+
+public class bootstrap_with_no_persistence
+{
+ [Fact]
+ public async Task start_up_with_no_persistence()
+ {
+ #region sample_bootstrap_with_no_persistence
+
+ using var host = await AlbaHost.For(builder =>
+ {
+ builder.ConfigureServices(services =>
+ {
+ // You probably have to do both
+ services.DisableAllExternalWolverineTransports();
+ services.DisableAllWolverineMessagePersistence();
+ });
+ });
+
+ #endregion
+
+ host.Services.GetRequiredService().ShouldBeOfType();
+ host.GetRuntime().Storage.ShouldBeOfType();
+ }
+}
\ No newline at end of file
diff --git a/src/Http/Wolverine.Http.Tests/multi_tenancy_detection_and_integration.cs b/src/Http/Wolverine.Http.Tests/multi_tenancy_detection_and_integration.cs
index 72eb065c5..cfbd16c2f 100644
--- a/src/Http/Wolverine.Http.Tests/multi_tenancy_detection_and_integration.cs
+++ b/src/Http/Wolverine.Http.Tests/multi_tenancy_detection_and_integration.cs
@@ -5,6 +5,8 @@
using IntegrationTests;
using Marten;
using Marten.Metadata;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
@@ -41,6 +43,7 @@ public void Dispose()
protected async Task configure(Action configure)
{
var builder = WebApplication.CreateBuilder([]);
+
builder.Services.AddScoped();
// Haven't gotten around to it yet, but there'll be some end to
@@ -57,17 +60,21 @@ protected async Task configure(Action configure)
});
builder.Services.AddWolverineHttp();
+ builder.Services.AddAuthentication("test");
+ builder.Services.AddAuthorization();
// Setting up Alba stubbed authentication so that we can fake
// out ClaimsPrincipal data on requests later
- var securityStub = new AuthenticationStub()
+ var securityStub = new AuthenticationStub("test")
.With("foo", "bar")
.With(JwtRegisteredClaimNames.Email, "guy@company.com")
.WithName("jeremy");
-
+
// Spinning up a test application using Alba
theHost = await AlbaHost.For(builder, app =>
{
+ app.UseAuthentication();
+ app.UseAuthorization();
app.MapWolverineEndpoints(configure);
}, securityStub);
@@ -367,12 +374,14 @@ public async Task does_tag_current_activity_with_tenant_id()
public static class TenantedEndpoints
{
+ [Authorize]
[WolverineGet("/tenant/route/{tenant}")]
public static string GetTenantIdFromRoute(IMessageBus bus)
{
return bus.TenantId;
}
+ [Authorize]
[WolverineGet("/tenant")]
public static string GetTenantIdFromWhatever(IMessageBus bus, HttpContext httpContext)
{
@@ -470,4 +479,12 @@ public static CustomActivityFeature FromHttpContext(HttpContext httpContext)
var activity = httpContext.Features.Get()?.Activity;
return new CustomActivityFeature(activity);
}
+}
+
+public class StubAuthenticationHandlerProvider : IAuthenticationHandlerProvider
+{
+ public Task GetHandlerAsync(HttpContext context, string authenticationScheme)
+ {
+ throw new NotImplementedException();
+ }
}
\ No newline at end of file
diff --git a/src/Persistence/Wolverine.RDBMS/Polling/DatabaseBatcher.cs b/src/Persistence/Wolverine.RDBMS/Polling/DatabaseBatcher.cs
index 923dbca48..8171a7c07 100644
--- a/src/Persistence/Wolverine.RDBMS/Polling/DatabaseBatcher.cs
+++ b/src/Persistence/Wolverine.RDBMS/Polling/DatabaseBatcher.cs
@@ -78,12 +78,19 @@ await _executor.Value.InvokeAsync(new DatabaseOperationBatch(_database, operatio
public async Task DrainAsync()
{
- _internalCancellation.Cancel();
+ try
+ {
+ _internalCancellation.Cancel();
- _batchingBlock.Complete();
- await _batchingBlock.Completion;
+ _batchingBlock.Complete();
+ await _batchingBlock.Completion;
- _executingBlock.Complete();
- await _executingBlock.Completion;
+ _executingBlock.Complete();
+ await _executingBlock.Completion;
+ }
+ catch (Exception e)
+ {
+ _logger.LogError(e, "Error trying to drain the current database batcher");
+ }
}
}
\ No newline at end of file
diff --git a/src/Wolverine/HostBuilderExtensions.cs b/src/Wolverine/HostBuilderExtensions.cs
index 91c09ab45..462168f64 100644
--- a/src/Wolverine/HostBuilderExtensions.cs
+++ b/src/Wolverine/HostBuilderExtensions.cs
@@ -378,6 +378,20 @@ public static IServiceCollection DisableAllExternalWolverineTransports(this ISer
}
#endregion
+
+ ///
+ /// Disable all Wolverine message persistence bootstrapping and durability agents. This
+ /// was built for the case of needing to run the application for OpenAPI generation when
+ /// the database might not be available
+ ///
+ ///
+ ///
+ public static IServiceCollection DisableAllWolverineMessagePersistence(this IServiceCollection services)
+ {
+ services.AddSingleton();
+ services.AddSingleton();
+ return services;
+ }
#region sample_DisableExternalTransports
@@ -391,6 +405,15 @@ public void Configure(WolverineOptions options)
#endregion
+ internal class DisablePersistence : IWolverineExtension
+ {
+ public void Configure(WolverineOptions options)
+ {
+ options.Durability.DurabilityMetricsEnabled = false;
+ options.Durability.DurabilityAgentEnabled = false;
+ }
+ }
+
///
/// Override the durability mode of Wolverine to be "Solo". This is valuable in automated
/// testing scenarios to make application activation and teardown faster and to bypass
diff --git a/src/Wolverine/Runtime/WolverineRuntime.HostService.cs b/src/Wolverine/Runtime/WolverineRuntime.HostService.cs
index e174b6bcc..4a395a914 100644
--- a/src/Wolverine/Runtime/WolverineRuntime.HostService.cs
+++ b/src/Wolverine/Runtime/WolverineRuntime.HostService.cs
@@ -25,9 +25,12 @@ public async Task StartAsync(CancellationToken cancellationToken)
await ApplyAsyncExtensions();
- foreach (var configuresRuntime in Options.Transports.OfType().ToArray())
+ if (!Options.ExternalTransportsAreStubbed)
{
- await configuresRuntime.ConfigureAsync(this);
+ foreach (var configuresRuntime in Options.Transports.OfType().ToArray())
+ {
+ await configuresRuntime.ConfigureAsync(this);
+ }
}
// Build up the message handlers