如何使Azure Function被Azure Event Grid触发?

5

我应该使用哪种触发器类型将Azure函数作为Azure事件网格主题的订阅运行?

这种能力在与事件网格相关的所有地方都有提到,但我没有看到任何教程或代码示例。

2个回答

4

您可以使用通用Webhook触发器来实现此目的。

这里是一个示例函数。

function.json

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

C#实现:

#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; }
}

请注意两个重要事项:
  • 自定义 GridEvent 类将事件 JSON 解析为 POCO
  • if 代码块负责端点验证(事件网格要求)

4
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)}");

      }
   }
}

使用Azure门户:

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
   }

测试样例:

{
    "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":"-----------"
    }
 }

最后一步是在集成页面中创建一个事件网格订阅URL: enter image description here

谢谢!“秘诀”是在门户网站中的“方案”下拉菜单中选择“实验性” :) - Mikhail Shilkov
那是正确的。我还没有弄清楚如何在由VS2017 15.3.5设计的AF项目中配置EventGrid订阅URL。 - Roman Kiss
我猜你得手动配置它,比如说事件网格门户页面? - Mikhail Shilkov
1
我在门户中找不到Event Grid订阅URL,我的应用程序被标记为只读,我猜测是因为C#应用程序。有什么想法吗? - Jonathan
在门户/Function_app_settings页面上将函数应用的编辑模式更改为读/写。然后,转到函数/integrate页面以创建EventGrid订阅URL(您的事件订阅)。完成后,可以将编辑模式返回为只读。 - Roman Kiss
@RomanKiss 感谢您的建议,但将函数设置更改为读/写仍然无法让我在门户中再次创建订阅。 - Kapé

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接