diff --git a/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/end_to_end.cs b/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/end_to_end.cs index f00e28259..5eca04a66 100644 --- a/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/end_to_end.cs +++ b/src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/end_to_end.cs @@ -3,6 +3,7 @@ using JasperFx; using JasperFx.CommandLine.Descriptions; using JasperFx.Core; +using JasperFx.Core.Reflection; using Marten; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -77,6 +78,31 @@ public async Task rabbitmq_transport_is_exposed_as_a_resource() } } + [Fact] + public async Task find_endpoints_through_conventions_as_part_of_find_resources() + { + using var host = Host.CreateDefaultBuilder() + .UseWolverine(opts => + { + opts.ApplicationAssembly = GetType().Assembly; + opts.UseRabbitMq().UseConventionalRouting(); + }).Build(); + + var sources = host.Services.GetServices().OfType(); + foreach (var source in sources) + { + var resources = await source.FindResources(); + } + + var transport = host.GetRuntime().Options.Transports.GetOrCreate(); + transport.Exchanges.Contains(typeof(OM1).FullNameInCode()).ShouldBeTrue(); + transport.Exchanges.Contains(typeof(OM2).FullNameInCode()).ShouldBeTrue(); + transport.Exchanges.Contains(typeof(OM3).FullNameInCode()).ShouldBeTrue(); + transport.Exchanges.Contains(typeof(OM4).FullNameInCode()).ShouldBeTrue(); + } + + + [Fact] public async Task rabbitmq_transport_is_NOT_exposed_as_a_resource_if_external_transports_are_stubbed() { @@ -905,4 +931,9 @@ public static async Task HandleAsync(RequestColors message, IMessageBus bus) response.Color.ShouldBe(message.Colors[i]); } } -} \ No newline at end of file +} + +public record OM1 : IMessage; +public record OM2 : IMessage; +public record OM3 : IMessage; +public record OM4 : IMessage; \ No newline at end of file diff --git a/src/Wolverine/Transports/BrokerResource.cs b/src/Wolverine/Transports/BrokerResource.cs index faffd85ae..a2dac1ee4 100644 --- a/src/Wolverine/Transports/BrokerResource.cs +++ b/src/Wolverine/Transports/BrokerResource.cs @@ -3,6 +3,7 @@ using JasperFx.Resources; using Spectre.Console; using Spectre.Console.Rendering; +using Wolverine.Configuration; using Wolverine.Runtime; namespace Wolverine.Transports; @@ -28,7 +29,7 @@ public async Task Check(CancellationToken token) var missing = new List(); await _transport.ConnectAsync(_runtime); - foreach (var endpoint in _transport.Endpoints().OfType()) + foreach (var endpoint in _transport.Endpoints().OfType().Where(x => x.Role == EndpointRole.Application)) { try { diff --git a/src/Wolverine/Transports/IBrokerEndpoint.cs b/src/Wolverine/Transports/IBrokerEndpoint.cs index 44373aefa..b18cfc0a7 100644 --- a/src/Wolverine/Transports/IBrokerEndpoint.cs +++ b/src/Wolverine/Transports/IBrokerEndpoint.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.Logging; +using Wolverine.Configuration; namespace Wolverine.Transports; @@ -8,4 +9,9 @@ public interface IBrokerEndpoint ValueTask CheckAsync(); ValueTask TeardownAsync(ILogger logger); ValueTask SetupAsync(ILogger logger); + + /// + /// Is the endpoint controlled and configured by the application or Wolverine itself? + /// + public EndpointRole Role { get; } } \ No newline at end of file diff --git a/src/Wolverine/WolverineSystemPart.cs b/src/Wolverine/WolverineSystemPart.cs index 21af7569b..a2f3c9397 100644 --- a/src/Wolverine/WolverineSystemPart.cs +++ b/src/Wolverine/WolverineSystemPart.cs @@ -190,27 +190,47 @@ public void WriteErrorHandling() public override async ValueTask> FindResources() { - var list = new List(); - - // These have to run first. Right now, the only options are for building multi-tenanted - // databases with EF Core - list.AddRange(_runtime.Services.GetServices()); + WithinDescription = true; - if (!_runtime.Options.ExternalTransportsAreStubbed) + try { - foreach (var transport in _runtime.Options.Transports) + var list = new List(); + + // These have to run first. Right now, the only options are for building multi-tenanted + // databases with EF Core + list.AddRange(_runtime.Services.GetServices()); + + if (!_runtime.Options.ExternalTransportsAreStubbed) { - if (transport.TryBuildStatefulResource(_runtime, out var resource)) + foreach (var transport in _runtime.Options.Transports) + { + if (transport.TryBuildStatefulResource(_runtime, out var resource)) + { + await transport.InitializeAsync(_runtime); + list.Add(resource!); + } + } + + // Force Wolverine to find all message types... + var messageTypes = _runtime.Options.Discovery.FindAllMessages(_runtime.Options.HandlerGraph); + + // ...and force Wolverine to *also* execute the routing, which + // may discover new endpoints + foreach (var messageType in messageTypes.Where(x => x.Assembly != GetType().Assembly)) { - list.Add(resource!); + _runtime.RoutingFor(messageType); } } - } - var stores = await _runtime.Stores.FindAllAsync(); + var stores = await _runtime.Stores.FindAllAsync(); - list.AddRange(stores.Select(store => new MessageStoreResource(_runtime.Options, store))); + list.AddRange(stores.Select(store => new MessageStoreResource(_runtime.Options, store))); - return list; + return list; + } + finally + { + WithinDescription = false; + } } } \ No newline at end of file