Ce que j'essaie de faire: j'essaie de configurer Azure App Configuration avec une application Web .net core 2.1 mvc avec une clé sentinelle dans Azure App Configuration, dans le but de pouvoir changer les clés en azur et aucune des clés sera mis à jour dans mes applications jusqu'à ce que la valeur sentinelle ait changé. En théorie, cela devrait me permettre de procéder à des swaps à chaud en toute sécurité.
Quel est mon problème: lorsque je fais cela, aucune méthode WatchAndReloadAll () n'est disponible pour surveiller la sentinelle sur IWebHostBuilder, et les méthodes alternatives Refresh () ne semblent pas actualiser la configuration comme elles le disent.
Informations générales et ce que j'ai essayé: J'ai assisté à VS Live - San Diego, la semaine dernière et j'ai regardé une démo sur Azure App Configuration. J'ai eu quelques problèmes pour obtenir l'application pour actualiser les valeurs de configuration lors de l'implémentation, j'ai donc également référencé cette démo décrivant comment le faire également. La section pertinente se trouve à environ 10 minutes. Cependant, cette méthode ne semble pas être disponible sur IWebHostBuilder.
Documentation que je référence: Dans la documentation officielle il n'y a aucune référence à cette méthode voir doc quickstart .net core et doc dynamic configuration .net core
Mon environnement: utilisation de dot net core 2.1 en cours d'exécution à partir de Visual Studio Enterprise 2019, avec le dernier package de nuget d'aperçu pour Microsoft.Azure.AppConfiguration.AspNetCore 2.0.0-preview-010060003-1250
Mon code: dans la démo, ils ont créé un IWebHostBuilder via la méthode CreateWebHostBuilder (string [] args) comme ceci:
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
var settings = config.Build();
config.AddAzureAppConfiguration(options =>
{
options.Connect(settings["ConnectionStrings:AzureConfiguration"])
.Use(keyFilter: "TestApp:*")
.WatchAndReloadAll(key: "TestApp:Sentinel", pollInterval: TimeSpan.FromSeconds(5));
});
})
.UseStartup<Startup>();
}
Je l'ai également essayé de cette façon, en utilisant la documentation actuelle:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
var settings = config.Build();
config.AddAzureAppConfiguration(options =>
{
// fetch connection string from local config. Could use KeyVault, or Secrets as well.
options.Connect(settings["ConnectionStrings:AzureConfiguration"])
// filter configs so we are only searching against configs that meet this pattern
.Use(keyFilter: "WebApp:*")
.ConfigureRefresh(refreshOptions =>
{
// In theory, when this value changes, on the next refresh operation, the config will update all modified configs since it was last refreshed.
refreshOptions.Register("WebApp:Sentinel", true);
refreshOptions.Register("WebApp:Settings:BackgroundColor", false);
refreshOptions.Register("WebApp:Settings:FontColor", false);
refreshOptions.Register("WebApp:Settings:FontSize", false);
refreshOptions.Register("WebApp:Settings:Message", false);
});
});
})
.UseStartup<Startup>();
Ensuite, dans ma classe de démarrage:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<Settings>(Configuration.GetSection("WebApp:Settings"));
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseAzureAppConfiguration();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
et enfin mon modèle de configuration des paramètres:
public class Settings
{
public string BackgroundColor { get; set; }
public long FontSize { get; set; }
public string FontColor { get; set; }
public string Message { get; set; }
}
Maintenant, dans mon contrôleur, je tire ces paramètres et les jette dans un sac de vue pour les afficher sur la vue.
public class HomeController : Controller
{
private readonly Settings _Settings;
public HomeController(IOptionsSnapshot<Settings> settings)
{
_Settings = settings.Value;
}
public IActionResult Index()
{
ViewData["BackgroundColor"] = _Settings.BackgroundColor;
ViewData["FontSize"] = _Settings.FontSize;
ViewData["FontColor"] = _Settings.FontColor;
ViewData["Message"] = _Settings.Message;
return View();
}
}
Une vue simple pour afficher les changements:
<!DOCTYPE html>
<html lang="en">
<style>
body {
background-color: @ViewData["BackgroundColor"]
}
h1 {
color: @ViewData["FontColor"];
font-size: @ViewData["FontSize"];
}
</style>
<head>
<title>Index View</title>
</head>
<body>
<h1>@ViewData["Message"]</h1>
</body>
</html>
Je peux l'obtenir pour tirer la configuration vers le bas la première fois, cependant, la fonctionnalité de rafraîchissement ne semble en aucun cas fonctionner.
Dans le dernier exemple, je m'attendais à ce que les configs se mettent à jour lorsque la sentinelle a été définie sur une nouvelle valeur, ou à tout le moins, à mettre à jour une valeur 30 secondes après sa modification. Aucune longueur d'attente ne met à jour les valeurs, et seul un arrêt complet et un redémarrage de l'application charge la nouvelle configuration.
Mise à jour: ajout de app.UseAzureAppConfiguration (); dans la méthode configure au démarrage et en définissant un délai d'expiration explicite sur le cache pour la configuration, la méthode d'actualisation était actualisée après un certain temps, mais la fonctionnalité sentinelle ne fonctionne toujours pas, pas plus que l'indicateur updateAll sur la méthode d'actualisation.
la source
ConfigureServices
méthode dans startuop.cs, commeservices.Configure<LogSettings>(configuration.GetSection("LogSettings"));
Réponses:
Ok, après de nombreux tests et essais et erreurs, je le fais fonctionner.
Mon problème était un service manquant pour azure sur la méthode de configuration. Il y a un comportement intéressant ici, dans la mesure où il abaissera toujours les paramètres, il ne sera simplement pas mis à jour, s'il est manquant. Donc, une fois que cela a été installé et avec une sentinelle appropriée configurée par la documentation, cela fonctionne avec le drapeau updateAll. Cependant, cela n'est actuellement pas documenté.
Voici la solution:
Dans Program.cs:
Puis dans Startup.cs:
Le modèle de paramètres auquel je lie mes données extraites d'azur:
Un contrôleur d'accueil générique avec la configuration définie sur le ViewBag pour passer à notre vue:
Notre point de vue:
J'espère que ceci aide quelqu'un d'autre!
la source