Azure功能:如何在创建Blob时向云表添加行?

时间:2019-07-08 14:03:17

标签: azure .net-core azure-functions azure-eventgrid

我正在开发一个Azure函数,当添加新的Blob时,应该在Azure表中添加新行。该应用程序在Blob存储中有许多容器,我的Azure函数应该处理所有容器中的所有Blob。

我试图用EventGrid实现事件获取,但是它给出了一个错误。

我的Azure函数:

#r "D:\home\site\wwwroot\BlobCreatedFunction\Microsoft.Azure.EventGrid.dll"
#r"D:\home\site\wwwroot\BlobCreatedFunction\Microsoft.WindowsAzure.Storage.dll"
    using Microsoft.Azure.EventGrid.Models;
    using Microsoft.WindowsAzure.Storage.Table;
    using System;
public class TemporaryBlobEntity : TableEntity
{
    public TemporaryBlobEntity(string partitionKey, string rowKey)
    {
        this.PartitionKey = partitionKey;
        this.RowKey = rowKey;
    }

    public string BlobUrl { get; set; }
    public DateTime BlobUploaded { get; set; }

}
public static TemporaryBlobEntity Run(EventGridEvent eventGridEvent, ILogger log)
{
    if (eventGridEvent.Data is StorageBlobCreatedEventData eventData)
    {
        log.LogInformation(eventData.Url);

        log.LogInformation(eventGridEvent.Data.ToString());

        var temporaryBlob = new TemporaryBlobEntity("blobs", eventData.Url)
        {
            BlobUrl = eventData.Url,
            BlobUploaded = DateTime.UtcNow
        };

        return temporaryBlob;
    }

    return null;
}

这是我的集成JSON:

{
  "bindings": [
    {
      "type": "eventGridTrigger",
      "name": "eventGridEvent",
      "direction": "in"
    },
    {
      "type": "table",
      "name": "$return",
      "tableName": "temporaryBlobs",
      "connection": "AzureWebJobsStorage",
      "direction": "out"
    }
  ]
}

在Azure功能设置中,我添加了AzureWebJobsStorage的值。

当我在测试部分中按 Run 时,日志显示:

2019-07-08T13:52:16.756 [Information] Executed 'Functions.BlobCreatedFunction' (Succeeded, Id=6012daf1-9b98-4892-9560-932d05857c3e)

看起来不错,但云表中没有新项目。为什么?

然后我尝试将函数与EventGrid主题连接。我填写了新的订阅表单,选择“ Web Hook”作为端点类型,并将订户端点设置为:https://<azure-function-service>.azurewebsites.net/runtime/webhooks/EventGrid?functionName=<my-function-name>。然后我收到以下错误消息:

Deployment has failed with the following error: {"code":"Url validation","message":"The attempt to validate the provided endpoint https://####.azurewebsites.net/runtime/webhooks/EventGrid failed. For more details, visit https://aka.ms/esvalidation."}

据我了解,该应用程序需要某种请求验证。我真的需要在我的每个Azure函数中实施验证吗?还是应该使用其他端点类型?

2 个答案:

答案 0 :(得分:2)

当您在事件网格中输入一个Webhook时,它将发出一个请求,以验证您实际上对该端点具有权限。将功能连接到事件网格的最简单方法是从“功能”应用程序而非事件网格刀片创建订阅。

在门户中打开“功能”,您应该在顶部找到“添加事件网格订阅”的链接。即使“功能”应用是在本地创建并发布到Azure的,因此该代码也不可见,该链接仍然可用。 enter image description here

这将打开用于创建事件网格订阅的屏幕。区别在于,不是预先填充了“事件网格”主题信息,而是为您预填充了Web挂钩信息。填写有关“事件网格”主题的信息,以完成创建订阅。

enter image description here

如果您出于任何原因决定要执行验证响应,则可以通过检查消息的类型来实现。

// Validate whether EventType is of "Microsoft.EventGrid.SubscriptionValidationEvent"
if (eventGridEvent.EventType == "Microsoft.EventGrid.SubscriptionValidationEvent")
{
    var eventData = (SubscriptionValidationEventData)eventGridEvent.Data;
    // Do any additional validation (as required) such as validating that the Azure resource ID of the topic matches
    // the expected topic and then return back the below response
    var responseData = new SubscriptionValidationResponse()
    {
        ValidationResponse = eventData.ValidationCode
    };


    if (responseData.ValidationResponse != null)
    {

        return Ok(responseData);
    }
}
else
{
    //Your code here
}

通过从验证消息中获取验证链接并在浏览器中导航至validate the link manually,还有一个选项。此方法主要用于无法添加验证码的第三方服务。

答案 1 :(得分:1)

以下是对EventGridTrigger函数的更改:

#r "Microsoft.WindowsAzure.Storage"
#r "Microsoft.Azure.EventGrid"
#r "Newtonsoft.Json"

using System;
using Newtonsoft.Json.Linq;
using Microsoft.Azure.EventGrid.Models;
using Microsoft.WindowsAzure.Storage.Table;

public static TemporaryBlobEntity Run(EventGridEvent eventGridEvent, ILogger log)
{
    log.LogInformation(eventGridEvent.Data.ToString());

    var eventData = (eventGridEvent.Data as JObject)?.ToObject<StorageBlobCreatedEventData>();
    if(eventData?.Api == "PutBlob")
    {  
        log.LogInformation(eventData.Url);

        return new TemporaryBlobEntity("blobs", eventData.Sequencer)   
        {
            BlobUrl = eventData.Url,
            BlobUploaded = DateTime.UtcNow
        };   
    }
    return null;     
}

public class TemporaryBlobEntity : TableEntity
{
    public TemporaryBlobEntity(string partitionKey, string rowKey)
    {
        this.PartitionKey = partitionKey;
        this.RowKey = rowKey;
    }

    public string BlobUrl { get; set; }
    public DateTime BlobUploaded { get; set; }
}

注意:

  1. 您不需要为AEG订阅Webhook端点验证EventGridTrigger函数。此验证内置在EventGridTrigger函数的预处理中。
  2. eventGridEvent.Data 属性是一个JObject,必须转换(反序列化)到 StorageBlobCreatedEventData 对象,请参见here
  3. 对于 RowKey (和 PartitionKey ),请参见here中的限制字符,因此在本示例中,我将其更改为Sequencer值。
  4. EventGridTrigger函数的AEG订阅Webhook端点具有以下格式:

    https://{azure-function-service}.azurewebsites.net/runtime/webhooks/EventGrid?functionName={my-function-name}&code={systemkey}