diff --git a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs index 3c7fc105a..aff7df81b 100644 --- a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs +++ b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs @@ -10,21 +10,21 @@ namespace Microsoft.AspNetCore.Hosting { public static class IWebHostExtensions { - public static bool IsInKubernetes(this IWebHost webHost) + public static bool IsInKubernetes(this IServiceProvider services) { - var cfg = webHost.Services.GetService(); + var cfg = services.GetService(); var orchestratorType = cfg.GetValue("OrchestratorType"); return orchestratorType?.ToUpper() == "K8S"; } - public static IWebHost MigrateDbContext(this IWebHost webHost, Action seeder) where TContext : DbContext + public static IServiceProvider MigrateDbContext(this IServiceProvider services, Action seeder) where TContext : DbContext { - var underK8s = webHost.IsInKubernetes(); + var underK8s = services.IsInKubernetes(); - using var scope = webHost.Services.CreateScope(); - var services = scope.ServiceProvider; - var logger = services.GetRequiredService>(); - var context = services.GetService(); + using var scope = services.CreateScope(); + var scopeServices = scope.ServiceProvider; + var logger = scopeServices.GetRequiredService>(); + var context = scopeServices.GetService(); try { @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Hosting if (underK8s) { - InvokeSeeder(seeder, context, services); + InvokeSeeder(seeder, context, scopeServices); } else { @@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Hosting //migration can't fail for network related exception. The retry options for DbContext only //apply to transient exceptions // Note that this is NOT applied when running some orchestrators (let the orchestrator to recreate the failing service) - retry.Execute(() => InvokeSeeder(seeder, context, services)); + retry.Execute(() => InvokeSeeder(seeder, context, scopeServices)); } logger.LogInformation("Migrated database associated with context {DbContextName}", typeof(TContext).Name); @@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Hosting } } - return webHost; + return services; } private static void InvokeSeeder(Action seeder, TContext context, IServiceProvider services) diff --git a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs index 06336c5aa..d763a336e 100644 --- a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs +++ b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs @@ -6,6 +6,12 @@ namespace Basket.FunctionalTests.Base; public class BasketScenarioBase : WebApplicationFactory { private const string ApiUrlBase = "api/v1/basket"; + + public TestServer CreateServer() + { + return Server; + } + public static class Get { public static string GetBasket(int id) diff --git a/src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj b/src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj index f7ccc5df6..d91ecd779 100644 --- a/src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj +++ b/src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj @@ -6,10 +6,6 @@ false - - - - PreserveNewest diff --git a/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs b/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs index 8726e6627..794ca7b1e 100644 --- a/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs +++ b/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs @@ -1,20 +1,15 @@ namespace Basket.FunctionalTests; -public class BasketScenarios : BasketScenarioBase +public class BasketScenarios : + BasketScenarioBase { - private readonly HttpClient _httpClient; - - public BasketScenarios() - { - _httpClient = CreateClient(); - } - [Fact] public async Task Post_basket_and_response_ok_status_code() { + using var server = CreateServer(); var content = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json"); var uri = "/api/v1/basket/"; - var response = await _httpClient.PostAsync(uri, content); + var response = await server.CreateClient().PostAsync(uri, content); response.EnsureSuccessStatusCode(); } @@ -22,7 +17,8 @@ public class BasketScenarios : BasketScenarioBase [Fact] public async Task Get_basket_and_response_ok_status_code() { - var response = await _httpClient + using var server = CreateServer(); + var response = await server.CreateClient() .GetAsync(Get.GetBasket(1)); response.EnsureSuccessStatusCode(); } @@ -30,9 +26,10 @@ public class BasketScenarios : BasketScenarioBase [Fact] public async Task Send_Checkout_basket_and_response_ok_status_code() { + using var server = CreateServer(); var contentBasket = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json"); - await _httpClient + await server.CreateClient() .PostAsync(Post.Basket, contentBasket); var contentCheckout = new StringContent(BuildCheckout(), UTF8Encoding.UTF8, "application/json") @@ -40,7 +37,7 @@ public class BasketScenarios : BasketScenarioBase Headers = { { "x-requestid", Guid.NewGuid().ToString() } } }; - var response = await _httpClient + var response = await server.CreateClient() .PostAsync(Post.CheckoutOrder, contentCheckout); response.EnsureSuccessStatusCode(); diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index 8e3e8aa50..0649ea2dc 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -331,7 +331,7 @@ static class CustomExtensionsMethods public static IServiceCollection AddCustomSwagger(this IServiceCollection services, IConfiguration configuration) { - services.AddSwaggerGen(options => + return services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo { @@ -339,6 +339,9 @@ static class CustomExtensionsMethods Version = "v1", Description = "The Ordering Service HTTP API" }); + + var identityUrl = configuration["IdentityUrlExternal"]; + options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, @@ -346,8 +349,8 @@ static class CustomExtensionsMethods { Implicit = new OpenApiOAuthFlow() { - AuthorizationUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize"), - TokenUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/token"), + AuthorizationUrl = new Uri($"{identityUrl}/connect/authorize"), + TokenUrl = new Uri($"{identityUrl}/connect/token"), Scopes = new Dictionary() { { "orders", "Ordering API" } @@ -355,9 +358,9 @@ static class CustomExtensionsMethods } } }); + options.OperationFilter(); }); - return services; } public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration) diff --git a/src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj b/src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj index 89f8910a2..f0b75f017 100644 --- a/src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj +++ b/src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj @@ -6,6 +6,12 @@ false + + + PreserveNewest + + + @@ -18,7 +24,6 @@ - diff --git a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs index a0b31568b..81832f32e 100644 --- a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs +++ b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs @@ -1,36 +1,42 @@ -namespace Ordering.FunctionalTests; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.Hosting; -public class OrderingScenarioBase +namespace Ordering.FunctionalTests; + +public class OrderingScenarioBase : WebApplicationFactory { public TestServer CreateServer() { - var path = Assembly.GetAssembly(typeof(OrderingScenarioBase)) - .Location; + Services.MigrateDbContext((context, services) => + { + var env = services.GetService(); + var settings = services.GetService>(); + var logger = services.GetService>(); - var hostBuilder = new WebHostBuilder() - .UseContentRoot(Path.GetDirectoryName(path)) - .ConfigureAppConfiguration(cb => - { - cb.AddJsonFile("appsettings.json", optional: false) - .AddEnvironmentVariables(); - }); + new OrderingContextSeed() + .SeedAsync(context, env, settings, logger) + .Wait(); + }) + .MigrateDbContext((_, __) => { }); + + return Server; + } - var testServer = new TestServer(hostBuilder); + protected override IHost CreateHost(IHostBuilder builder) + { + builder.ConfigureServices(servies => + { + servies.AddSingleton(); + }); - testServer.Host - .MigrateDbContext((context, services) => - { - var env = services.GetService(); - var settings = services.GetService>(); - var logger = services.GetService>(); + builder.ConfigureAppConfiguration(c => + { + var directory = Path.GetDirectoryName(typeof(OrderingScenarioBase).Assembly.Location)!; - new OrderingContextSeed() - .SeedAsync(context, env, settings, logger) - .Wait(); - }) - .MigrateDbContext((_, __) => { }); + c.AddJsonFile(Path.Combine(directory, "appsettings.json"), optional: false); + }); - return testServer; + return base.CreateHost(builder); } public static class Get @@ -48,4 +54,17 @@ public class OrderingScenarioBase public static string CancelOrder = "api/v1/orders/cancel"; public static string ShipOrder = "api/v1/orders/ship"; } + + private class AuthStartupFilter : IStartupFilter + { + public Action Configure(Action next) + { + return app => + { + app.UseMiddleware(); + + next(app); + }; + } + } } diff --git a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs index 252cc02ff..4ed21ba1b 100644 --- a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs +++ b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs @@ -1,7 +1,6 @@ using System.Net; using System.Text; using System.Text.Json; -using WebMVC.Services.ModelDTOs; using Xunit; namespace Ordering.FunctionalTests @@ -16,6 +15,7 @@ namespace Ordering.FunctionalTests var response = await server.CreateClient() .GetAsync(Get.Orders); + var s = await response.Content.ReadAsStringAsync(); response.EnsureSuccessStatusCode(); } @@ -49,7 +49,7 @@ namespace Ordering.FunctionalTests string BuildOrder() { - var order = new OrderDTO() + var order = new { OrderNumber = "-1" };