Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure WebJobs SDK 3, trying to add a BlobTrigger and related connection string

The old way of doing things looked as so:

        var jobConfig = new JobHostConfiguration(cfg.DocumentDatabase.BlobStorageServer)
        {
            NameResolver = new Support.BlobNameResolver(_env)
        };
        jobConfig.Queues.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);

        _wjHost = new JobHost(jobConfig);

I am trying to translate this to the new way in 3.0, and this is how far I have come:

        _wjHost = new HostBuilder().ConfigureWebJobs(b =>
        {
            b.AddAzureStorage(x =>
            {
                x.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
            });
        }).ConfigureServices(s =>
        {
            s.AddSingleton<INameResolver, Support.BlobNameResolver>(_ => new Support.BlobNameResolver(_env));
            s.Configure<QueuesOptions>(o =>
            {
                o.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
            });
        }).Build();

Firstly, i don't know which MaxPollingInterval is the right one to use... so i set both. I assume i shouldn't be using the one in AddBlobStorage

Secondly, and more importantly, where do I specify the blob storage connection string? In the case above, it's the setting stored in cfg.DocumentDatabase.BlobStorageServer

Thanks

like image 885
Andy Avatar asked Jan 01 '23 15:01

Andy


2 Answers

Official sample available at WebJob Github

In your Functions, you can pass the connection string key name used in appsettings.json

ex:

public void ProcessBlob([BlobTrigger("blobPath", Connection = "AzureWebJobsBlobConnection")] string blob)

the "AzureWebJobsBlobConnection" is configured in appsettings.json as follows: { "Logging": { ... }, "AzureWebJobsBlobConnection": "...", }

And do not forget to add the configuration in program.cs:

var builder = new HostBuilder()
            .ConfigureAppConfiguration((builderContext, cb) =>
            {
                IHostingEnvironment env = builderContext.HostingEnvironment;

                cb.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
            })
            .ConfigureWebJobs(b =>
            {
                b.AddAzureStorage(o => 
                {
                    o.MaxDequeueCount = 1;
                })
                .AddServiceBus(c =>
                {
                    c.MessageHandlerOptions.MaxConcurrentCalls = 1;
                });
            })
            .ConfigureLogging((webHostBuilder, loggingBuilder) =>
            {
                loggingBuilder.AddConsole();
                loggingBuilder.AddDebug();
            })
            .ConfigureServices((hb, sc) =>
            {
                string connectionString = hb.Configuration.GetConnectionString("DefaultConnection");

                sc.AddScoped<Functions, Functions>();
                ...
            });

        builder.RunConsoleAsync().GetAwaiter().GetResult();
like image 60
Jek Avatar answered Jan 22 '23 12:01

Jek


So, after staring at the source code for the webjob SDK, I found a kludge. Well, I think it's a kludge. It works and I can now use the new 3.0 SDK.

I am posting this here, mainly because I fear there is no other way to do this using my own configuration files.

If this is wrong, please just let me know and I will delete this answer.

So my code now looks like this:

    _wjHost = new HostBuilder().ConfigureWebJobs(b =>
    {
        b.AddAzureStorage(x =>
        {
            x.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
        });
    }).ConfigureServices(s =>
    {
        s.AddSingleton(new StorageAccountProvider(new BlobStorageConfiguration(cfg.DocumentDatabase.BlobStorageServer)));
        s.AddSingleton<INameResolver, Support.BlobNameResolver>(_ => new Support.BlobNameResolver(_env));
        s.Configure<QueuesOptions>(o =>
        {
            o.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
        });
    }).Build();

The line I added was s.AddSingleton(new StorageAccountProvider(new BlobStorageConfiguration(cfg.DocumentDatabase.BlobStorageServer)));

The webjobs SDK is specifically looking for a key named Storage. So I had to implement IConfiguration and kludge this in as so:

private sealed class BlobStorageConfiguration : IConfiguration
{
    private readonly string _bsConnString;
    public BlobStorageConfiguration(string connString)
    {
        _bsConnString = connString;
    }

    public string this[string key]
    {
        get => key == "Storage" ? _bsConnString : null;
        set { }
    }

    public IEnumerable<IConfigurationSection> GetChildren() => null;
    public IChangeToken GetReloadToken() => null;
    public IConfigurationSection GetSection(string key) => null;
}

and now the trigger is firing just fine. Not pretty. But there is ZERO documentation on the new IHost methods.

like image 45
Andy Avatar answered Jan 22 '23 10:01

Andy