Locally Debugging an Event Grid event in an Azure Function
Posted December 6, 2020
Reading time: 5 minutes
I have a requirement to add a JSON file to Azure Blob Storage and have an Azure Function automatically process
it via a BlobTrigger
. Simple enough, but when reading the docs for BlobTrigger
, I came across this
section on Polling
(emphasis mine):
In addition, storage logs are created on a “best effort” basis. There’s no guarantee that all events are captured. Under some conditions, logs may be missed.
If you require faster or more reliable blob processing, consider creating a queue message when you create the blob. Then use a queue trigger instead of a blob trigger to process the blob. Another option is to use Event Grid; see the tutorial Automate resizing uploaded images using Event Grid.
I’m not building a banking application, but I still want more reliability than “best effort”, and faster is
always nice, so I decided to let an EventGridTrigger
handle the blob created event.
The docs for locally debugging an Azure Function with an EventGridTrigger
do a great job of explaining how to set up an Event Grid Subscription to call a webhook in response to the blob
created event, but at the time I write this, that page is two years old and is missing a critical piece to get
local debugging working: you need to use a separate HttpTrigger
to parse the posted Event Grid event and
handle the webhook validation handshake:
Synchronous handshake: At the time of event subscription creation, Event Grid sends a subscription validation event to your endpoint. The schema of this event is similar to any other Event Grid event. The data portion of this event includes a validationCode property. Your application verifies that the validation request is for an expected event subscription, and returns the validation code in the response synchronously. This handshake mechanism is supported in all Event Grid versions.
You have to have a separate function with an HttpTrigger
because the signature of the EventGridTrigger
doesn’t allow
you to return a 200 OK
response with the validation code:
|
|
I tried changing the signature to return a Task<IActionResult>
, but the Functions runtime was NOT happy about that.
So that function can be used in Azure environments when setting up the Event Grid Subscription in Azure Portal, but not for
local debugging because there is no way to return the validation code (if you know how to make this happen with an EventGridTrigger
,
please let me know in the comments).
For local debugging, and to participate in the validation handshake, you need an HttpTrigger
function. The Azure team
has some nice sample code,
but it looks like it targets .NET Framework
, so I have adapted it for .NET Core 3.1
:
|
|
You can see in lines 5-14 that we’re manually parsing the request JSON and deserializing it into EventGridEvent
instances. We then loop through the array of events and handle any that interest us. Here, there are two that we
want to handle:
-
SubscriptionValidationEventData
: this contains the validation code that we need to return in a200 OK
response to complete the Event Grid validation handshake. -
StorageBlobCreatedEventData
: this contains information about a blob that was just uploaded to your Blob Storage account. To eliminate code duplication, this calls the sameInternalHandleBlobCreatedEvent
method to handle the event that we use in the “production” function with theEventGridTrigger
.
Now when you click Create
in Azure Portal to create your Event Grid Subscription, you’ll see in ngrok
that the
validation handshake succeeded:
And now that Event Grid has validated your webhook, you can set a breakpoint in your HttpTrigger
function, upload
a blob, and receive the event right in your local debugger:
And voilà, you are now locally debugging your Event Grid events in your Azure Function.