Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prep Extensions.Rpc release: merge main into release/main #2805

Merged
merged 24 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0f345be
Generators package version update (#2755)
surgupta-msft Oct 7, 2024
33047a0
Generator tests: Add transitive dependency for System.Text.Json v8.0.…
liliankasem Oct 8, 2024
7a9559a
Fixing Function Executor test
fabiocav Oct 10, 2024
9590def
Refactor WebJobs extension info (#2762)
satvu Oct 10, 2024
97e7048
skipBuildTagsForGitHubPullRequests when the PR is a fork (#2770)
satvu Oct 10, 2024
2684846
Bump System.Text.Json from 8.0.4 to 8.0.5 in /host/src/FunctionsNetHo…
dependabot[bot] Oct 11, 2024
f249435
re-use FunctionsWorkerApplicationBuilder if called multiple times (#2…
brettsam Oct 11, 2024
afd1006
Add worker extension validation to CI (#2764)
satvu Oct 11, 2024
04ce8b7
ignore rider temp files
SimonCropp Sep 10, 2024
9f278fa
Support SignalR trigger return value (#2771)
Y-Sindo Oct 12, 2024
52594e0
add skipBuildTagsForGitHubPullRequests for extensions (#2779)
satvu Oct 14, 2024
ad547ba
Fix typos in CI referencing test projects (#2773)
satvu Oct 14, 2024
f2c700d
Adding a null check before initiating the internal Activity (#2765)
RohitRanjanMS Oct 14, 2024
30fd904
Bump System.Text.Json to 8.0.5 (#2783)
liliankasem Oct 15, 2024
b1a94a1
Use full namespace for Task.FromResult in function metadata provider …
DL444 Oct 16, 2024
7b1bd29
Analyzer for Multiple-Output Binding Scenarios with ASP.NET Core Inte…
satvu Oct 16, 2024
6abd03d
Remove documentation tag (#2751)
vanillajonathan Oct 18, 2024
04e8bd1
Update global.json .net8 value (#2795)
satvu Oct 21, 2024
96db64d
initial fix of duplicate registrations if AddFunctionsWorkerCore call…
brettsam Oct 21, 2024
4b29c59
Ignoring fatal exceptions in InvocationHandler (#2789)
fabiocav Oct 22, 2024
2b83c35
Update nethost global json, update sample (#2797)
satvu Oct 22, 2024
0acbeec
Set extension RPC max message length (#2772)
jviau Oct 23, 2024
aba80d0
Update packages (#2800)
satvu Oct 23, 2024
27dd566
Merge branch 'main' into jviau/merge-release-main
jviau Oct 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,4 @@ Migrations/
local.settings.json
/tools/localpack.ps1
/.vscode
/.idea
10 changes: 10 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,14 @@
<SuppressTfmSupportBuildWarnings Condition="'$(TargetFramework)' == 'net5.0'">true</SuppressTfmSupportBuildWarnings>
</PropertyGroup>

<PropertyGroup>
<RepoRoot>$(MSBuildThisFileDirectory)</RepoRoot>
<EngRoot>$(RepoRoot)eng/</EngRoot>
<TargetsRoot>$(EngRoot)build/</TargetsRoot>
</PropertyGroup>

<PropertyGroup Condition="'$(TF_BUILD)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>

</Project>
2 changes: 1 addition & 1 deletion docs/analyzer-rules/AZFW0014.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# AZFW0011: Missing Registration for ASP.NET Core Integration
# AZFW0014: Missing Registration for ASP.NET Core Integration

| | Value |
|-|-|
Expand Down
44 changes: 44 additions & 0 deletions docs/analyzer-rules/AZFW0015.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# AZFW0015: Missing HttpResult attribute for multi-output function

| | Value |
|-|-|
| **Rule ID** |AZFW00015|
| **Category** |[Usage]|
| **Severity** |Error|

## Cause

This rule is triggered when a multi-output function is missing a `HttpResultAttribute` on the HTTP response type.

## Rule description

For [functions with multiple output bindings](https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=windows#multiple-output-bindings) using ASP.NET Core integration, the property correlating with the HTTP response needs to be decorated with the `HttpResultAttribute` in order to write the HTTP response correctly. Properties of the type `HttpResponseData` will still have their responses written correctly.

## How to fix violations

Add the attribute `[HttpResult]` (or `[HttpResultAttribute]`) to the relevant property. Example:

```csharp
public static class MultiOutput
{
[Function(nameof(MultiOutput))]
public static MyOutputType Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req,
FunctionContext context)
{
...
}
}

public class MyOutputType
{
[QueueOutput("myQueue")]
public string Name { get; set; }

[HttpResult]
public IActionResult HttpResponse { get; set; }
}
```

## When to suppress warnings

This rule should not be suppressed because this error will prevent the HTTP response from being written correctly.
46 changes: 46 additions & 0 deletions docs/analyzer-rules/AZFW0016.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# AZFW0016: Missing HttpResult attribute for multi-output function

| | Value |
|-|-|
| **Rule ID** |AZFW00016|
| **Category** |[Usage]|
| **Severity** |Warning|

## Cause

This rule is triggered when a multi-output function using `HttpResponseData` is missing a `HttpResultAttribute` on the HTTP response type.

## Rule description

Following the introduction of ASP.NET Core integration, for [functions with multiple output bindings](https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=windows#multiple-output-bindings), the property in a custom output type correlating with the HTTP response is expected to be decorated with the `HttpResultAttribute`.

`HttpResponseData` does not require this attribute for multi-output functions to work because support for it was available before the introduction of ASP.NET Core Integration. However, this is the expected convention moving forward as all other HTTP response types in this scenario will not work without this attribute.

## How to fix violations

Add the attribute `[HttpResult]` (or `[HttpResultAttribute]`) to the relevant property. Example:

```csharp
public static class MultiOutput
{
[Function(nameof(MultiOutput))]
public static MyOutputType Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req,
FunctionContext context)
{
...
}
}

public class MyOutputType
{
[QueueOutput("myQueue")]
public string Name { get; set; }

[HttpResult]
public HttpResponseData HttpResponse { get; set; }
}
```

## When to suppress warnings

This rule can be suppressed if there is no intention to migrate from `HttpResponseData` to other types (like `IActionResult`).
30 changes: 30 additions & 0 deletions eng/build/WorkerExtensions.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<Project>
<PropertyGroup>
<_ExtensionProjectTemplate>$(MSBuildThisFileDirectory)/extensionValidationProjectTemplate.txt</_ExtensionProjectTemplate>
<_ExtensionValidationLocation>$(IntermediateOutputPath)ExtensionValidation/</_ExtensionValidationLocation>
</PropertyGroup>

<Target Name="AddWebJobsExtensionInformation" BeforeTargets="GetAssemblyAttributes" Condition="'@(WebJobsExtension)' != ''">
<ItemGroup>
<_ExtensionInformationAttribute Include="@(WebJobsExtension->'Microsoft.Azure.Functions.Worker.Extensions.Abstractions.ExtensionInformationAttribute')">
<_Parameter1>%(WebJobsExtension.Identity)</_Parameter1>
<_Parameter2>%(WebJobsExtension.Version)</_Parameter2>
</_ExtensionInformationAttribute>
<AssemblyAttribute Include="@(_ExtensionInformationAttribute)" RemoveMetadata="Version" />
</ItemGroup>
</Target>

<Target Name="GenerateExtensionProject" AfterTargets="Compile" Condition="'@(WebJobsExtension)' != '' and '$(ContinuousIntegrationBuild)' == 'true'">
<MakeDir Directories="$(_ExtensionValidationLocation)" />
<WriteLinesToFile
File="$(_ExtensionValidationLocation)ExtensionValidation.csproj"
Lines="$([System.IO.File]::ReadAllText($(_ExtensionProjectTemplate))
.Replace('$PackageName$', '%(WebJobsExtension.Identity)')
.Replace('$PackageVersion$', '%(WebJobsExtension.Version)'))"
Overwrite="true" />
</Target>

<Target Name="RestoreGeneratedExtensionProject" AfterTargets="GenerateExtensionProject" Condition="'@(WebJobsExtension)' != '' and '$(ContinuousIntegrationBuild)' == 'true'">
<MSBuild Projects="$(_ExtensionValidationLocation)ExtensionValidation.csproj" Targets="Restore" />
</Target>
</Project>
10 changes: 10 additions & 0 deletions eng/build/extensionValidationProjectTemplate.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Library</OutputType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="$PackageName$" Version="$PackageVersion$" />
</ItemGroup>
</Project>
4 changes: 4 additions & 0 deletions eng/ci/public-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ extends:
image: 1es-windows-2022
os: windows

settings:
# PR's from forks do not have sufficient permissions to set tags.
skipBuildTagsForGitHubPullRequests: ${{ variables['System.PullRequest.IsFork'] }}

stages:
- stage: Test

Expand Down
10 changes: 1 addition & 9 deletions eng/ci/templates/jobs/run-unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,6 @@ jobs:
projects: |
**\DotNetWorker.Opentelemetry.Tests.csproj

- task: DotNetCoreCLI@2
displayName: Application Insights Tests
inputs:
command: test
arguments: -v n
projects: |
**\DotNetWorker.ApplicationInsights.Tests.csproj

- task: DotNetCoreCLI@2
displayName: Sdk Tests
inputs:
Expand All @@ -56,7 +48,7 @@ jobs:
projects: |
**\SdkTests.csproj
**\Sdk.Analyzers.Tests.csproj
**\Sdk.Generatior.Tests.csproj
**\Sdk.Generator.Tests.csproj

- task: DotNetCoreCLI@2
displayName: Extension Tests
Expand Down
8 changes: 8 additions & 0 deletions extensions/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project>

<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, $(_DirectoryBuildTargetsFile)))/$(_DirectoryBuildTargetsFile)"
Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, $(_DirectoryBuildTargetsFile)))' != '' " />

<Import Project="$(TargetsRoot)WorkerExtensions.targets" />

</Project>
4 changes: 4 additions & 0 deletions extensions/Worker.Extensions.CosmosDB/ci/public-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ extends:
image: 1es-windows-2022
os: windows

settings:
# PR's from forks do not have sufficient permissions to set tags.
skipBuildTagsForGitHubPullRequests: ${{ variables['System.PullRequest.IsFork'] }}

stages:
- stage: Test

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Runtime.CompilerServices;
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions;

[assembly: ExtensionInformation("Microsoft.Azure.WebJobs.Extensions.CosmosDB", "4.8.0")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@
<SharedReference Include="..\..\Worker.Extensions.Shared\Worker.Extensions.Shared.csproj" />
</ItemGroup>

<ItemGroup>
<WebJobsExtension Include="Microsoft.Azure.WebJobs.Extensions.CosmosDB" Version="4.8.0" />
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions extensions/Worker.Extensions.EventGrid/ci/public-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ extends:
image: 1es-windows-2022
os: windows

settings:
# PR's from forks do not have sufficient permissions to set tags.
skipBuildTagsForGitHubPullRequests: ${{ variables['System.PullRequest.IsFork'] }}

stages:
- stage: Test

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@
using System.Runtime.CompilerServices;
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions;

[assembly: ExtensionInformation("Microsoft.Azure.WebJobs.Extensions.EventGrid", "3.4.2")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@
<PackageReference Include="Azure.Messaging.EventGrid" Version="4.17.0" />
</ItemGroup>

<ItemGroup>
<WebJobsExtension Include="Microsoft.Azure.WebJobs.Extensions.EventGrid" Version="3.4.2" />
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions extensions/Worker.Extensions.EventHubs/ci/public-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ extends:
image: 1es-windows-2022
os: windows

settings:
# PR's from forks do not have sufficient permissions to set tags.
skipBuildTagsForGitHubPullRequests: ${{ variables['System.PullRequest.IsFork'] }}

stages:
- stage: Test

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Runtime.CompilerServices;
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions;

[assembly: ExtensionInformation("Microsoft.Azure.WebJobs.Extensions.EventHubs", "6.3.5")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@
<SharedReference Include="..\..\Worker.Extensions.Shared\Worker.Extensions.Shared.csproj" />
</ItemGroup>

<ItemGroup>
<WebJobsExtension Include="Microsoft.Azure.WebJobs.Extensions.EventHubs" Version="6.3.5" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore
{
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CodeFixForHttpResultAttribute)), Shared]
public sealed class CodeFixForHttpResultAttribute : CodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds =>
ImmutableArray.Create<string>(
DiagnosticDescriptors.MultipleOutputHttpTriggerWithoutHttpResultAttribute.Id,
DiagnosticDescriptors.MultipleOutputWithHttpResponseDataWithoutHttpResultAttribute.Id);

public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;

public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
Diagnostic diagnostic = context.Diagnostics.First();
context.RegisterCodeFix(new AddHttpResultAttribute(context.Document, diagnostic), diagnostic);

return Task.CompletedTask;
}

/// <summary>
/// CodeAction implementation which adds the HttpResultAttribute on the return type of a function using the multi-output bindings pattern.
/// </summary>
private sealed class AddHttpResultAttribute : CodeAction
{
private readonly Document _document;
private readonly Diagnostic _diagnostic;
private const string ExpectedAttributeName = "HttpResult";

internal AddHttpResultAttribute(Document document, Diagnostic diagnostic)
{
this._document = document;
this._diagnostic = diagnostic;
}

public override string Title => "Add HttpResultAttribute";

public override string EquivalenceKey => null;

/// <summary>
/// Asynchronously retrieves the modified <see cref="Document"/>, with the HttpResultAttribute added to the relevant property.
/// </summary>
/// <param name="cancellationToken">A token that can be used to propagate notifications that the operation should be canceled.</param>
/// <returns>An updated <see cref="Document"/> object.</returns>
protected override async Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
{
// Get the syntax root of the document
var root = await _document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var semanticModel = await _document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

var typeNode = root.FindNode(this._diagnostic.Location.SourceSpan)
.FirstAncestorOrSelf<TypeSyntax>();

var typeSymbol = semanticModel.GetSymbolInfo(typeNode).Symbol;
var typeDeclarationSyntaxReference = typeSymbol.DeclaringSyntaxReferences.FirstOrDefault();
if (typeDeclarationSyntaxReference is null)
{
return _document;
}

var typeDeclarationNode = await typeDeclarationSyntaxReference.GetSyntaxAsync(cancellationToken);

var propertyNode = typeDeclarationNode.DescendantNodes()
.OfType<PropertyDeclarationSyntax>()
.First(prop =>
{
var propertyType = semanticModel.GetTypeInfo(prop.Type).Type;
return propertyType != null && (propertyType.Name == "IActionResult" || propertyType.Name == "HttpResponseData" || propertyType.Name == "IResult");
});

var attribute = SyntaxFactory.Attribute(SyntaxFactory.IdentifierName(ExpectedAttributeName));

var newPropertyNode = propertyNode
.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(attribute)));

var newRoot = root.ReplaceNode(propertyNode, newPropertyNode);

return _document.WithSyntaxRoot(newRoot);
}
}
}
}
Loading
Loading