Кто-нибудь испытывал время от времени зависание Azure.ConfigurationBuilder при запуске? Я настроил Azure KeyVault как подключенную службу, которую я использую для аутентификации разработчиков в KeyVault. Затем ConfigurationBuilder обрабатывает применение AppSettings на основе секретов в хранилище.
ПРИМЕЧАНИЕ: Все это прекрасно работает, за исключением того, что если я последовательно отлаживаюсь, я могу успешно вызвать зависание ConfigurationBuilder. Там нет никаких ошибок. Я использовал ReSharpers dotTrace, чтобы увидеть, что зависает:
Я также немного настраиваюсь в дополнение к использованию ConfigurationBuilder. Я храню ConnectionStrings в KeyVault, и я извлекаю их и применяю их в PreApplicationStart, позволяя ConfigurationBuilder обрабатывать AppSettings.
Вот мой KeyVaultHandler, который использует ConnectedService для аутентификации на KeyVault:
public static class KeyVaultHandler
{
private static readonly string VaultUri = ConfigurationManager.AppSettings["vaultUri"];
private static readonly AzureServiceTokenProvider AzureServiceTokenProvider = new AzureServiceTokenProvider();
private static readonly KeyVaultClient KvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(AzureServiceTokenProvider.KeyVaultTokenCallback));
public static Dictionary<string, string> GetSecrets()
{
try
{
var result = KvClient.GetSecretsAsync(VaultUri).GetAwaiter().GetResult();
return result.ToDictionary(value => value.Id, value => value.Identifier.Name);
}
catch (Exception e)
{
return null;
}
}
public static string GetSecretValue(string key)
{
try
{
return KvClient.GetSecretAsync(key).GetAwaiter().GetResult().Value;
}
catch (Exception e)
{
return null;
}
}
public static string GetSecretType(string key)
{
try
{
return KvClient.GetSecretAsync(key).GetAwaiter().GetResult().ContentType;
}
catch (Exception e)
{
return null;
}
}
...
Вот мой класс запуска, который применяет мои ConnectionStrings:
[assembly: PreApplicationStartMethod(typeof(SettingsProcessor), "Start")]
namespace CompanyKeyVault
{
public static class SettingsProcessor
{
#region Public Methods and Operators
public static void Start()
{
var secrets = KeyVaultHandler.GetSecrets();
foreach (var entry in secrets)
{
var name = entry.Value;
var val = KeyVaultHandler.GetSecretValue(entry.Key);
var type = KeyVaultHandler.GetSecretType(entry.Key);
if (type != null)
{
KeyVaultContentTypes enumType = (KeyVaultContentTypes)Enum.Parse(typeof(KeyVaultContentTypes), type);
switch (enumType)
{
case KeyVaultContentTypes.ConnectionString:
//Remove the KeyVault prefix in the name
name = Regex.Replace(name, @"Connection--", string.Empty);
//Now lets check if it is a Entity conecction or reguler SQL connection
string dbProvider = "System.Data.SqlClient";
Regex r3 = new Regex(@"App=EntityFramework");
Match m3 = r3.Match(val);
if (m3.Success)
{
dbProvider = "System.Data.EntityClient";
}
SetConnectionString(name, val, dbProvider);
break;
}
}
}
}
...
Я вполне уверен, что приведенный выше код не является проблемой, о которой я говорил, поскольку проблема, с которой я сталкиваюсь, связана с зависанием ConfigurationBuilder перед применением AppSettings. Этот код также запускает, аутентифицирует и извлекает все секреты KeyVault в обычном режиме и без проблем до того, как ConfigurationBuilder зависнет. Приведенный выше код предназначен исключительно для применения моей ConnectionString, и, как я уже говорил, я оставляю AppSettings для применения ConfigurationBuilder. Вот мой web.config, который охватывает это:
<configSections>
<section name="configBuilders" type="System.Configuration.ConfigurationBuildersSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" restartOnExternalChanges="false" requirePermission="false" />
</configSections>
<configBuilders>
<builders>
<add name="AzureKeyVault" vaultName="my-key-vault" type="Microsoft.Configuration.ConfigurationBuilders.AzureKeyVaultConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.Azure, Version=1.0.0.0, Culture=neutral" />
</builders>
</configBuilders>
...
<appSettings configBuilders="AzureKeyVault">
...
Если это имеет значение, я также использую кэш Azure Redis в качестве
SessionState провайдер. Я не уверен, влияет ли это на
Конфигурация Builder завершена, но я подумал, что упомяну об этом.
Я провел тщательный поиск по этому вопросу, но, честно говоря, документации, связанной с подключенными службами или ConfigurationBuilder, не так много.
Также важно отметить, что я работаю с Asp.Net 4.7.1 приложением WebForms (Это не приложение Core, в котором сосредоточена большая часть документации) . Я также создал несколько базовых и урезанных тестовых приложений, которые содержат только логику KeyVault, и они кажутся более последовательными, что наводит меня на мысль, что что-то в более крупном приложении портит ConfigurationBuilder.
Наверное, мои вопросы таковы:
- Кто-нибудь испытывал это вообще?
- Где мне искать первопричину этого зависания?
- Кто-нибудь знает какой-либо код, который я могу применить, который истечет время ожидания ConfigurationBuilder или создаст какое-то исключение для лучшей локализации и выявления проблемы здесь?
- Любая информативная информация будет приветствоваться!
Спасибо всем и приношу извинения за то, что этот вопрос не очень подробный - я думаю, именно поэтому я пишу, потому что у меня возникают проблемы с определением проблемы / причины, и он носит эпизодический характер.