Skip to content

Commit

Permalink
Table converter (Azure#1506)
Browse files Browse the repository at this point in the history
* Add E2E tests for blob SDK type bindings (Azure#1360)

* Add analyzer for SupportsDeferredBindingAttribute (Azure#1367)

* Update SupportsDeferredBinding diagnostic code & update docs (Azure#1377)

* Revert "Remove types, tests & logic related to the SDK-binding feature (Azure#1374)"

This reverts commit eac5b19.

* Added unit tests for BlobStorageConverter (Azure#1370)

* Adding test project
* Added tests

* Initial changes

* Updating metadata

* Adding a test

* Code refactoring

* Cosmos DB converter for SDK-type support and samples (Azure#1406)

* Execution flow added

* Update pipeline variables to include tags (Azure#1427)

* Update extension variables to not use build number with tags (Azure#1429)

* Execution flow

* cleanup

* Cleanup

* Cleanup

* Cleanup execution flow

* Added test

* Adding tests

* code cleanup

* Code cleanup

* code refactor

* Added logic to check type before sending to converter

* Updated tests

* Removing advertised converters from options

* Adding options back

* Changes to check type

* updating type check logic

* correction in metadata generation

* code cleanup

* Test cleanup

* Added changes to support poco

* Metadata generation changes

* Changes on Invocation side

* correcting type check and tests

* Test for poco invocation support

* Added tests for poco invocation flows

* Metadata generator minor update

* Grpc definition update

* Added poco and poco collection check

* cleanup metadata generation

* Adding support for type collection

* code cleanup

* Fixing metadata gen

* Test fix

* Grpc definition fix

* Removing BlobContainerClient advertisement

* Readding containerclient

* Updated metadata generator

* Changes as per latest design

* code cleanup

* updatin tests input

* code cleanup

* Cleanup Metadata generation

* correcting converters fallback logic

* Removing converter advertisement on cosmos trigger

* Fixing failing test

* test check in

* Undo testing changes in sample app

* spacing fix

* updated tests

* non secret changes

* Addressing PR feedback

* e2e test work

* adding comments

* Removed json deserialization attribute

* Rename to AllowConverterFallback

* Addressing feedback

* Metada generation cleanup

* Test cleanup

* Addressing feedback

* Updated grpcFunctionDefinition for multiple inputConverterAttribute

* Removing cosmos converter registration

* Address PR feedback

* Address PR feedback

* Test fix

* Minor

* addressing comments

* getting e2e working

* Implement bypass deferred binding (Azure#1462)

Implement bypass deferred binding

* Build issue fix

* comments

* Update test/E2ETests/E2EApps/E2EApp/Table/TableInputBindingFunctions.cs

Co-authored-by: Lilian Kasem <likasem@microsoft.com>

* Adding check for PR in yml file (Azure#1546)

* addressing some more comments

* dependency

* one more dependency

* trying to compile lol

* seeing if tables project compiles with dependency

* removing local instance

* see if this compiles

* trying to remove test

* nvm adding it back

* adding keys to nuget.config

* trying to get feed

* trying again

* more yml

* fixing spacing

* ci.yml

* Add ability to bind to SBReceivedMessage (Azure#1313)

* another change

* trying again

* formatting changes

* changes

* updating worker.sdk package

* fixing unit test

* getting unit tests to pass

* fixing test

---------

Co-authored-by: Lilian Kasem <likasem@microsoft.com>
Co-authored-by: Surgupta <surgupta@microsoft.com>
Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
  • Loading branch information
4 people committed Oct 4, 2023
1 parent a396817 commit 99d2207
Show file tree
Hide file tree
Showing 14 changed files with 1,165 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
Expand Down Expand Up @@ -61,4 +61,4 @@ public void Configure(string name, BlobStorageBindingOptions options)
options.Credential = _componentFactory.CreateTokenCredential(connectionSection);
}
}
}
}
2 changes: 1 addition & 1 deletion extensions/Worker.Extensions.Tables/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@

### Microsoft.Azure.Functions.Worker.Extensions.Tables <version>

- <entry>
- Add abiility to bind table input to TableClient, TableEntity, and IEnumerable<TableEntity> (#1470)
7 changes: 7 additions & 0 deletions extensions/Worker.Extensions.Tables/src/Nuget.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>
6 changes: 0 additions & 6 deletions samples/WorkerBindingSamples/NuGet.Config

This file was deleted.

118 changes: 118 additions & 0 deletions samples/WorkerBindingSamples/Table/TableInputBindingSamples.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Net;
using Azure.Data.Tables;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;

namespace WorkerBindingSamples.Table
{
public class TableInputBindingSamples
{
private readonly ILogger<TableInputBindingSamples> _logger;

public TableInputBindingSamples(ILogger<TableInputBindingSamples> logger)
{
_logger = logger;
}

[Function(nameof(TableClientFunction))]
public async Task<HttpResponseData> TableClientFunction(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[TableInput("TableName")] TableClient table)
{
var tableEntity = table.QueryAsync<TableEntity>();
var response = req.CreateResponse(HttpStatusCode.OK);

await foreach (TableEntity val in tableEntity)
{
val.TryGetValue("Text", out var text);
_logger.LogInformation("Value of text: " + text);

await response.WriteStringAsync(text?.ToString() ?? "");
}

return response;
}

[Function(nameof(ReadTableDataFunction))]
public async Task<HttpResponseData> ReadTableDataFunction(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "items/{partitionKey}/{rowKey}")] HttpRequestData req,
[TableInput("TableName", "{partitionKey}", "{rowKey}")] TableEntity table)

{
table.TryGetValue("Text", out var text);
var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync(text?.ToString() ?? "");
return response;
}

[Function(nameof(ReadTableDataFunctionWithFilter))]
public async Task<HttpResponseData> ReadTableDataFunctionWithFilter(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[TableInput("TableName", "My Partition", 2, Filter = "RowKey ne 'value'")] IEnumerable<TableEntity> table)

{
List<string> tableList = new();
var response = req.CreateResponse(HttpStatusCode.OK);

foreach (TableEntity tableEntity in table)
{
tableEntity.TryGetValue("Text", out var text);
_logger.LogInformation("Value of text: " + text);
tableList.Add(text?.ToString() ?? "");
}

await response.WriteStringAsync(string.Join(",", tableList));
return response;
}

[Function(nameof(EnumerableFunction))]
public async Task<HttpResponseData> EnumerableFunction(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "items/{partitionKey}")] HttpRequestData req,
[TableInput("TableName", "{partitionKey}")] IEnumerable<TableEntity> tables)

{
var response = req.CreateResponse(HttpStatusCode.OK);
List<string> tableList = new();

foreach (TableEntity tableEntity in tables)
{
tableEntity.TryGetValue("Text", out var text);
_logger.LogInformation("Value of text: " + text);
tableList.Add((text?.ToString()) ?? "");
}

await response.WriteStringAsync(string.Join(",", tableList));
return response;
}

[Function(nameof(PocoFunction))]
public async Task<HttpResponseData> PocoFunction(
[HttpTrigger(AuthorizationLevel.Function, "get","post", Route = null)] HttpRequestData req,
[TableInput("TableName")] IEnumerable<MyEntity> entities,
FunctionContext executionContext)
{
var response = req.CreateResponse(HttpStatusCode.OK);
List<string> entityList = new();

foreach (MyEntity entity in entities)
{
_logger.LogInformation($"Text: {entity.Text}");
entityList.Add((entity.Text ?? "").ToString());
}

await response.WriteStringAsync(string.Join(",", entityList));
return response;
}
}

public class MyEntity
{
public string? Text { get; set; }
public string? PartitionKey { get; set; }
public string? RowKey { get; set; }
}
}
1 change: 1 addition & 0 deletions test/E2ETests/E2ETests/E2ETests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Azure.Data.Tables" Version="12.8.0" />
</ItemGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions test/FunctionMetadataGeneratorTests/SdkTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<ItemGroup>
<ProjectReference Include="..\..\extensions\Worker.Extensions.Http\src\Worker.Extensions.Http.csproj" />
<ProjectReference Include="..\..\extensions\Worker.Extensions.EventHubs\src\Worker.Extensions.EventHubs.csproj" />
<ProjectReference Include="..\..\extensions\Worker.Extensions.Tables\src\Worker.Extensions.Tables.csproj" />
<ProjectReference Include="..\..\extensions\Worker.Extensions.ServiceBus\src\Worker.Extensions.ServiceBus.csproj" />
<ProjectReference Include="..\..\extensions\Worker.Extensions.Storage\src\Worker.Extensions.Storage.csproj" />
<ProjectReference Include="..\..\extensions\Worker.Extensions.Tables\src\Worker.Extensions.Tables.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,190 @@
[
{
"name": "TableClientFunction",
"scriptFile": "WorkerBindingSamples.dll",
"entryPoint": "WorkerBindingSamples.Table.TableInputBindingSamples.TableClientFunction",
"language": "dotnet-isolated",
"properties": {
"IsCodeless": false
},
"bindings": [
{
"name": "req",
"direction": "In",
"type": "httpTrigger",
"authLevel": "Function",
"methods": [
"get",
"post"
],
"properties": {}
},
{
"name": "table",
"direction": "In",
"type": "table",
"tableName": "TableName",
"properties": {
"supportsDeferredBinding": "True"
}
},
{
"name": "$return",
"type": "http",
"direction": "Out"
}
]
},
{
"name": "ReadTableDataFunction",
"scriptFile": "WorkerBindingSamples.dll",
"entryPoint": "WorkerBindingSamples.Table.TableInputBindingSamples.ReadTableDataFunction",
"language": "dotnet-isolated",
"properties": {
"IsCodeless": false
},
"bindings": [
{
"name": "req",
"direction": "In",
"type": "httpTrigger",
"authLevel": "Function",
"methods": [
"get",
"post"
],
"route": "items/{partitionKey}/{rowKey}",
"properties": {}
},
{
"name": "table",
"direction": "In",
"type": "table",
"tableName": "TableName",
"partitionKey": "{partitionKey}",
"rowKey": "{rowKey}",
"properties": {
"supportsDeferredBinding": "True"
}
},
{
"name": "$return",
"type": "http",
"direction": "Out"
}
]
},
{
"name": "ReadTableDataFunctionWithFilter",
"scriptFile": "WorkerBindingSamples.dll",
"entryPoint": "WorkerBindingSamples.Table.TableInputBindingSamples.ReadTableDataFunctionWithFilter",
"language": "dotnet-isolated",
"properties": {
"IsCodeless": false
},
"bindings": [
{
"name": "req",
"direction": "In",
"type": "httpTrigger",
"authLevel": "Function",
"methods": [
"get",
"post"
],
"properties": {}
},
{
"name": "table",
"direction": "In",
"type": "table",
"tableName": "TableName",
"partitionKey": "My Partition",
"take": 2,
"filter": "RowKey ne 'value'",
"properties": {
"supportsDeferredBinding": "True"
}
},
{
"name": "$return",
"type": "http",
"direction": "Out"
}
]
},
{
"name": "EnumerableFunction",
"scriptFile": "WorkerBindingSamples.dll",
"entryPoint": "WorkerBindingSamples.Table.TableInputBindingSamples.EnumerableFunction",
"language": "dotnet-isolated",
"properties": {
"IsCodeless": false
},
"bindings": [
{
"name": "req",
"direction": "In",
"type": "httpTrigger",
"authLevel": "Function",
"methods": [
"get",
"post"
],
"route": "items/{partitionKey}",
"properties": {}
},
{
"name": "tables",
"direction": "In",
"type": "table",
"tableName": "TableName",
"partitionKey": "{partitionKey}",
"properties": {
"supportsDeferredBinding": "True"
}
},
{
"name": "$return",
"type": "http",
"direction": "Out"
}
]
},
{
"name": "PocoFunction",
"scriptFile": "WorkerBindingSamples.dll",
"entryPoint": "WorkerBindingSamples.Table.TableInputBindingSamples.PocoFunction",
"language": "dotnet-isolated",
"properties": {
"IsCodeless": false
},
"bindings": [
{
"name": "req",
"direction": "In",
"type": "httpTrigger",
"authLevel": "Function",
"methods": [
"get",
"post"
],
"properties": {}
},
{
"name": "entities",
"direction": "In",
"type": "table",
"tableName": "TableName",
"properties": {}
},
{
"name": "$return",
"type": "http",
"direction": "Out"
}
]
},
{
"name": "BlobInputClientFunction",
"scriptFile": "WorkerBindingSamples.dll",
Expand Down
5 changes: 4 additions & 1 deletion test/SdkE2ETests/PublishTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,10 @@ private async Task RunPublishTestForSdkTypeBindings(string outputDir, string add
@"./.azurefunctions/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.dll"),
new Extension("AzureStorageQueues",
"Microsoft.Azure.WebJobs.Extensions.Storage.AzureStorageQueuesWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.Storage.Queues, Version=5.0.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8",
@"./.azurefunctions/Microsoft.Azure.WebJobs.Extensions.Storage.Queues.dll")
@"./.azurefunctions/Microsoft.Azure.WebJobs.Extensions.Storage.Queues.dll"),
new Extension("AzureTables",
"Microsoft.Azure.WebJobs.Extensions.Tables.AzureTablesWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.Tables, Version=1.2.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8",
@"./.azurefunctions/Microsoft.Azure.WebJobs.Extensions.Tables.dll")
}
});
Assert.True(JToken.DeepEquals(extensionsJsonContents, expected), $"Actual: {extensionsJsonContents}{Environment.NewLine}Expected: {expected}");
Expand Down

0 comments on commit 99d2207

Please sign in to comment.