diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs index 5afe775681..0291efbfd0 100644 --- a/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs +++ b/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs @@ -11,7 +11,6 @@ using Infrastructure.DomainEvents; using Infrastructure.WebApi; using Microsoft.AspNetCore.Builder; - using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -19,7 +18,6 @@ using NServiceBus; using NServiceBus.AcceptanceTesting; using NServiceBus.AcceptanceTesting.Support; - using NServiceBus.Configuration.AdvancedExtensibility; using Particular.ServiceControl; using Particular.ServiceControl.Hosting; using RavenDB.Shared; @@ -118,6 +116,7 @@ async Task InitializeServiceControl(ScenarioContext context) EnvironmentName = Environments.Development }); hostBuilder.AddServiceControl(settings, configuration, loggingSettings); + hostBuilder.AddServiceControlApi(); hostBuilder.AddServiceControlTesting(settings); diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs b/src/ServiceControl.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs index 5660b837a3..8455a2dd3b 100644 --- a/src/ServiceControl.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs +++ b/src/ServiceControl.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs @@ -23,11 +23,8 @@ public static void AddServiceControlTesting(this WebApplicationBuilder hostBuild // This facilitates receiving the test server anywhere where DI is available hostBuilder.Services.AddSingleton(provider => (TestServer)provider.GetRequiredService()); - // By default, ASP.NET Core uses the entry point assembly to discover controllers. When running - // inside a test runner the runner exe becomes the entry point which obviously has no controllers in it ;) - // so we are explicitly registering all necessary application parts. + // For acceptance testing purposes we are adding more controllers to the host var addControllers = hostBuilder.Services.AddControllers(); - addControllers.AddApplicationPart(typeof(Settings).Assembly); addControllers.AddApplicationPart(typeof(AcceptanceTest).Assembly); hostBuilder.Services.AddHttpClientDefaultsOverrides(settings); diff --git a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs index 5f242d4fab..453754ec52 100644 --- a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs +++ b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs @@ -9,21 +9,16 @@ namespace ServiceControl.Audit.AcceptanceTests.TestSupport using System.Threading; using System.Threading.Tasks; using AcceptanceTesting; - using Auditing; - using Infrastructure; using Infrastructure.Hosting; using Infrastructure.Hosting.Commands; using Infrastructure.Settings; using Infrastructure.WebApi; using Microsoft.AspNetCore.Builder; - using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.TestHost; - using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using NServiceBus; using NServiceBus.AcceptanceTesting; using NServiceBus.AcceptanceTesting.Support; - using NServiceBus.Configuration.AdvancedExtensibility; public class ServiceControlComponentRunner( ITransportIntegration transportToUse, @@ -129,6 +124,8 @@ async Task InitializeServiceControl(ScenarioContext context) return criticalErrorContext.Stop(cancellationToken); }, settings, configuration, loggingSettings); + hostBuilder.AddServiceControlAuditApi(); + hostBuilder.AddServiceControlAuditTesting(settings); hostBuilderCustomization(hostBuilder); diff --git a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs index da69c2d069..8fb87a9f57 100644 --- a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs +++ b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs @@ -1,9 +1,7 @@ namespace ServiceControl.Audit.AcceptanceTests.TestSupport; using System; -using Auditing; using Infrastructure.Settings; -using Infrastructure.WebApi; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.TestHost; @@ -21,11 +19,8 @@ public static void AddServiceControlAuditTesting(this WebApplicationBuilder host // This facilitates receiving the test server anywhere where DI is available hostBuilder.Services.AddSingleton(provider => (TestServer)provider.GetRequiredService()); - // By default, ASP.NET Core uses the entry point assembly to discover controllers. When running - // inside a test runner the runner exe becomes the entry point which obviously has no controllers in it ;) - // so we are explicitly registering all necessary application parts. + // For acceptance testing purposes we are adding more controllers to the host var addControllers = hostBuilder.Services.AddControllers(); - addControllers.AddApplicationPart(typeof(Settings).Assembly); addControllers.AddApplicationPart(typeof(AcceptanceTest).Assembly); } } \ No newline at end of file diff --git a/src/ServiceControl.Audit/WebApplicationBuilderExtension.cs b/src/ServiceControl.Audit/HostApplicationBuilderEtensions.cs similarity index 93% rename from src/ServiceControl.Audit/WebApplicationBuilderExtension.cs rename to src/ServiceControl.Audit/HostApplicationBuilderEtensions.cs index f297ae4d74..8c24149157 100644 --- a/src/ServiceControl.Audit/WebApplicationBuilderExtension.cs +++ b/src/ServiceControl.Audit/HostApplicationBuilderEtensions.cs @@ -24,9 +24,9 @@ namespace ServiceControl.Audit; using Persistence; using Transports; -static class WebApplicationBuilderExtension +static class HostApplicationBuilderEtensions { - public static void AddServiceControlAudit(this WebApplicationBuilder builder, + public static void AddServiceControlAudit(this IHostApplicationBuilder builder, Func onCriticalError, Settings settings, EndpointConfiguration configuration, @@ -90,8 +90,6 @@ static class WebApplicationBuilderExtension services.AddHostedService(); } - builder.AddWebApi(settings.RootUrl); - builder.Services.AddWindowsService(); } @@ -108,7 +106,7 @@ static TransportSettings MapSettings(Settings settings) static void RecordStartup(Settings settings, LoggingSettings loggingSettings, EndpointConfiguration endpointConfiguration, IPersistenceConfiguration persistenceConfiguration) { - var version = FileVersionInfo.GetVersionInfo(typeof(WebApplicationBuilderExtension).Assembly.Location).ProductVersion; + var version = FileVersionInfo.GetVersionInfo(typeof(HostApplicationBuilderEtensions).Assembly.Location).ProductVersion; var startupMessage = $@" ------------------------------------------------------------- @@ -121,7 +119,7 @@ static void RecordStartup(Settings settings, LoggingSettings loggingSettings, En Persistence: {persistenceConfiguration.Name} -------------------------------------------------------------"; - var logger = LogManager.GetLogger(typeof(WebApplicationBuilderExtension)); + var logger = LogManager.GetLogger(typeof(HostApplicationBuilderEtensions)); logger.Info(startupMessage); endpointConfiguration.GetSettings().AddStartupDiagnosticsSection("Startup", new { diff --git a/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/ImportFailedAuditsCommand.cs b/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/ImportFailedAuditsCommand.cs index 6225f54480..c80ecf579f 100644 --- a/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/ImportFailedAuditsCommand.cs +++ b/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/ImportFailedAuditsCommand.cs @@ -4,8 +4,8 @@ using System.Threading; using System.Threading.Tasks; using Auditing; - using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; using NLog; using NServiceBus; using Settings; @@ -21,8 +21,7 @@ public override async Task Execute(HostArguments args, Settings settings) using var tokenSource = new CancellationTokenSource(); - // TODO: Ideally we would never want to actually bootstrap the web api. Figure out how - var hostBuilder = WebApplication.CreateBuilder(); + var hostBuilder = Host.CreateApplicationBuilder(); hostBuilder.AddServiceControlAudit((_, __) => { tokenSource.Cancel(); @@ -30,7 +29,6 @@ public override async Task Execute(HostArguments args, Settings settings) }, settings, endpointConfiguration, loggingSettings); using var app = hostBuilder.Build(); - app.UseServiceControlAudit(); await app.StartAsync(tokenSource.Token); var importer = app.Services.GetRequiredService(); diff --git a/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/RunCommand.cs b/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/RunCommand.cs index 373ed0d659..e7275213df 100644 --- a/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/RunCommand.cs +++ b/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/RunCommand.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Builder; using NServiceBus; using Settings; + using WebApi; class RunCommand : AbstractCommand { @@ -21,10 +22,11 @@ public override async Task Execute(HostArguments args, Settings settings) //Do nothing. The transports in NSB 8 are designed to handle broker outages. Audit ingestion will be paused when broker is unavailable. return Task.CompletedTask; }, settings, endpointConfiguration, loggingSettings); + hostBuilder.AddServiceControlAuditApi(); var app = hostBuilder.Build(); app.UseServiceControlAudit(); - await app.RunAsync(); + await app.RunAsync(settings.RootUrl); } } } \ No newline at end of file diff --git a/src/ServiceControl.Audit/Infrastructure/WebApi/WebApplicationBuilderExtensions.cs b/src/ServiceControl.Audit/Infrastructure/WebApi/HostApplicationBuilderExtensions.cs similarity index 78% rename from src/ServiceControl.Audit/Infrastructure/WebApi/WebApplicationBuilderExtensions.cs rename to src/ServiceControl.Audit/Infrastructure/WebApi/HostApplicationBuilderExtensions.cs index c29674b888..4eaa203c64 100644 --- a/src/ServiceControl.Audit/Infrastructure/WebApi/WebApplicationBuilderExtensions.cs +++ b/src/ServiceControl.Audit/Infrastructure/WebApi/HostApplicationBuilderExtensions.cs @@ -1,15 +1,14 @@ namespace ServiceControl.Audit.Infrastructure.WebApi { + using System.Reflection; using Microsoft.AspNetCore.Builder; - using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; - static class WebApplicationBuilderExtensions + static class HostApplicationBuilderExtensions { - public static void AddWebApi(this WebApplicationBuilder builder, string rootUrl) + public static void AddServiceControlAuditApi(this IHostApplicationBuilder builder) { - builder.WebHost.UseUrls(rootUrl); - builder.Services.AddCors(options => options.AddDefaultPolicy(Cors.GetDefaultPolicy())); // We're not explicitly adding Gzip here because it's already in the default list of supported compressors @@ -23,6 +22,7 @@ public static void AddWebApi(this WebApplicationBuilder builder, string rootUrl) options.ModelBinderProviders.Insert(0, new PagingInfoModelBindingProvider()); options.ModelBinderProviders.Insert(0, new SortInfoModelBindingProvider()); }); + controllers.AddApplicationPart(Assembly.GetExecutingAssembly()); controllers.AddJsonOptions(options => options.JsonSerializerOptions.CustomizeDefaults()); } } diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs index 751a5cad7b..ced2115f9d 100644 --- a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs +++ b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs @@ -8,8 +8,8 @@ namespace ServiceControl.Monitoring.AcceptanceTests.TestSupport using System.Threading.Tasks; using AcceptanceTesting; using Infrastructure; + using Infrastructure.WebApi; using Microsoft.AspNetCore.Builder; - using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -17,7 +17,6 @@ namespace ServiceControl.Monitoring.AcceptanceTests.TestSupport using NServiceBus; using NServiceBus.AcceptanceTesting; using NServiceBus.AcceptanceTesting.Support; - using NServiceBus.Configuration.AdvancedExtensibility; using NServiceBus.Logging; class ServiceControlComponentRunner( @@ -106,6 +105,7 @@ async Task InitializeServiceControl(ScenarioContext context) context.Logs.Enqueue(logitem); return criticalErrorContext.Stop(cancellationToken); }, settings, configuration); + hostBuilder.AddServiceControlMonitoringApi(); hostBuilder.AddServiceControlMonitoringTesting(settings); diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs index 925156a0bb..22e2108d72 100644 --- a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs +++ b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs @@ -18,11 +18,8 @@ public static void AddServiceControlMonitoringTesting(this WebApplicationBuilder hostBuilder.Services.AddKeyedSingleton(settings.EndpointName, (provider, _) => (TestServer)provider.GetRequiredService()); - // By default, ASP.NET Core uses the entry point assembly to discover controllers. When running - // inside a test runner the runner exe becomes the entry point which obviously has no controllers in it ;) - // so we are explicitly registering all necessary application parts. + // // For acceptance testing purposes we are adding more controllers to the host var addControllers = hostBuilder.Services.AddControllers(); - addControllers.AddApplicationPart(typeof(Settings).Assembly); addControllers.AddApplicationPart(typeof(AcceptanceTest).Assembly); } } \ No newline at end of file diff --git a/src/ServiceControl.Monitoring/WebApplicationBuilderExtensions.cs b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs similarity index 89% rename from src/ServiceControl.Monitoring/WebApplicationBuilderExtensions.cs rename to src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs index 223fdb5908..f263eb8363 100644 --- a/src/ServiceControl.Monitoring/WebApplicationBuilderExtensions.cs +++ b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs @@ -6,11 +6,8 @@ namespace ServiceControl.Monitoring; using System.Threading.Tasks; using Infrastructure; using Infrastructure.Extensions; -using Infrastructure.WebApi; using Licensing; using Messaging; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpLogging; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -24,9 +21,9 @@ namespace ServiceControl.Monitoring; using Timings; using Transports; -public static class WebApplicationBuilderExtensions +public static class HostApplicationBuilderExtensions { - public static void AddServiceControlMonitoring(this WebApplicationBuilder hostBuilder, + public static void AddServiceControlMonitoring(this IHostApplicationBuilder hostBuilder, Func onCriticalError, Settings settings, EndpointConfiguration endpointConfiguration) { @@ -56,7 +53,9 @@ public static class WebApplicationBuilderExtensions services.AddHttpLogging(options => { - options.LoggingFields = HttpLoggingFields.RequestPath | HttpLoggingFields.RequestMethod | HttpLoggingFields.ResponseStatusCode | HttpLoggingFields.Duration; + // TODO Do we need to expose the host? + // we could also include the time it took to process the request + options.LoggingFields = HttpLoggingFields.RequestPath | HttpLoggingFields.RequestMethod | HttpLoggingFields.ResponseStatusCode; }); // Core registers the message dispatcher to be resolved from the transport seam. The dispatcher @@ -67,15 +66,6 @@ public static class WebApplicationBuilderExtensions ConfigureEndpoint(endpointConfiguration, onCriticalError, transportCustomization, settings); hostBuilder.UseNServiceBus(endpointConfiguration); - - // We also don't do this in the primary instance - hostBuilder.WebHost.UseUrls(settings.RootUrl); - var controllers = hostBuilder.Services.AddControllers(options => - { - options.Filters.Add(); - options.Filters.Add(); - }); - controllers.AddJsonOptions(options => options.JsonSerializerOptions.CustomizeDefaults()); } internal static void ConfigureEndpoint(EndpointConfiguration config, Func onCriticalError, ITransportCustomization transportCustomization, Settings settings) diff --git a/src/ServiceControl.Monitoring/Hosting/Commands/RunCommand.cs b/src/ServiceControl.Monitoring/Hosting/Commands/RunCommand.cs index ec4c96684e..9900f0eaaa 100644 --- a/src/ServiceControl.Monitoring/Hosting/Commands/RunCommand.cs +++ b/src/ServiceControl.Monitoring/Hosting/Commands/RunCommand.cs @@ -2,6 +2,7 @@ namespace ServiceControl.Monitoring { using System.Threading.Tasks; using Infrastructure; + using Infrastructure.WebApi; using Microsoft.AspNetCore.Builder; using NServiceBus; @@ -13,10 +14,11 @@ public override async Task Execute(Settings settings) var hostBuilder = WebApplication.CreateBuilder(); hostBuilder.AddServiceControlMonitoring((_, __) => Task.CompletedTask, settings, endpointConfiguration); + hostBuilder.AddServiceControlMonitoringApi(); var app = hostBuilder.Build(); app.UseServiceControlMonitoring(); - await app.RunAsync(); + await app.RunAsync(settings.RootUrl); } } } \ No newline at end of file diff --git a/src/ServiceControl.Monitoring/Infrastructure/WebApi/HostApplicationBuilderExtensions.cs b/src/ServiceControl.Monitoring/Infrastructure/WebApi/HostApplicationBuilderExtensions.cs new file mode 100644 index 0000000000..d0dd094ce9 --- /dev/null +++ b/src/ServiceControl.Monitoring/Infrastructure/WebApi/HostApplicationBuilderExtensions.cs @@ -0,0 +1,19 @@ +namespace ServiceControl.Monitoring.Infrastructure.WebApi; + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Infrastructure; + +public static class HostApplicationBuilderExtensions +{ + public static void AddServiceControlMonitoringApi(this IHostApplicationBuilder hostBuilder) + { + var controllers = hostBuilder.Services.AddControllers(options => + { + options.Filters.Add(); + options.Filters.Add(); + }); + controllers.AddApplicationPart(typeof(Settings).Assembly); + controllers.AddJsonOptions(options => options.JsonSerializerOptions.CustomizeDefaults()); + } +} \ No newline at end of file diff --git a/src/ServiceControl.Persistence.Tests.RavenDB/RavenPersistedTypes.cs b/src/ServiceControl.Persistence.Tests.RavenDB/RavenPersistedTypes.cs index 873d9e288d..6329f03739 100644 --- a/src/ServiceControl.Persistence.Tests.RavenDB/RavenPersistedTypes.cs +++ b/src/ServiceControl.Persistence.Tests.RavenDB/RavenPersistedTypes.cs @@ -4,8 +4,8 @@ using System.Linq; using NUnit.Framework; using Particular.Approvals; - using Particular.ServiceControl; using Raven.Client.Documents.Indexes; + using ServiceBus.Management.Infrastructure.Settings; using ServiceControl.Persistence; class RavenPersistedTypes @@ -13,7 +13,7 @@ class RavenPersistedTypes [Test] public void Verify() { - var allTypes = typeof(WebApplicationBuilderExtension).Assembly.GetTypes().Concat(typeof(RavenQueryExtensions).Assembly.GetTypes()).Concat(typeof(EndpointsView).Assembly.GetTypes()); + var allTypes = typeof(Settings).Assembly.GetTypes().Concat(typeof(RavenQueryExtensions).Assembly.GetTypes()).Concat(typeof(EndpointsView).Assembly.GetTypes()); var documentTypes = allTypes .Where(type => typeof(AbstractIndexCreationTask).IsAssignableFrom(type)) diff --git a/src/ServiceControl.UnitTests/API/APIApprovals.cs b/src/ServiceControl.UnitTests/API/APIApprovals.cs index 610cd97e02..c4b20c7467 100644 --- a/src/ServiceControl.UnitTests/API/APIApprovals.cs +++ b/src/ServiceControl.UnitTests/API/APIApprovals.cs @@ -178,7 +178,7 @@ static IEnumerable GetCustomChecks() { var settings = (object)new Settings(); - var serviceControlTypes = typeof(WebApplicationBuilderExtension).Assembly + var serviceControlTypes = typeof(Settings).Assembly .GetTypes() .Where(t => t.IsAbstract == false); diff --git a/src/ServiceControl.UnitTests/EventHierarchy.cs b/src/ServiceControl.UnitTests/EventHierarchy.cs index e44a211a9f..f50526539e 100644 --- a/src/ServiceControl.UnitTests/EventHierarchy.cs +++ b/src/ServiceControl.UnitTests/EventHierarchy.cs @@ -3,7 +3,7 @@ using System.Linq; using NServiceBus; using NUnit.Framework; - using Particular.ServiceControl; + using ServiceBus.Management.Infrastructure.Settings; [TestFixture] class EventHierarchy @@ -11,13 +11,14 @@ class EventHierarchy [TestCase] public void EnsureEventHierarchyIsFlat() { - var serviceControlAssembly = typeof(WebApplicationBuilderExtension).Assembly; + var serviceControlAssembly = typeof(Settings).Assembly; var eventTypes = serviceControlAssembly.GetTypes().Where(typeof(IEvent).IsAssignableFrom).Where(x => !x.IsAbstract).ToArray(); var flatEvents = eventTypes.Where(t => t.BaseType == typeof(object)).ToArray(); var nonFlatEvents = eventTypes.Except(flatEvents).ToArray(); + Assert.IsNotEmpty(eventTypes); Assert.IsEmpty(nonFlatEvents, "Complex Event Hierarchy causes duplicate event handling with Azure ServiceBus and SubscribeToOwnEvents"); } } diff --git a/src/ServiceControl/WebApplicationBuilderExtension.cs b/src/ServiceControl/HostApplicationBuilderExtensions.cs similarity index 93% rename from src/ServiceControl/WebApplicationBuilderExtension.cs rename to src/ServiceControl/HostApplicationBuilderExtensions.cs index c02e3b7756..36745c09c1 100644 --- a/src/ServiceControl/WebApplicationBuilderExtension.cs +++ b/src/ServiceControl/HostApplicationBuilderExtensions.cs @@ -32,9 +32,9 @@ namespace Particular.ServiceControl using ServiceBus.Management.Infrastructure.Installers; using ServiceBus.Management.Infrastructure.Settings; - static class WebApplicationBuilderExtension + static class HostApplicationBuilderExtensions { - public static void AddServiceControl(this WebApplicationBuilder hostBuilder, Settings settings, EndpointConfiguration configuration, LoggingSettings loggingSettings) + public static void AddServiceControl(this IHostApplicationBuilder hostBuilder, Settings settings, EndpointConfiguration configuration, LoggingSettings loggingSettings) { ArgumentNullException.ThrowIfNull(configuration); @@ -101,8 +101,6 @@ public static void AddServiceControl(this WebApplicationBuilder hostBuilder, Set hostBuilder.AddExternalIntegrationEvents(); } - hostBuilder.AddWebApi([Assembly.GetExecutingAssembly()], settings.RootUrl); - hostBuilder.AddServicePulseSignalRNotifier(); hostBuilder.AddEmailNotifications(); hostBuilder.AddAsyncTimer(); @@ -141,7 +139,7 @@ static TransportSettings MapSettings(Settings settings) static void RecordStartup(Settings settings, LoggingSettings loggingSettings, EndpointConfiguration endpointConfiguration) { - var version = FileVersionInfo.GetVersionInfo(typeof(WebApplicationBuilderExtension).Assembly.Location).ProductVersion; + var version = FileVersionInfo.GetVersionInfo(typeof(HostApplicationBuilderExtensions).Assembly.Location).ProductVersion; var startupMessage = $@" ------------------------------------------------------------- @@ -154,7 +152,7 @@ static void RecordStartup(Settings settings, LoggingSettings loggingSettings, En Selected Transport Customization: {settings.TransportType} -------------------------------------------------------------"; - var logger = LogManager.GetLogger(typeof(WebApplicationBuilderExtension)); + var logger = LogManager.GetLogger(typeof(HostApplicationBuilderExtensions)); logger.Info(startupMessage); endpointConfiguration.GetSettings().AddStartupDiagnosticsSection("Startup", new { diff --git a/src/ServiceControl/Hosting/Commands/ImportFailedErrorsCommand.cs b/src/ServiceControl/Hosting/Commands/ImportFailedErrorsCommand.cs index 4bf8e9e973..e27df6b8a5 100644 --- a/src/ServiceControl/Hosting/Commands/ImportFailedErrorsCommand.cs +++ b/src/ServiceControl/Hosting/Commands/ImportFailedErrorsCommand.cs @@ -3,8 +3,8 @@ using System; using System.Threading; using System.Threading.Tasks; - using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; using NLog; using NServiceBus; using Operations; @@ -24,12 +24,10 @@ public override async Task Execute(HostArguments args, Settings settings) var loggingSettings = new LoggingSettings(settings.ServiceName, LogLevel.Info); - // TODO: Ideally we would never want to actually bootstrap the web api. Figure out how - var hostBuilder = WebApplication.CreateBuilder(); + var hostBuilder = Host.CreateApplicationBuilder(); hostBuilder.AddServiceControl(settings, endpointConfiguration, loggingSettings); using var app = hostBuilder.Build(); - app.UseServiceControl(); await app.StartAsync(); var importFailedErrors = app.Services.GetRequiredService(); diff --git a/src/ServiceControl/Hosting/Commands/RunCommand.cs b/src/ServiceControl/Hosting/Commands/RunCommand.cs index 509a17a989..570c67383c 100644 --- a/src/ServiceControl/Hosting/Commands/RunCommand.cs +++ b/src/ServiceControl/Hosting/Commands/RunCommand.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Hosting.Commands { using System.Threading.Tasks; + using Infrastructure.WebApi; using Microsoft.AspNetCore.Builder; using NServiceBus; using Particular.ServiceControl; @@ -22,10 +23,11 @@ public override async Task Execute(HostArguments args, Settings settings) var hostBuilder = WebApplication.CreateBuilder(); hostBuilder.AddServiceControl(settings, endpointConfiguration, loggingSettings); + hostBuilder.AddServiceControlApi(); var app = hostBuilder.Build(); app.UseServiceControl(); - await app.RunAsync(); + await app.RunAsync(settings.RootUrl); } } } diff --git a/src/ServiceControl/Infrastructure/WebApi/WebApiHostBuilderExtensions.cs b/src/ServiceControl/Infrastructure/WebApi/HostApplicationBuilderExtensions.cs similarity index 75% rename from src/ServiceControl/Infrastructure/WebApi/WebApiHostBuilderExtensions.cs rename to src/ServiceControl/Infrastructure/WebApi/HostApplicationBuilderExtensions.cs index e18ea6d4d0..75e3c22bf7 100644 --- a/src/ServiceControl/Infrastructure/WebApi/WebApiHostBuilderExtensions.cs +++ b/src/ServiceControl/Infrastructure/WebApi/HostApplicationBuilderExtensions.cs @@ -1,26 +1,20 @@ namespace ServiceControl.Infrastructure.WebApi { - using System.Collections.Generic; using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Builder; - using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; + using Microsoft.Extensions.Hosting; using ServiceControl.CompositeViews.Messages; - static class WebApiHostBuilderExtensions + static class HostApplicationBuilderExtensions { - public static void AddWebApi(this WebApplicationBuilder builder, List apiAssemblies, string rootUrl) + public static void AddServiceControlApi(this IHostApplicationBuilder builder) { - builder.WebHost.UseUrls(rootUrl); - - foreach (var apiAssembly in apiAssemblies) - { - // This registers concrete classes that implement IApi. Currently it is hard to find out to what - // component those APIs should belong to so we leave it here for now. - builder.Services.RegisterApiTypes(apiAssembly); - } + // This registers concrete classes that implement IApi. Currently it is hard to find out to what + // component those APIs should belong to so we leave it here for now. + builder.Services.RegisterApiTypes(Assembly.GetExecutingAssembly()); builder.Services.AddCors(options => options.AddDefaultPolicy(Cors.GetDefaultPolicy())); @@ -35,6 +29,7 @@ public static void AddWebApi(this WebApplicationBuilder builder, List options.ModelBinderProviders.Insert(0, new PagingInfoModelBindingProvider()); options.ModelBinderProviders.Insert(0, new SortInfoModelBindingProvider()); }); + controllers.AddApplicationPart(Assembly.GetExecutingAssembly()); controllers.AddJsonOptions(options => options.JsonSerializerOptions.CustomizeDefaults()); var signalR = builder.Services.AddSignalR();