From 3abc982676d4696a560939d27d0207c730cfadaf Mon Sep 17 00:00:00 2001 From: Rob Foulkrod Date: Wed, 13 Mar 2024 11:34:32 -0400 Subject: [PATCH 1/4] Reapplying code changes for Dynamic AppConfig Lab --- .vscode/settings.json | 4 +++ Directory.Packages.props | 3 +++ src/Web/Pages/Index.cshtml | 6 +++-- src/Web/Pages/Index.cshtml.cs | 5 +++- src/Web/Pages/_ViewImports.cshtml | 1 + src/Web/Program.cs | 37 ++++++++++++++++++++++++++ src/Web/Properties/launchSettings.json | 5 +++- src/Web/Web.csproj | 8 +++--- src/Web/appsettings.json | 12 +++++++-- 9 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..5a8609f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "appService.defaultWebAppToDeploy": "/subscriptions/48640fa2-e257-4a45-a974-878a933075d5/resourceGroups/AZ400-EWebShop/providers/Microsoft.Web/sites/az400-webapp-rrf", + "appService.deploySubpath": "src\\Web" +} \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props index 9f9a205..7b3e48a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -38,7 +38,10 @@ + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Web/Pages/Index.cshtml b/src/Web/Pages/Index.cshtml index e90def0..cc07e69 100644 --- a/src/Web/Pages/Index.cshtml +++ b/src/Web/Pages/Index.cshtml @@ -5,7 +5,9 @@ }
- + + +
@@ -39,7 +41,7 @@ else {
- THERE ARE NO RESULTS THAT MATCH YOUR SEARCH + @Model.SettingsModel.NoResultsMessage
} diff --git a/src/Web/Pages/Index.cshtml.cs b/src/Web/Pages/Index.cshtml.cs index f41ba30..701a301 100644 --- a/src/Web/Pages/Index.cshtml.cs +++ b/src/Web/Pages/Index.cshtml.cs @@ -1,16 +1,19 @@ using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.eShopWeb.Web.Services; using Microsoft.eShopWeb.Web.ViewModels; +using Microsoft.Extensions.Options; namespace Microsoft.eShopWeb.Web.Pages; public class IndexModel : PageModel { private readonly ICatalogViewModelService _catalogViewModelService; + public SettingsViewModel SettingsModel { get; } - public IndexModel(ICatalogViewModelService catalogViewModelService) + public IndexModel(ICatalogViewModelService catalogViewModelService, IOptionsSnapshot options) { _catalogViewModelService = catalogViewModelService; + SettingsModel = options.Value; } public required CatalogIndexViewModel CatalogModel { get; set; } = new CatalogIndexViewModel(); diff --git a/src/Web/Pages/_ViewImports.cshtml b/src/Web/Pages/_ViewImports.cshtml index 2bf31ee..d85ca5f 100644 --- a/src/Web/Pages/_ViewImports.cshtml +++ b/src/Web/Pages/_ViewImports.cshtml @@ -7,3 +7,4 @@ @using Microsoft.eShopWeb.Infrastructure.Identity @namespace Microsoft.eShopWeb.Web.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, Microsoft.FeatureManagement.AspNetCore diff --git a/src/Web/Program.cs b/src/Web/Program.cs index 9761361..6207b78 100644 --- a/src/Web/Program.cs +++ b/src/Web/Program.cs @@ -18,6 +18,10 @@ using Microsoft.eShopWeb.Web.Configuration; using Microsoft.eShopWeb.Web.HealthChecks; using Microsoft.Extensions.Diagnostics.HealthChecks; +using Azure.Identity; +using Microsoft.eShopWeb.Web.Pages; +using Microsoft.FeatureManagement; +using Microsoft.IdentityModel.Tokens; var builder = WebApplication.CreateBuilder(args); builder.Logging.AddConsole(); @@ -93,6 +97,33 @@ config.Path = "/allservices"; }); +// Bind configuration "eShopWeb:Settings" section to the Settings object +builder.Services.Configure(builder.Configuration.GetSection("eShopWeb:Settings")); +// Initialize useAppConfig parameter +var useAppConfig = false; +Boolean.TryParse(builder.Configuration["UseAppConfig"], out useAppConfig); +// Add Azure App Configuration middleware to the container of services. +builder.Services.AddAzureAppConfiguration(); +builder.Services.AddFeatureManagement(); +// Load configuration from Azure App Configuration +if (useAppConfig) +{ + builder.Configuration.AddAzureAppConfiguration(options => + { + options.Connect(new Uri(builder.Configuration["AppConfigEndpoint"]), new DefaultAzureCredential()) + .ConfigureRefresh(refresh => + { + // Default cache expiration is 30 seconds + refresh.Register("eShopWeb:Settings:NoResultsMessage").SetCacheExpiration(TimeSpan.FromSeconds(10)); + }) + .UseFeatureFlags(featureFlagOptions => + { + // Default cache expiration is 30 seconds + featureFlagOptions.CacheExpirationInterval = TimeSpan.FromSeconds(10); + }); + }); +} + // blazor configuration var configSection = builder.Configuration.GetRequiredSection(BaseUrlConfiguration.CONFIG_NAME); builder.Services.Configure(configSection); @@ -115,6 +146,12 @@ var app = builder.Build(); +if (useAppConfig) +{ + // Use Azure App Configuration middleware for dynamic configuration refresh. + app.UseAzureAppConfiguration(); +} + app.Logger.LogInformation("App created..."); app.Logger.LogInformation("Seeding Database..."); diff --git a/src/Web/Properties/launchSettings.json b/src/Web/Properties/launchSettings.json index 4dfb1e9..edbd81b 100644 --- a/src/Web/Properties/launchSettings.json +++ b/src/Web/Properties/launchSettings.json @@ -22,7 +22,10 @@ "launchBrowser": true, "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + "AZURE_TENANT_ID": "{azure-tenant-id}", + "AZURE_CLIENT_ID": "{azure-client-id}", + "AZURE_CLIENT_SECRET": "{azure-client-secret}" }, "applicationUrl": "https://localhost:5001;http://localhost:5000" }, diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index 6ed273b..0598e42 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -1,6 +1,6 @@  - + enable enable Microsoft.eShopWeb.Web @@ -29,11 +29,13 @@ + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + diff --git a/src/Web/appsettings.json b/src/Web/appsettings.json index c2bc659..95c8d9f 100644 --- a/src/Web/appsettings.json +++ b/src/Web/appsettings.json @@ -16,5 +16,13 @@ "System": "Warning" }, "AllowedHosts": "*" - } -} + }, + + "eShopWeb": { + "Settings": { + "NoResultsMessage": "THERE ARE NO RESULTS THAT MATCH YOUR SEARCH" + } + }, + "UseAppConfig": true, + "AppConfigEndpoint": "https://appcs-rrf-eastus.azconfig.io" +} \ No newline at end of file From 4db6a0a7654ea671d57f5c749055a21da225a9d3 Mon Sep 17 00:00:00 2001 From: Rob Foulkrod <89028299+rob-foulkrod@users.noreply.github.com> Date: Wed, 13 Mar 2024 11:40:23 -0400 Subject: [PATCH 2/4] Delete .vscode/settings.json --- .vscode/settings.json | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 5a8609f..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "appService.defaultWebAppToDeploy": "/subscriptions/48640fa2-e257-4a45-a974-878a933075d5/resourceGroups/AZ400-EWebShop/providers/Microsoft.Web/sites/az400-webapp-rrf", - "appService.deploySubpath": "src\\Web" -} \ No newline at end of file From 4fb34d802b39a6b2ba0ed1597fe0eeec604c9c3f Mon Sep 17 00:00:00 2001 From: Rob Foulkrod Date: Wed, 13 Mar 2024 12:22:34 -0400 Subject: [PATCH 3/4] Edit to remove compiler warnings from Program.cs --- src/Web/Program.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Web/Program.cs b/src/Web/Program.cs index 6207b78..7e37730 100644 --- a/src/Web/Program.cs +++ b/src/Web/Program.cs @@ -18,7 +18,6 @@ using Microsoft.eShopWeb.Web.Configuration; using Microsoft.eShopWeb.Web.HealthChecks; using Microsoft.Extensions.Diagnostics.HealthChecks; -using Azure.Identity; using Microsoft.eShopWeb.Web.Pages; using Microsoft.FeatureManagement; using Microsoft.IdentityModel.Tokens; @@ -26,11 +25,13 @@ var builder = WebApplication.CreateBuilder(args); builder.Logging.AddConsole(); -if (builder.Environment.IsDevelopment() || builder.Environment.EnvironmentName == "Docker"){ +if (builder.Environment.IsDevelopment() || builder.Environment.EnvironmentName == "Docker") +{ // Configure SQL Server (local) Microsoft.eShopWeb.Infrastructure.Dependencies.ConfigureServices(builder.Configuration, builder.Services); } -else{ +else +{ // Configure SQL Server (prod) var credential = new ChainedTokenCredential(new AzureDeveloperCliCredential(), new DefaultAzureCredential()); builder.Configuration.AddAzureKeyVault(new Uri(builder.Configuration["AZURE_KEY_VAULT_ENDPOINT"] ?? ""), credential); @@ -110,7 +111,14 @@ { builder.Configuration.AddAzureAppConfiguration(options => { - options.Connect(new Uri(builder.Configuration["AppConfigEndpoint"]), new DefaultAzureCredential()) + var appConfigEndpoint = builder.Configuration["AppConfigEndpoint"]; + + if (String.IsNullOrEmpty(appConfigEndpoint)) + { + throw new Exception("AppConfigEndpoint is not set in the configuration. Please set AppConfigEndpoint in the configuration."); + } + + options.Connect(new Uri(appConfigEndpoint), new DefaultAzureCredential()) .ConfigureRefresh(refresh => { // Default cache expiration is 30 seconds From 9906f9e9a9dd7b3e666993f5882204c5235bc014 Mon Sep 17 00:00:00 2001 From: Rob Foulkrod <89028299+rob-foulkrod@users.noreply.github.com> Date: Thu, 14 Mar 2024 19:41:28 -0400 Subject: [PATCH 4/4] Update appsettings.json to disable dynamic config by default --- src/Web/appsettings.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Web/appsettings.json b/src/Web/appsettings.json index 95c8d9f..9cf1fc4 100644 --- a/src/Web/appsettings.json +++ b/src/Web/appsettings.json @@ -23,6 +23,6 @@ "NoResultsMessage": "THERE ARE NO RESULTS THAT MATCH YOUR SEARCH" } }, - "UseAppConfig": true, - "AppConfigEndpoint": "https://appcs-rrf-eastus.azconfig.io" -} \ No newline at end of file + "UseAppConfig": false, + "AppConfigEndpoint": "" +}