Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Azure Function triggered by Azure Event Grid?

Which trigger type should I use to run an Azure Function as subscription to Azure Event Grid topic?

This capability is mentioned everywhere related to Event Grid, but I don't see any tutorials or code samples.

like image 583
Mikhail Shilkov Avatar asked Oct 05 '17 15:10

Mikhail Shilkov


2 Answers

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Azure.WebJobs.Extensions.EventGrid;
using Newtonsoft.Json;

namespace FunctionApp3
{
   public static class Function2
   {

      [FunctionName("Function2")]
      public static void Run([EventGridTrigger()]EventGridEvent eventGridEvent, TraceWriter log)
      {
        log.Info($"EventGridEvent\n\tId:{eventGridEvent.Id}\n\tTopic:{eventGridEvent.Topic}\n\tSubject:{eventGridEvent.Subject}\n\tType:{eventGridEvent.EventType}\n\tData:{JsonConvert.SerializeObject(eventGridEvent.Data)}");

      }
   }
}

using the azure portal:

run.cs:

#r "Microsoft.Azure.WebJobs.Extensions.EventGrid"
#r "Newtonsoft.Json"

using Microsoft.Azure.WebJobs.Extensions.EventGrid;
using Newtonsoft.Json;

public static void Run(EventGridEvent eventGridEvent, TraceWriter log)
{
    //log.Info(eventGridEvent.ToString());

    var jsondata = JsonConvert.SerializeObject(eventGridEvent.Data);
    var tmp = new { make = "", model = "", test = ""};   
    var data = JsonConvert.DeserializeAnonymousType(jsondata, tmp);

    log.Info($"Data = make:{data.make}, model:{data.model}, test:{data.test}");
    log.Info($"EventGridEvent\n\tId:{eventGridEvent.Id}\n\tTopic:{eventGridEvent.Topic}\n\tSubject:{eventGridEvent.Subject}\n\tType:{eventGridEvent.EventType}\n\tData:{jsondata}");   
}

function.json:

   {
     "bindings": [
     {
       "type": "eventGridTrigger",
       "name": "eventGridEvent",
       "direction": "in"
     }
    ],
    "disabled": false
   }

sample for test:

{
    "Topic": null,
    "Subject": "/myapp/vehicles/motorcycles",    
    "Id": "b68529f3-68cd-4744-baa4-3c0498ec19e2",
    "EventType": "recordInserted",
    "EventTime": "2017-06-26T18:41:00.9584103Z",
    "Data":{
      "make": "Ducati",
      "model": "Monster",
      "test":"-----------"
    }
 }

last step is to create an Event Grid Subscription Url in the integrate page:

enter image description here

like image 97
Roman Kiss Avatar answered Oct 06 '22 12:10

Roman Kiss


It's possible to use Generic Webhook trigger for this purpose.

Here is a sample function.

function.json:

{
  "bindings": [
    {
      "type": "httpTrigger",
      "direction": "in",
      "webHookType": "genericJson",
      "name": "req"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ],
  "disabled": false
}

C# implementation:

#r "Newtonsoft.Json"

using System;
using System.Net;
using Newtonsoft.Json;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    string jsonContent = await req.Content.ReadAsStringAsync();
    var events = JsonConvert.DeserializeObject<GridEvent[]>(jsonContent);

    if (req.Headers.GetValues("Aeg-Event-Type").First() == "SubscriptionValidation")
    {
        var code = events[0].Data["validationCode"];
        return req.CreateResponse(HttpStatusCode.OK, new { validationResponse = code });
    }

    // Do whatever you need with events    
    foreach (var e in events)
        log.Info(e.Id);

    return req.CreateResponse(HttpStatusCode.OK);
}

public class GridEvent
{
    public string Id { get; set; }
    public string EventType { get; set; }
    public string Subject { get; set; }
    public DateTime EventTime { get; set; }
    public Dictionary<string,string> Data { get; set; }
    public string Topic { get; set; }
}

Note two important things:

  • Custom GridEvent class to parse event JSON into POCO
  • if block that takes care of endpoint validation (Event Grid requirement)
like image 20
Mikhail Shilkov Avatar answered Oct 06 '22 12:10

Mikhail Shilkov