Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing container name as a parameter to BlobTrigger

I have a little C# app that does some stuff when a new blob is added to a container in a storage account.

I'm working locally using Visual Studio 2017.

The VS template gives me:

using System.IO;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;

namespace LogicAppTriggerFunction
{
    public static class BlobTrigger
    {
        [FunctionName("BlobTrigger")]
        public static void Run([BlobTrigger("samples-workitems/{name}", Connection = "")]Stream myBlob, string name, ILogger log)
        {
            log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
        }
    }
}

I'm trying to replace "samples-workitems" with a variable that relates to the name of my container. I only want to work with one container, but I don't want to "hard code" it.

If I am on the right lines, this setting is stored in function.json that is built at compile-time. When working locally, I think / thought that the contents of function.json is read by local.settings.json, however I now believe that to be for appSettings.json.

Reading the MS doco, particularly on trigger bindings, it looks like myContainer/{name} should be read from function.json. I understand that function.json is built dynamically and shouldn't be modified.

I have tried various methods that I know to essentially replace the string myContainer/{name}, but they all result in the error:

[20/08/2018 14:56:36] Run: Microsoft.Azure.WebJobs.Host: Error indexing method 'TriggerLogicApp.Run'. Microsoft.Azure.WebJobs.Host: Invalid blob trigger path '{container}/{name}'. Container paths cannot contain {resolve} tokens.

I believe what I need to do is "create" (or update) the path value in function.json, programatically, but I can't find out how to do this.

Can anyone shed any light on what I need to do and possibly how?

like image 378
woter324 Avatar asked Jan 02 '23 23:01

woter324


2 Answers

Specify your container name in local.settings.json locally or in Application settings on Azure.

{
    "IsEncrypted": false,
    "Values": {
        ....
        "MyBlobContainer":"samples-workitems"
    }
}

In your function signature, use App setting binding expressions wrapped in percent signs.

public static void Run([BlobTrigger("%MyBlobContainer%/{name}", Connection = "")]Stream myBlob, string name, ILogger log)
like image 173
Jerry Liu Avatar answered Jan 17 '23 20:01

Jerry Liu


Instead of using a BlobTrigger, have you considered using the EventGridTrigger?

Your function will receive subscribed events from the Storage Accounts topic, and will need logic to ignore/discard uninteresting events, but the upside is that you will receive the full URL of the storage container in either the subject or the events' data.url structure.

Here's what that structure looks like (from MSDN):

[{
  "topic": "/subscriptions/{subscriptionid}/resourceGroups/eg0122/providers/Microsoft.Storage/storageAccounts/egblobstore",
  "subject": "/blobServices/default/containers/{containername}/blobs/blobname.jpg",
  "eventType": "Microsoft.Storage.BlobCreated",
  "eventTime": "2018-01-23T17:02:19.6069787Z",
  "id": "{guid}",
  "data": {
    "api": "PutBlockList",
    "clientRequestId": "{guid}",
    "requestId": "{guid}",
    "eTag": "0x8D562831044DDD0",
    "contentType": "application/octet-stream",
    "contentLength": 2248,
    "blobType": "BlockBlob",
    "url": "https://egblobstore.blob.core.windows.net/{containername}/blobname.jpg",
    "sequencer": "000000000000272D000000000003D60F",
    "storageDiagnostics": {
      "batchId": "{guid}"
    }
  },
  "dataVersion": "",
  "metadataVersion": "1"
}]
like image 25
Josh E Avatar answered Jan 17 '23 19:01

Josh E