Azure WebJobs QueueTrigger ignores environment when reading configuration

573 Views Asked by At

I have an Azure WebJobs with QueueTrigger:

public void ProcessTestQueueByTrigger(
    [QueueTrigger("test-queue", Connection = "MyCustomStorageConnection")] string queueMessage,
    int dequeueCount,
    TextWriter log)
    {
        var message = $"ProcessTestQueueByTrigger executed: {queueMessage}, dequeue: {dequeueCount}";
        log.WriteLine(message);
    }
}

Where MyCustomStorageConnection is not the same as default jobs connection (that is why I define it in the QueueTrigger attribute). I also have two local files which defines settings for dev and prod environment: appsettings.json and appsettings.Production.json.

When I start the WebJobs, I'm reading the valid configuration and settings to the config object

var configuration = new JobHostConfiguration
{
    DashboardConnectionString = config.GetConnectionString("AzureWebJobsDashboard"),
    StorageConnectionString = config.GetConnectionString("AzureWebJobsStorage"),
};

and the valid connection stored in config.GetConnectionString("MyCustomStorageConnection") but there is no place to set it with the host. And whenever host is started, the QueueTrigger is reading the value from the appsettings.json and totally ignores the appsettings.Production.json.

How can I force QueueTrigger to use the proper config or just define the value for the QueueTrigger connection string?

1

There are 1 best solutions below

0
On

You can achieve this easily by setting environment variable.

The following are the steps, on windows 10 with visual studio 2017.

1.Create a .NET core webjob(you can follow this doc if not familiar), and the completed code as below:

Program.cs:

using System;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace MySampleWebjob
{
    class Program
    {
        static void Main(string[] args)
        {

            //since we have 2 .json files, we can control which .json file is to be used by setting a Environment variable. And then read the value here.
            var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
            Console.WriteLine($"the environment is: "+ environment);

            var builder = new HostBuilder();
            builder.ConfigureWebJobs(b =>
            {
                b.AddAzureStorageCoreServices();
                b.AddAzureStorage();
            })
            .ConfigureAppConfiguration((hostContext, configApp) => {
                configApp.AddJsonFile("appsettings.json", optional: true,reloadOnChange:true);
                configApp.AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true);
                configApp.AddEnvironmentVariables();
            })
            .ConfigureLogging((context, b) =>
            {
                b.AddConsole();
            })
            ;
            var host = builder.Build();
            using (host)
            {
                host.Run();
            }
        }
    }
}

Functions.cs:

using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

namespace MySampleWebjob
{
        public class Functions
        {
            public static void ProcessQueueMessage([QueueTrigger("myqueue-items")] string message, ILogger logger)
            {
                logger.LogInformation(message);
            }
        }    
}

Then add 2 .json files in the project: appsettings.Production.json and appsettings.json. The structure of the 2 .json files are the same, but have different storage connectiong strings.

appsettings.json:

{
  "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=xxx;AccountKey=xx;EndpointSuffix=core.windows.net"
}

appsettings.Production.json:

  {
      "AzureWebJobsStorage": "Another azure storage connection string"
    }

Note that in visual studio, right click each of the json file -> properties -> set "Copy to Output Directory" to "Copy if newer".

At last, set environment variable via cmd or UI. The cmd command is setx ASPNETCORE_ENVIRONMENT "Production", then restart the visual studio if you want to use the environment variable.

So if you want to use the storage connection string from appsettings.json, don't need to set the environment variable. If you want to use the connection string from appsettings.Production.json, need to set the environment variable.

Note that, if you set an environment variable or remove an environment variable, remember to restart the visual studio to take effect.