处理来自不同 AD 租户的多个 Azure 订阅中的存储帐户的 blob 事件?

Handle blob events from storage accounts in multiple Azure Subscriptions in different AD Tenants?

是否可以收到有关在多个 Azure 订阅中的多个存储帐户中发生的 blobCreated 事件的通知?

我想在我的订阅中的中心 Azure 函数中处理任意存储帐户中发生的 blob 创建事件,但我想让客户能够将数据存储在他们自己的订阅中。

我正在考虑使用事件网格 Webhook 端点将事件路由到我的中央 Azure 函数。这是实现多订阅方案的可靠方法吗?

编辑:更准确地说,我需要它在不同的租户上工作(因为我们的客户会带来他们自己的订阅,我们需要集成它们而不将它们分配给我们的 AD 租户)

根据我们的讨论,以下屏幕片段显示了您的 multi-tenant-fan-in-scenarios。

通过 Azure 订阅 (multi-tenants) 订阅分布式兴趣源已完成将主题映射到 Webhook 端点。请注意,主题表示事件发布(发布)到 AEG 服务的位置的完整资源路径 (id)。此路径在当前租户的范围内,参见以下示例:

"topic": "/subscriptions/myID/resourceGroups/myRG/providers/microsoft.storage/storageaccounts/mySA"

"endpointBaseUrl": "https://myFnc.azurewebsites.net/runtime/webhooks/EventGrid?functionName=myEventGridTrigger&code=xxxx"

此映射在订阅元数据中声明,订阅元数据存储在与主题相同的范围内。另一方面,可以在此范围之外发布 webhook 端点。

其他更复杂的解决方案以及使用 FAN-OUT Pub/Sub 方式与事件分发完全隔离的方案如下面的屏幕片段所示:

在上述解决方案中,fan-in 订阅者可以将原始事件消息调解为正确的面向业务的事件消息,包括用于访问 blob 元数据的短 sasToken and/or body,等等

要使用 EventGridTrigger 函数的事件处理程序在您的租户中创建事件订阅,您可以使用例如 REST API call,请参见以下示例:

   PUT https://management.azure.com/subscriptions/myId/resourceGroups/myRG/providers/Microsoft.Storage/storageaccounts/mySA/providers/Microsoft.EventGrid/eventSubscriptions/mySubscription?api-version=2019-01-01

Headers:

  Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhb....

Body(最小负载):

{
  "properties": {
    "destination": {
      "endpointType": "WebHook",
      "properties": {
        "endpointUrl": "https://myFnc.azurewebsites.net/runtime/webhooks/EventGrid?functionName=myEventGridTrigger&code=xxxxxxxx..."
      }
    }
  }
}

更新:

在隔离的 multi-tenants 分布式事件架构中使用 Azure 事件网格 Pub/Sub 模型的另一种方法是其 级联 。 逻辑事件管道可以通过 Azure 事件网格的级联来构建,例如使用自定义主题将一个 Azure 事件网格订阅到另一个。

以下屏幕片段显示了 Azure 事件网格级联的示例:

通过将自定义主题端点订阅到标准 [=92] 中另一个事件网格模型的 WebHook 事件处理程序,可以启用基于 Fan-In 到 Fan-Out 模式的级联概念=] 方式。

请注意,Azure 事件网格没有 built-in 端点用于相互级联,包括验证事件环回。但是,以下步骤可以允许相互级联 Azure 事件网格。

  1. 使用 CustomInputSchema 创建自定义主题端点,例如:

    {
       "properties": {
          "inputSchema": "CustomEventSchema",
          "inputSchemaMapping": {
          "properties": {
            "id": {
              "sourceField": null
            },
            "topic": {
              "sourceField": null
            },
            "eventTime": {
               "sourceField": null
            },
            "eventType": {
               "sourceField": "myEventType",
               "defaultValue": "recordInserted"
            },
            "subject": {
               "sourceField": "subject",
               "defaultValue": "/myapp/vehicles/motorcycles"
            },
            "dataVersion": {
              "sourceField": null,
              "defaultValue": "1.0"
            }
        },
        "inputSchemaMappingType": "Json"
        }
      }
    }
    

    请注意,主题 属性 必须有一个 "sourceField": null,这对于自定义主题(不适用于事件域)是可以的。

  2. 对于 webhook 事件处理程序端点,请在 url 查询字符串中使用 aeg-sas-key,例如:

    https://myTopic.westus-1.eventgrid.azure.net/api/events?aeg-sas-key=xxxxxxxxxx

    请注意,aeg-sas-key 值必须是 url 编码字符串。

  3. 对于订阅验证,使用了 validationUrl 即发即弃方式的握手。可以在EventGridTrigger函数中实现,订阅自定义主题实现级联。 以下代码片段显示了此实现的示例:

    #r "Newtonsoft.Json"
    
    using System;
    using System.Threading.Tasks;
    using System.Text;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    
    public static async Task Run(JObject eventGridEvent, ILogger log)
    {
       log.LogInformation(eventGridEvent.ToString());
    
       string eventType = $"{eventGridEvent["data"]?["eventType"]?.Value<string>()}";
       if(!string.IsNullOrEmpty(eventType) && eventType == "Microsoft.EventGrid.SubscriptionValidationEvent")
       {
          // manual validation
          string validationUrl = $"{eventGridEvent["data"]?["data"]?["validationUrl"]?.Value<string>()}";
          using (var client = new HttpClient())
          {
            var response = await client.GetAsync(validationUrl);
            log.LogInformation(response.ToString());
          }
       }
       else
       {
         // notifications
       }
    
       await Task.CompletedTask;
    }
    

    请注意,原始事件消息(原始来源兴趣)在事件数据中级联(嵌套)每次发布时 object