Skip to content

Commit

Permalink
Update blob extension deffered binding attributes (#1462)
Browse files Browse the repository at this point in the history
  • Loading branch information
surgupta-msft authored and liliankasem committed Jul 18, 2023
1 parent ca5d1fa commit c2c6547
Show file tree
Hide file tree
Showing 11 changed files with 1,165 additions and 53 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using Microsoft.Azure.Functions.Worker.Converters;
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions;

namespace Microsoft.Azure.Functions.Worker
{
[SupportsDeferredBinding]
[AllowConverterFallback(false)]
[InputConverter(typeof(BlobStorageConverter))]
public sealed class BlobInputAttribute : InputBindingAttribute
{
private readonly string _blobPath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
using Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions;

namespace Microsoft.Azure.Functions.Worker
{
/// <summary>
/// Converter to bind Blob Storage type parameters.
/// </summary>
[SupportsDeferredBinding]
internal class BlobStorageConverter : IInputConverter
{
private readonly IOptions<WorkerOptions> _workerOptions;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using Microsoft.Azure.Functions.Worker.Converters;
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions;

namespace Microsoft.Azure.Functions.Worker
{
[SupportsDeferredBinding]
[AllowConverterFallback(true)]
[InputConverter(typeof(BlobStorageConverter))]
public sealed class BlobTriggerAttribute : TriggerBindingAttribute
{
private readonly string _blobPath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ public override void Configure(IFunctionsWorkerApplicationBuilder applicationBui
applicationBuilder.Services.AddAzureClientsCore(); // Adds AzureComponentFactory
applicationBuilder.Services.AddOptions<BlobStorageBindingOptions>();
applicationBuilder.Services.AddSingleton<IConfigureOptions<BlobStorageBindingOptions>, BlobStorageBindingOptionsSetup>();

applicationBuilder.Services.Configure<WorkerOptions>((workerOption) =>
{
workerOption.InputConverters.RegisterAt<BlobStorageConverter>(0);
});
}
}
}
1 change: 1 addition & 0 deletions test/DotNetWorkerTests/DotNetWorkerTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\extensions\Worker.Extensions.Storage.Blobs\src\Worker.Extensions.Storage.Blobs.csproj" />
<ProjectReference Include="..\..\extensions\Worker.Extensions.Abstractions\src\Worker.Extensions.Abstractions.csproj" />
<ProjectReference Include="..\..\extensions\Worker.Extensions.Http.AspNetCore\src\Worker.Extensions.Http.AspNetCore.csproj" />
<ProjectReference Include="..\..\extensions\Worker.Extensions.Http\src\Worker.Extensions.Http.csproj" />
Expand Down
84 changes: 84 additions & 0 deletions test/DotNetWorkerTests/GrpcFunctionDefinitionTests.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.Azure.Functions.Tests;
using Microsoft.Azure.Functions.Worker.Converters;
using Microsoft.Azure.Functions.Worker.Core;
using Microsoft.Azure.Functions.Worker.Grpc.Messages;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Azure.Functions.Worker.Invocation;
Expand Down Expand Up @@ -74,6 +79,74 @@ public void Creates()
});
}

[Fact]
public void GrpcFunctionDefinition_BlobInput_Creates()
{
using var testVariables = new TestScopedEnvironmentVariable("FUNCTIONS_WORKER_DIRECTORY", ".");

var bindingInfoProvider = new DefaultOutputBindingsInfoProvider();
var methodInfoLocator = new DefaultMethodInfoLocator();

string fullPathToThisAssembly = GetType().Assembly.Location;
var functionLoadRequest = new FunctionLoadRequest
{
FunctionId = "abc",
Metadata = new RpcFunctionMetadata
{
EntryPoint = $"Microsoft.Azure.Functions.Worker.Tests.{nameof(GrpcFunctionDefinitionTests)}+{nameof(MyBlobFunctionClass)}.{nameof(MyBlobFunctionClass.Run)}",
ScriptFile = Path.GetFileName(fullPathToThisAssembly),
Name = "myfunction"
}
};

// We base this on the request exclusively, not the binding attributes.
functionLoadRequest.Metadata.Bindings.Add("req", new BindingInfo { Type = "HttpTrigger", Direction = Direction.In });
functionLoadRequest.Metadata.Bindings.Add("$return", new BindingInfo { Type = "Http", Direction = Direction.Out });

FunctionDefinition definition = functionLoadRequest.ToFunctionDefinition(methodInfoLocator);

Assert.Equal(functionLoadRequest.FunctionId, definition.Id);
Assert.Equal(functionLoadRequest.Metadata.EntryPoint, definition.EntryPoint);
Assert.Equal(functionLoadRequest.Metadata.Name, definition.Name);
Assert.Equal(fullPathToThisAssembly, definition.PathToAssembly);

// Parameters
Assert.Collection(definition.Parameters,
p =>
{
Assert.Equal("req", p.Name);
Assert.Equal(typeof(HttpRequestData), p.Type);
},
q =>
{
Assert.Equal("myBlob", q.Name);
Assert.Equal(typeof(string), q.Type);
Assert.Contains(PropertyBagKeys.AllowConverterFallback, q.Properties.Keys);
Assert.Contains(PropertyBagKeys.BindingAttributeSupportedConverters, q.Properties.Keys);
Assert.True(true, q.Properties[PropertyBagKeys.AllowConverterFallback].ToString());
Assert.Contains(new Dictionary<Type, List<Type>>().ToString(), q.Properties[PropertyBagKeys.BindingAttributeSupportedConverters].ToString());
});

// InputBindings
Assert.Collection(definition.InputBindings,
p =>
{
Assert.Equal("req", p.Key);
Assert.Equal(BindingDirection.In, p.Value.Direction);
Assert.Equal("HttpTrigger", p.Value.Type);
});

// OutputBindings
Assert.Collection(definition.OutputBindings,
p =>
{
Assert.Equal("$return", p.Key);
Assert.Equal(BindingDirection.Out, p.Value.Direction);
Assert.Equal("Http", p.Value.Type);
});
}


private class MyFunctionClass
{
public HttpResponseData Run(HttpRequestData req)
Expand All @@ -89,5 +162,16 @@ public HttpResponseData Run(HttpRequestData req, CancellationToken cancellationT
return req.CreateResponse();
}
}

private class MyBlobFunctionClass
{
public HttpResponseData Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[BlobInput("input-container/{id}.txt")] string myBlob)
{
return req.CreateResponse();
}
}

}
}

0 comments on commit c2c6547

Please sign in to comment.