3

I have followed the Microsoft tutorial to process event based on blob being created in Azure storage.

The event is firing but the event code to process the image is bypassed as the input stream parameter is not being populated by the EventGrid event. This should be passing through the path of the blob (image file) to process.

 public static async Task Run(
        [EventGridTrigger]EventGridEvent eventGridEvent,
        [Blob("{data.url}", FileAccess.Read)] Stream input,
        ILogger log)
    {
        try
        {
            log.LogInformation("Entered Thumbnail Function ..");

            if (input != null) 
            { //doesn't get to here ..

The log each time the event fires is

2018-11-15T05:33:41.096 [Information] Executing 'Thumbnail' (Reason='EventGrid trigger fired at 2018-11-15T05:33:41.0781270+00:00' ..

2018-11-15T05:33:41.096 [Information] Entered Thumbnail Function

2018-11-15T05:33:41.096 [Information] Executed 'Thumbnail' (Succeeded, 

2018-11-15T05:33:41.096 [Information] Executing 'Thumbnail' (Reason='EventGrid trigger fired at 2018-11-15T05:33:41.0781270+00:00', 

2018-11-15T05:33:41.096 [Information] Entered Thumbnail Function

2018-11-15T05:33:41.096 [Information] Executed 'Thumbnail' (Succeeded,
Jayendran
  • 9,638
  • 8
  • 60
  • 103
Cyborg
  • 1,244
  • 12
  • 12
  • I ran the sample and it is fine for me, the binding works. Which version of az functions/ event grid extensions are using (nuget package version)? – Thomas Nov 15 '18 at 12:17

3 Answers3

5

The tutorial works for v1 c# script function as you can see it mentions csx file when talking about function code. But now the project link points to v2 pre-compiled code, changes in the code could cause problem when we follow the tutorial strictly.

Let's fix the inconsistency with two steps.

  1. The key point is function wasn't connected to the blob Storage account created in part1, hence we got null input stream.

    Since we have created an app setting myblobstorage_STORAGE in this step, we only have to add it in our function code.

    public static async Task Run(
        [EventGridTrigger]EventGridEvent eventGridEvent,
        [Blob("{data.url}", FileAccess.Read, Connection = "myblobstorage_STORAGE")] Stream input,
        ILogger log)
    
  2. In the same step, tutorial sets an app setting myContainerName for container thumbnails created in Blob Storage Account in part1.

    But in our code we can see it connects to the Storage account created for Function app with AzureWebJobsStorage and wants to get container name from app setting THUMBNAIL_CONTAINER_NAME.

    The quick fix is to replace AzureWebJobsStorage and THUMBNAIL_CONTAINER_NAME, and set a constant for thumbnailWidth.

    private static readonly string BLOB_STORAGE_CONNECTION_STRING = Environment.GetEnvironmentVariable("myblobstorage_STORAGE");
    ...
    var thumbnailWidth = 100;
    var thumbContainerName = Environment.GetEnvironmentVariable("myContainerName");
    

    Of course you could choose to add THUMBNAIL_WIDTH in Application settings of Azure portal.

Republish and everything should work.

Jerry Liu
  • 17,282
  • 4
  • 40
  • 61
  • 1
    how does it know what value to bind to `Blob("{data.url}"`? – Alex Gordon Mar 29 '19 at 22:39
  • This doesn't work for Azure Functions v1 (with WebJobs packages)... – rios0rios0 Feb 03 '21 at 04:43
  • @AlexGordon. I found an answer to the data.url question [here](https://github.com/Azure/azure-sdk-for-js/issues/13024). Deep in this discussion ramya-rao-a says, "According to [JSON payloads](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-expressions-patterns#json-payloads) and [binding expressions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-event-grid-trigger?tabs=javascript%2Cbash#event-schema), since the event data payload is a JSON object, you are able to refer to anything inside it in the bindings." – David Yates May 19 '21 at 17:28
2

The data will never be passed in. Event Grid event will only pass metadata, which will include blob URI you could use to retrieve the content if you need to.

Sean Feldman
  • 23,443
  • 7
  • 55
  • 80
1

In addition to the currently accepted answer (https://stackoverflow.com/a/53314953/816663), you can also make it work without adding the Connection parameter if your Function app has a system or user-assigned identity that has the appropriate Blob permissions on the storage account.

SvenAelterman
  • 1,532
  • 1
  • 15
  • 26