c#-使用输入绑定将blob名称匹配到函数变量
作者:互联网
根据Azure Blob storage bindings for Azure Functions documentation,在配置Blob触发器时,您可以利用Blob名称上的模式匹配将路径的一部分映射到函数中的变量,例如.
[FunctionName("BlobTriggered")]
public static void BlobTriggered(
[BlobTrigger("myContainer/{name}.{extension}")] Stream myBlob,
string name,
string extension,
TraceWriter log)
{
// Given the blob path "myContainer/myBlob.png":
// name == "myBlob"
// extension == "png"
}
我已经对此进行了测试,并且它在我的用例中表现出色,但是由于BlobTrigger触发的延迟较大(通常超过5分钟),因此这不是一个可行的选择.因此,我希望根据Azure Functions scale and hosting documentation的建议,将其设置为事件网格触发器:
When you’re using a blob trigger on a Consumption plan, there can be up to a 10-minute delay in processing new blobs. This delay occurs when a function app has gone idle. After the function app is running, blobs are processed immediately. To avoid this cold-start delay, use an App Service plan with Always On enabled, or use the Event Grid trigger.
有没有办法从输入绑定而不是触发器中获得相同的模式匹配行为?
在我的特定情况下,我为Event Blob设置了EventGrid订阅,该订阅运行一个Orchestrator函数,该Orchestrator函数调用一个Activity函数来读取和解析The Blob:
[FunctionName("NewBlobCreated")]
public static async Task NewBlobCreated(
[EventGridTrigger]EventGridEvent eventGridEvent,
[OrchestrationClient]DurableOrchestrationClient starter,
ILogger log)
{
// Start our orchestrator function to read the file
string instanceId = await starter.StartNewAsync(
"OrchestrateBlobReader",
eventGridEvent);
}
// Orchestrator function
[FunctionName("OrchestrateBlobReader")]
public static async Task OrchestrateBlobReader(
[OrchestrationTrigger] DurableOrchestrationContext context,
ILogger log)
{
var eventGridEvent = context.GetInput<EventGridEvent>();
var parsedBlob = await context.CallActivityAsync<string>("ReadBlob", eventGridEvent.Data);
...
}
[FunctionName("ReadBlob")]
public static async Task<string> ReadBlob(
[ActivityTrigger] JObject eventData,
[Blob("{data.url}", FileAccess.Read)]CloudBlockBlob blob,
ILogger log)
{
using (var blobStream = await blob.OpenReadAsync())
{
// Blob is able to be read from blobStream here
...
}
}
理想情况下,我希望我的ReadBlob函数的行为类似于上述第一个示例示例中的BlobTriggered函数,以执行以下操作:
[FunctionName("ReadBlob")]
public static async Task<string> ReadBlob(
[ActivityTrigger] JObject eventData,
[Blob("{data.url}", FileAccess.Read)]CloudBlockBlob blob,
string extension,
ILogger log)
{
if (extension.Equals("txt", StringComparison.OrdinalIgnoreCase))
{ ... }
else if (extension.Equals("png", StringComparison.OrdinalIgnoreCase)
{ ... }
else
{ ... }
}
问题是我无法像我为BlobTrigger所做的那样看到将扩展参数绑定到Blob输入绑定的任何方法-特别是将路径绑定到EventGridEvent提供的url
以eventData JObject的形式.
在这种情况下是否可以实现相同的模式匹配功能?还是我必须自己解析路径字符串以提取相关信息?
解决方法:
在查看了源代码触发器绑定的源代码之后,我的“快速处理”解决方案是利用底层BindingTemplateSource
class,触发器用于映射路径和路径.模式到字典.
更新的ReadBlob函数如下:
// So we can access the BindingTemplateSource class
using Microsoft.Azure.WebJobs.Host.Bindings.Path;
[FunctionName("ReadBlob")]
public static async Task<string> ReadBlob(
[ActivityTrigger] JObject eventData,
[Blob("{data.url}", FileAccess.Read)]CloudBlockBlob blob,
ILogger log)
{
// Define the pattern to match
var blobPattern = "myContainer/{name}.{extension}";
// Create a BindingTemplateSource from the pattern string
var patternTemplate = BindingTemplateSource.FromString(blobPattern);
// Use this BindingTemplateSource to create the binding data
// This returns a IReadOnlyDictionary<string, object> with the parameters mapped
var parameters = patternTemplate.CreateBindingData($"{blob.Container.Name}/{blob.Name}");
// Assuming blob path was "myContainer/myBlob.png":
// Parameters are objects so we need to ToString() them
var name = parameters["name"].ToString(); // name == "myBlob"
var extension = parameters["extension"].ToString(); // extension == "png"
if (extension.Equals("txt", StringComparison.OrdinalIgnoreCase))
{ ... }
else if (extension.Equals("png", StringComparison.OrdinalIgnoreCase))
{
// This executes now!
}
else
{ ... }
}
然后,可以将此功能包装在custom binding中,在其中将参数映射到函数上的输出绑定,就像BlobTrigger为最优雅的解决方案所做的那样,但是将其侵入这样的函数中可以满足我短期的需求
标签:azure-storage-blobs,azure-functions,c 来源: https://codeday.me/bug/20191108/2008368.html