Функции Azure, как иметь несколько файлов конфигурации .json - PullRequest
0 голосов
/ 05 июня 2019

Итак, я написал функцию Azure, которая работает локально просто отлично. Я считаю, что это связано с файлом local.setting.json. Но когда я публикую его на Azure, функция не работает, так как не может найти значения параметров, которые я определил. Исходя из подхода, основанного на веб-приложении и консоли, у нас будут разные конфигурационные файлы, которые будут связаны с каждой средой. Как я могу заставить это работать, чтобы я мог иметь несколько settings.json файлов, например один для dev, stag и prod сред? Конечным результатом является его развертывание с помощью развертывания осьминога, но на этом этапе, если я не могу получить событие, работающее с публикацией, у меня нет шансов сделать это.

Я довольно озадачен, почему эта информация не так легко доступна, так как предположил бы, что это обычное дело?

Ответы [ 3 ]

1 голос
/ 06 июня 2019

Мне бы очень хотелось, чтобы функции поддерживали специфические для среды настройки так же, как приложения ядра или консоли asp.net.В то же время я использую приведенный ниже код, который несколько хакерский (см. Комментарии).

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        // Get the path to the folder that has appsettings.json and other files.
        // Note that there is a better way to get this path: ExecutionContext.FunctionAppDirectory when running inside a function. But we don't have access to the ExecutionContext here.
        // Functions team should improve this in future. It will hopefully expose FunctionAppDirectory through some other way or env variable.
        string basePath = IsDevelopmentEnvironment() ?
            Environment.GetEnvironmentVariable("AzureWebJobsScriptRoot") :
            $"{Environment.GetEnvironmentVariable("HOME")}\\site\\wwwroot";

        var config = new ConfigurationBuilder()
            .SetBasePath(basePath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)  // common settings go here.
            .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT")}.json", optional: false, reloadOnChange: false)  // environment specific settings go here
            .AddJsonFile("local.settings.json", optional: true, reloadOnChange: false)  // secrets go here. This file is excluded from source control.
            .AddEnvironmentVariables()
            .Build();

        builder.Services.AddSingleton<IConfiguration>(config);
    }

    public bool IsDevelopmentEnvironment()
    {
        return "Development".Equals(Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT"), StringComparison.OrdinalIgnoreCase);
    }
}
1 голос
/ 06 июня 2019

ОК, теперь у меня все работает :) Поскольку мы используем развертывание осьминога, нам не нужны несколько файлов конфигурации, поэтому у нас есть только один appsettings.Release.json файл, в который подставляются значения на основе среда разворачивается тоже.

Ниже приведен основной код функции.

public static class Function
    {
        // Format in a CRON Expression e.g. {second} {minute} {hour} {day} {month} {day-of-week}
        // https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer
        // [TimerTrigger("0 59 23 * * *") = 11:59pm
        [FunctionName("Function")]
        public static void Run([TimerTrigger("0 59 23 * * *")]TimerInfo myTimer, ILogger log)
        {

            // If running in debug then we dont want to load the appsettings.json file, this has its variables substituted in octopus
            // Running locally will use the local.settings.json file instead
#if DEBUG
            IConfiguration config = new ConfigurationBuilder()
                .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables()
                .Build();
#else
            IConfiguration config = Utils.GetSettingsFromReleaseFile();
#endif

            // Initialise dependency injections
            var serviceProvider = Bootstrap.ConfigureServices(log4Net, config);

            var retryCount = Convert.ToInt32(config["RetryCount"]);

            int count = 0;
            while (count < retryCount)
            {
                count++;
                try
                {
                    var business = serviceProvider.GetService<IBusiness>();
                    business.UpdateStatusAndLiability();
                    return;
                }
                catch (Exception e)
                {
                    // Log your error
                }
            }

        }

    }

Файл Utils.cs выглядит следующим образом

public static class Utils
    {

        public static string LoadSettingsFromFile(string environmentName)
        {
            var executableLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            // We need to go back up one level as the appseetings.Release.json file is not put in the bin directory
            var actualPathToConfig = Path.Combine(executableLocation, $"..\\appsettings.{environmentName}.json");
            using (StreamReader reader = new StreamReader(actualPathToConfig))
            {
                return reader.ReadToEnd();
            }
        }

        public static IConfiguration GetSettingsFromReleaseFile()
        {
            var json = Utils.LoadSettingsFromFile("Release");
            var memoryFileProvider = new InMemoryFileProvider(json);

            var config = new ConfigurationBuilder()
                .AddJsonFile(memoryFileProvider, "appsettings.json", false, false)
                .Build();
            return config;
        }

    }

appsettings.Release.json установлен как Содержимое и Копировать всегда в visual studio. Похоже, это

{
  "RetryCount": "#{WagonStatusAndLiabilityRetryCount}",
  "RetryWaitInSeconds": "#{WagonStatusAndLiabilityRetryWaitInSeconds}",
  "DefaultConnection": "#{YourConnectionString}"
}

На самом деле, я думаю, что вы могли бы уже иметь файл appsettings.config и пропустить файл appsettings.Release.json, но это работает, и вы можете делать с ним все, что хотите.

1 голос
/ 05 июня 2019

Этот документ имеет описание о local.settings.json:

По умолчанию эти параметры не переносятся автоматически при публикации проекта в Azure.

Одним из способов является использование --publish-local-settings:

Публикация настроек в local.settings.json в Azure с предложением перезаписать, если настройка уже существует.

Другой способ - использовать Manage Application Settings, Remote - это текущая настройка в приложении функций в Azure.Или выберите «Добавить параметр», чтобы создать новый параметр приложения.Для получения дополнительной информации вы можете обратиться к этому документу: Настройки приложения функций .

enter image description here

...