From 4766c8ecfb737552b483a5005a74ed35d11b7f5c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 08:44:43 -0800 Subject: [PATCH 001/174] [release/9.x] Update dependencies from dotnet/installer (#5933) * Update dependencies from https://github.com/dotnet/installer build 20240130.9 Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.1.24080.2 -> To Version 9.0.100-preview.1.24080.9 * Update dependencies from https://github.com/dotnet/installer build 20240130.9 Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.1.24080.2 -> To Version 9.0.100-preview.1.24080.9 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 83a4e6bd4ec..af8fcce23fd 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade dd50030a0278e8c82f45624446fbec120b83c26b - + https://github.com/dotnet/installer - b8dce67ebe366f971308217b0e703e2a25eae16e + 46ba867793d0599759fbb8f1ac07a3f75cb2ea9d https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index 512d0e8996b..d16c303f9fb 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -65,7 +65,7 @@ 8.0.0-preview.24079.1 8.0.0-preview.24079.1 - 9.0.100-preview.1.24080.2 + 9.0.100-preview.1.24080.9 9.0.0-preview.24075.1 From 12521196593acceef9ca697cc39abd9515512606 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 08:45:07 -0800 Subject: [PATCH 002/174] Update dependencies from https://github.com/dotnet/arcade build 20240130.3 (#5937) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24080.1 -> To Version 9.0.0-beta.24080.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 +++++++++---------- eng/Versions.props | 6 +++--- .../templates/job/source-index-stage1.yml | 2 +- global.json | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index af8fcce23fd..13bcc679149 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -22,29 +22,29 @@ https://github.com/dotnet/roslyn-analyzers bf54e2bebc28004dec0311dc4083bcff4fd44cdb - + https://github.com/dotnet/arcade - dd50030a0278e8c82f45624446fbec120b83c26b + b4e9225c6c2f9da42fbb611a5e8942a08476fe89 - + https://github.com/dotnet/arcade - dd50030a0278e8c82f45624446fbec120b83c26b + b4e9225c6c2f9da42fbb611a5e8942a08476fe89 - + https://github.com/dotnet/arcade - dd50030a0278e8c82f45624446fbec120b83c26b + b4e9225c6c2f9da42fbb611a5e8942a08476fe89 - + https://github.com/dotnet/arcade - dd50030a0278e8c82f45624446fbec120b83c26b + b4e9225c6c2f9da42fbb611a5e8942a08476fe89 https://github.com/dotnet/installer 46ba867793d0599759fbb8f1ac07a3f75cb2ea9d - + https://github.com/dotnet/arcade - dd50030a0278e8c82f45624446fbec120b83c26b + b4e9225c6c2f9da42fbb611a5e8942a08476fe89 https://github.com/dotnet/symstore diff --git a/eng/Versions.props b/eng/Versions.props index d16c303f9fb..b9bb18e3348 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -53,9 +53,9 @@ --> - 9.0.0-beta.24080.1 - 9.0.0-beta.24080.1 - 9.0.0-beta.24080.1 + 9.0.0-beta.24080.3 + 9.0.0-beta.24080.3 + 9.0.0-beta.24080.3 9.0.0-preview.1.24075.4 9.0.0-preview.1.24075.4 diff --git a/eng/common/templates/job/source-index-stage1.yml b/eng/common/templates/job/source-index-stage1.yml index 79523366262..b5a3e5c4a6c 100644 --- a/eng/common/templates/job/source-index-stage1.yml +++ b/eng/common/templates/job/source-index-stage1.yml @@ -1,6 +1,6 @@ parameters: runAsPublic: false - sourceIndexPackageVersion: 1.0.1-20231213.4 + sourceIndexPackageVersion: 1.0.1-20240129.2 sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" preSteps: [] diff --git a/global.json b/global.json index d8a0624cd9e..f0c6a2282b9 100644 --- a/global.json +++ b/global.json @@ -31,7 +31,7 @@ }, "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.0", - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24080.1", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24080.1" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24080.3", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24080.3" } } From 9f0be88f9f5757e2e3e5b76bd9f3b59ced5d1d69 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 09:11:27 -0800 Subject: [PATCH 003/174] Update dependencies from https://github.com/dotnet/installer build 20240201.2 (#5948) Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.1.24080.9 -> To Version 9.0.100-preview.1.24101.2 Dependency coherency updates Microsoft.AspNetCore.App.Runtime.win-x64,Microsoft.NETCore.App.Runtime.win-x64,VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0,VS.Redist.Common.NetCore.SharedFramework.x64.9.0 From Version 9.0.0-preview.1.24075.4 -> To Version 9.0.0-preview.1.24081.5 (parent: Microsoft.Dotnet.Sdk.Internal Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 7d2e38b934d..c5f7dbd988a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/aspnetcore - 1d58b24591820b2a134cfc0a5e3154bf9fe65cb4 + b1beadfe0ad3d02eb5207681a5328793c4b3822c https://github.com/dotnet/diagnostics @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade b4e9225c6c2f9da42fbb611a5e8942a08476fe89 - + https://github.com/dotnet/installer - 46ba867793d0599759fbb8f1ac07a3f75cb2ea9d + 6bbd460f4db0a37cafeb04a1ed2d798ae56b0283 https://github.com/dotnet/arcade @@ -50,17 +50,17 @@ https://github.com/dotnet/symstore 0c7b75fc18db3a4f9b7737ae55a0d04e913ac40c - + https://github.com/dotnet/runtime - b4aa81d9da52616ac18e6eb584e37a08cfb2ba87 + 1d1bf92fcf43aa6981804dc53c5174445069c9e4 - + https://github.com/dotnet/aspnetcore - 1d58b24591820b2a134cfc0a5e3154bf9fe65cb4 + b1beadfe0ad3d02eb5207681a5328793c4b3822c - + https://github.com/dotnet/runtime - b4aa81d9da52616ac18e6eb584e37a08cfb2ba87 + 1d1bf92fcf43aa6981804dc53c5174445069c9e4 diff --git a/eng/Versions.props b/eng/Versions.props index ea393172f65..fd133a55c20 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -57,20 +57,20 @@ 9.0.0-beta.24080.3 9.0.0-beta.24080.3 - 9.0.0-preview.1.24075.4 - 9.0.0-preview.1.24075.4 + 9.0.0-preview.1.24081.5 + 9.0.0-preview.1.24081.5 2.0.0-beta4.24068.1 8.0.0-preview.24080.1 8.0.0-preview.24080.1 - 9.0.100-preview.1.24080.9 + 9.0.100-preview.1.24101.2 9.0.0-preview.24075.1 - 9.0.0-preview.1.24074.8 - 9.0.0-preview.1.24074.8 + 9.0.0-preview.1.24080.9 + 9.0.0-preview.1.24080.9 1.0.507901 From 8308473abf6b3bc85129ad6a650fd78e1d462e22 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 11:52:47 -0800 Subject: [PATCH 004/174] Update dependencies from https://github.com/dotnet/arcade build 20240131.4 (#5945) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24080.3 -> To Version 9.0.0-beta.24081.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 6 +++--- eng/common/sdk-task.ps1 | 2 +- eng/common/tools.ps1 | 4 ++-- global.json | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c5f7dbd988a..e921eff25e0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -22,29 +22,29 @@ https://github.com/dotnet/roslyn-analyzers bf54e2bebc28004dec0311dc4083bcff4fd44cdb - + https://github.com/dotnet/arcade - b4e9225c6c2f9da42fbb611a5e8942a08476fe89 + 438a8e2488313fb3aa1b24a741a85c2669ee7e0d - + https://github.com/dotnet/arcade - b4e9225c6c2f9da42fbb611a5e8942a08476fe89 + 438a8e2488313fb3aa1b24a741a85c2669ee7e0d - + https://github.com/dotnet/arcade - b4e9225c6c2f9da42fbb611a5e8942a08476fe89 + 438a8e2488313fb3aa1b24a741a85c2669ee7e0d - + https://github.com/dotnet/arcade - b4e9225c6c2f9da42fbb611a5e8942a08476fe89 + 438a8e2488313fb3aa1b24a741a85c2669ee7e0d https://github.com/dotnet/installer 6bbd460f4db0a37cafeb04a1ed2d798ae56b0283 - + https://github.com/dotnet/arcade - b4e9225c6c2f9da42fbb611a5e8942a08476fe89 + 438a8e2488313fb3aa1b24a741a85c2669ee7e0d https://github.com/dotnet/symstore diff --git a/eng/Versions.props b/eng/Versions.props index fd133a55c20..a85ddd512b8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -53,9 +53,9 @@ --> - 9.0.0-beta.24080.3 - 9.0.0-beta.24080.3 - 9.0.0-beta.24080.3 + 9.0.0-beta.24081.4 + 9.0.0-beta.24081.4 + 9.0.0-beta.24081.4 9.0.0-preview.1.24081.5 9.0.0-preview.1.24081.5 diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 index 73828dd30d3..091023970f1 100644 --- a/eng/common/sdk-task.ps1 +++ b/eng/common/sdk-task.ps1 @@ -64,7 +64,7 @@ try { $GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty } if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) { - $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.8.1-2" -MemberType NoteProperty + $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.8.5" -MemberType NoteProperty } if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") { $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 0da65b5748a..a8f8edb3291 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -379,8 +379,8 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = # If the version of msbuild is going to be xcopied, # use this version. Version matches a package here: - # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/RoslynTools.MSBuild/versions/17.8.1-2 - $defaultXCopyMSBuildVersion = '17.8.1-2' + # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/RoslynTools.MSBuild/versions/17.8.5 + $defaultXCopyMSBuildVersion = '17.8.5' if (!$vsRequirements) { if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') { diff --git a/global.json b/global.json index f0c6a2282b9..aa1271b9ff9 100644 --- a/global.json +++ b/global.json @@ -31,7 +31,7 @@ }, "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.0", - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24080.3", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24080.3" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24081.4", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24081.4" } } From 969981e1f08255701ac5c1fc0ee08071c6e5ca63 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 14:50:09 -0800 Subject: [PATCH 005/174] Fixup dependencies (#5949) (#5950) (#5951) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Wiktor Kopec --- eng/dependabot/Versions.props | 2 +- eng/dependabot/net6.0/Versions.props | 2 +- eng/dependabot/net7.0/Versions.props | 2 +- eng/dependabot/net8.0/Versions.props | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/dependabot/Versions.props b/eng/dependabot/Versions.props index e070f1328e9..befaf63d821 100644 --- a/eng/dependabot/Versions.props +++ b/eng/dependabot/Versions.props @@ -5,7 +5,7 @@ 1.10.4 12.19.1 12.17.1 - 2.15.3 + 2.16.1 1.6.11 4.3.2 5.0.0 diff --git a/eng/dependabot/net6.0/Versions.props b/eng/dependabot/net6.0/Versions.props index fef6e983b2a..d3ee0d85e2d 100644 --- a/eng/dependabot/net6.0/Versions.props +++ b/eng/dependabot/net6.0/Versions.props @@ -10,6 +10,6 @@ 6.0.0 - 6.0.25 + 6.0.26 diff --git a/eng/dependabot/net7.0/Versions.props b/eng/dependabot/net7.0/Versions.props index 8e02e196398..9081b609ba5 100644 --- a/eng/dependabot/net7.0/Versions.props +++ b/eng/dependabot/net7.0/Versions.props @@ -10,6 +10,6 @@ 7.0.0 - 7.0.14 + 7.0.15 diff --git a/eng/dependabot/net8.0/Versions.props b/eng/dependabot/net8.0/Versions.props index 98e5ea8d781..bd2a060ebc6 100644 --- a/eng/dependabot/net8.0/Versions.props +++ b/eng/dependabot/net8.0/Versions.props @@ -10,6 +10,6 @@ 8.0.0 - 8.0.0 + 8.0.1 From c723cdf4fa40600cf5a76a5b14573b92d318f68e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 09:22:01 -0800 Subject: [PATCH 006/174] Update dependencies from https://github.com/dotnet/arcade build 20240201.2 (#5958) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24081.4 -> To Version 9.0.0-beta.24101.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 6 +++--- global.json | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e921eff25e0..53b070c67cc 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -22,29 +22,29 @@ https://github.com/dotnet/roslyn-analyzers bf54e2bebc28004dec0311dc4083bcff4fd44cdb - + https://github.com/dotnet/arcade - 438a8e2488313fb3aa1b24a741a85c2669ee7e0d + db8765409d91a7ac626f5ff932459876a5bea9c6 - + https://github.com/dotnet/arcade - 438a8e2488313fb3aa1b24a741a85c2669ee7e0d + db8765409d91a7ac626f5ff932459876a5bea9c6 - + https://github.com/dotnet/arcade - 438a8e2488313fb3aa1b24a741a85c2669ee7e0d + db8765409d91a7ac626f5ff932459876a5bea9c6 - + https://github.com/dotnet/arcade - 438a8e2488313fb3aa1b24a741a85c2669ee7e0d + db8765409d91a7ac626f5ff932459876a5bea9c6 https://github.com/dotnet/installer 6bbd460f4db0a37cafeb04a1ed2d798ae56b0283 - + https://github.com/dotnet/arcade - 438a8e2488313fb3aa1b24a741a85c2669ee7e0d + db8765409d91a7ac626f5ff932459876a5bea9c6 https://github.com/dotnet/symstore diff --git a/eng/Versions.props b/eng/Versions.props index a85ddd512b8..1a4c09cfb84 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -53,9 +53,9 @@ --> - 9.0.0-beta.24081.4 - 9.0.0-beta.24081.4 - 9.0.0-beta.24081.4 + 9.0.0-beta.24101.2 + 9.0.0-beta.24101.2 + 9.0.0-beta.24101.2 9.0.0-preview.1.24081.5 9.0.0-preview.1.24081.5 diff --git a/global.json b/global.json index aa1271b9ff9..fd5699cf856 100644 --- a/global.json +++ b/global.json @@ -31,7 +31,7 @@ }, "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.0", - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24081.4", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24081.4" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24101.2", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24101.2" } } From 803bd17c80da43f40b5657ab0837d24281453e6e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 09:23:58 -0800 Subject: [PATCH 007/174] Update dependencies from https://github.com/dotnet/command-line-api build 20240201.1 (#5961) System.CommandLine From Version 2.0.0-beta4.24068.1 -> To Version 2.0.0-beta4.24101.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 53b070c67cc..bb19c6fee98 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -12,9 +12,9 @@ https://github.com/dotnet/diagnostics ea5321da3def7bd803c356504e681edc64ca4629 - + https://github.com/dotnet/command-line-api - ecd2ce5eafbba3008a7d4f5d04b025d30928c812 + 3674f88896ded1be30c77b14196773372a2ddfac diff --git a/eng/Versions.props b/eng/Versions.props index 1a4c09cfb84..0848bb35ced 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -60,7 +60,7 @@ 9.0.0-preview.1.24081.5 9.0.0-preview.1.24081.5 - 2.0.0-beta4.24068.1 + 2.0.0-beta4.24101.1 8.0.0-preview.24080.1 8.0.0-preview.24080.1 From ec6fec47afc0580d81de91c64c64411e4c2ec03a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 10:59:05 -0800 Subject: [PATCH 008/174] Update dependencies from https://github.com/dotnet/installer build 20240201.4 (#5962) Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.1.24101.2 -> To Version 9.0.100-preview.1.24101.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index bb19c6fee98..0a0bd6d0714 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade db8765409d91a7ac626f5ff932459876a5bea9c6 - + https://github.com/dotnet/installer - 6bbd460f4db0a37cafeb04a1ed2d798ae56b0283 + 103ff6d4866ae1feff84a1865df0c1a7494ceffc https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index 0848bb35ced..2003a9deecf 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -65,7 +65,7 @@ 8.0.0-preview.24080.1 8.0.0-preview.24080.1 - 9.0.100-preview.1.24101.2 + 9.0.100-preview.1.24101.4 9.0.0-preview.24075.1 From 8510338d9fbf20afe68269fec1f4ef7bbf416ca0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 17:03:03 -0800 Subject: [PATCH 009/174] Update dependencies from https://github.com/dotnet/diagnostics build 20240202.2 (#5977) Microsoft.Diagnostics.Monitoring , Microsoft.Diagnostics.Monitoring.EventPipe From Version 8.0.0-preview.24080.1 -> To Version 8.0.510202 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0a0bd6d0714..6370cf622c7 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -4,13 +4,13 @@ https://github.com/dotnet/aspnetcore b1beadfe0ad3d02eb5207681a5328793c4b3822c - + https://github.com/dotnet/diagnostics - ea5321da3def7bd803c356504e681edc64ca4629 + 3cdae8a23a1b060baa09703b39eeee71474e1908 - + https://github.com/dotnet/diagnostics - ea5321da3def7bd803c356504e681edc64ca4629 + 3cdae8a23a1b060baa09703b39eeee71474e1908 https://github.com/dotnet/command-line-api diff --git a/eng/Versions.props b/eng/Versions.props index 2003a9deecf..3fb7fb2052d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -62,8 +62,8 @@ 2.0.0-beta4.24101.1 - 8.0.0-preview.24080.1 - 8.0.0-preview.24080.1 + 8.0.510202 + 8.0.510202 9.0.100-preview.1.24101.4 From bbbe9ebd26e5c6d8da879024053e892fa81b96dd Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 17:03:27 -0800 Subject: [PATCH 010/174] [release/9.x] Update dependencies from dotnet/command-line-api (#5973) * Update dependencies from https://github.com/dotnet/command-line-api build 20240202.1 System.CommandLine From Version 2.0.0-beta4.24101.1 -> To Version 2.0.0-beta4.24102.1 * Update dependencies from https://github.com/dotnet/command-line-api build 20240202.1 System.CommandLine From Version 2.0.0-beta4.24101.1 -> To Version 2.0.0-beta4.24102.1 * Update dependencies from https://github.com/dotnet/command-line-api build 20240202.1 System.CommandLine From Version 2.0.0-beta4.24101.1 -> To Version 2.0.0-beta4.24102.1 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6370cf622c7..abee1c55f2e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -12,9 +12,9 @@ https://github.com/dotnet/diagnostics 3cdae8a23a1b060baa09703b39eeee71474e1908 - + https://github.com/dotnet/command-line-api - 3674f88896ded1be30c77b14196773372a2ddfac + 46fea71e3d98dad0d676950522004b7f295dd372 diff --git a/eng/Versions.props b/eng/Versions.props index 3fb7fb2052d..443537cbe89 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -60,7 +60,7 @@ 9.0.0-preview.1.24081.5 9.0.0-preview.1.24081.5 - 2.0.0-beta4.24101.1 + 2.0.0-beta4.24102.1 8.0.510202 8.0.510202 From 1e4f1481cbc1345c1b668454e52f17c00e3670df Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 17:03:57 -0800 Subject: [PATCH 011/174] [release/9.x] Update dependencies from dotnet/arcade (#5971) * Update dependencies from https://github.com/dotnet/arcade build 20240202.4 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24101.2 -> To Version 9.0.0-beta.24102.4 * Update dependencies from https://github.com/dotnet/arcade build 20240202.4 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24101.2 -> To Version 9.0.0-beta.24102.4 * Update dependencies from https://github.com/dotnet/arcade build 20240202.4 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24101.2 -> To Version 9.0.0-beta.24102.4 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 6 +++--- global.json | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index abee1c55f2e..a02b5707c5c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -22,29 +22,29 @@ https://github.com/dotnet/roslyn-analyzers bf54e2bebc28004dec0311dc4083bcff4fd44cdb - + https://github.com/dotnet/arcade - db8765409d91a7ac626f5ff932459876a5bea9c6 + 2fb543a45580400a559b5ae41c96a815ea14dac5 - + https://github.com/dotnet/arcade - db8765409d91a7ac626f5ff932459876a5bea9c6 + 2fb543a45580400a559b5ae41c96a815ea14dac5 - + https://github.com/dotnet/arcade - db8765409d91a7ac626f5ff932459876a5bea9c6 + 2fb543a45580400a559b5ae41c96a815ea14dac5 - + https://github.com/dotnet/arcade - db8765409d91a7ac626f5ff932459876a5bea9c6 + 2fb543a45580400a559b5ae41c96a815ea14dac5 https://github.com/dotnet/installer 103ff6d4866ae1feff84a1865df0c1a7494ceffc - + https://github.com/dotnet/arcade - db8765409d91a7ac626f5ff932459876a5bea9c6 + 2fb543a45580400a559b5ae41c96a815ea14dac5 https://github.com/dotnet/symstore diff --git a/eng/Versions.props b/eng/Versions.props index 443537cbe89..e7cc1c9e0c9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -53,9 +53,9 @@ --> - 9.0.0-beta.24101.2 - 9.0.0-beta.24101.2 - 9.0.0-beta.24101.2 + 9.0.0-beta.24102.4 + 9.0.0-beta.24102.4 + 9.0.0-beta.24102.4 9.0.0-preview.1.24081.5 9.0.0-preview.1.24081.5 diff --git a/global.json b/global.json index fd5699cf856..75ae5dc037e 100644 --- a/global.json +++ b/global.json @@ -31,7 +31,7 @@ }, "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.0", - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24101.2", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24101.2" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24102.4", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24102.4" } } From e920ace469acaca8ad6f4163820da419cc703841 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 10:36:14 -0800 Subject: [PATCH 012/174] Update dependencies from https://github.com/dotnet/arcade build 20240205.3 (#5986) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24102.4 -> To Version 9.0.0-beta.24105.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 6 +++--- eng/common/native/init-os-and-arch.sh | 4 ++++ eng/common/tools.ps1 | 6 +++--- global.json | 4 ++-- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a02b5707c5c..d40b7b16224 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -22,29 +22,29 @@ https://github.com/dotnet/roslyn-analyzers bf54e2bebc28004dec0311dc4083bcff4fd44cdb - + https://github.com/dotnet/arcade - 2fb543a45580400a559b5ae41c96a815ea14dac5 + 8cfc9489d3e51071fedec9dcb99071dc912718bd - + https://github.com/dotnet/arcade - 2fb543a45580400a559b5ae41c96a815ea14dac5 + 8cfc9489d3e51071fedec9dcb99071dc912718bd - + https://github.com/dotnet/arcade - 2fb543a45580400a559b5ae41c96a815ea14dac5 + 8cfc9489d3e51071fedec9dcb99071dc912718bd - + https://github.com/dotnet/arcade - 2fb543a45580400a559b5ae41c96a815ea14dac5 + 8cfc9489d3e51071fedec9dcb99071dc912718bd https://github.com/dotnet/installer 103ff6d4866ae1feff84a1865df0c1a7494ceffc - + https://github.com/dotnet/arcade - 2fb543a45580400a559b5ae41c96a815ea14dac5 + 8cfc9489d3e51071fedec9dcb99071dc912718bd https://github.com/dotnet/symstore diff --git a/eng/Versions.props b/eng/Versions.props index e7cc1c9e0c9..092279bd845 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -53,9 +53,9 @@ --> - 9.0.0-beta.24102.4 - 9.0.0-beta.24102.4 - 9.0.0-beta.24102.4 + 9.0.0-beta.24105.3 + 9.0.0-beta.24105.3 + 9.0.0-beta.24105.3 9.0.0-preview.1.24081.5 9.0.0-preview.1.24081.5 diff --git a/eng/common/native/init-os-and-arch.sh b/eng/common/native/init-os-and-arch.sh index e693617a6c2..caa448ff030 100644 --- a/eng/common/native/init-os-and-arch.sh +++ b/eng/common/native/init-os-and-arch.sh @@ -35,6 +35,10 @@ fi case "$CPUName" in arm64|aarch64) arch=arm64 + if [ "$(getconf LONG_BIT)" -lt 64 ]; then + # This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS) + arch=arm + fi ;; loongarch64) diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index a8f8edb3291..7d8dc89b919 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -379,7 +379,7 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = # If the version of msbuild is going to be xcopied, # use this version. Version matches a package here: - # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/RoslynTools.MSBuild/versions/17.8.5 + # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.8.5 $defaultXCopyMSBuildVersion = '17.8.5' if (!$vsRequirements) { @@ -445,7 +445,7 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = if ($xcopyMSBuildVersion.Trim() -ine "none") { $vsInstallDir = InitializeXCopyMSBuild $xcopyMSBuildVersion $install if ($vsInstallDir -eq $null) { - throw "Could not xcopy msbuild. Please check that package 'RoslynTools.MSBuild @ $xcopyMSBuildVersion' exists on feed 'dotnet-eng'." + throw "Could not xcopy msbuild. Please check that package 'Microsoft.DotNet.Arcade.MSBuild.Xcopy @ $xcopyMSBuildVersion' exists on feed 'dotnet-eng'." } } if ($vsInstallDir -eq $null) { @@ -482,7 +482,7 @@ function InstallXCopyMSBuild([string]$packageVersion) { } function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) { - $packageName = 'RoslynTools.MSBuild' + $packageName = 'Microsoft.DotNet.Arcade.MSBuild.Xcopy' $packageDir = Join-Path $ToolsDir "msbuild\$packageVersion" $packagePath = Join-Path $packageDir "$packageName.$packageVersion.nupkg" diff --git a/global.json b/global.json index 75ae5dc037e..a658ae62e0a 100644 --- a/global.json +++ b/global.json @@ -31,7 +31,7 @@ }, "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.0", - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24102.4", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24102.4" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24105.3", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24105.3" } } From a34920d2bd3f69dc9bda7fb07ad8855bb2ab025f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 11:03:21 -0800 Subject: [PATCH 013/174] Update dependencies from https://github.com/dotnet/diagnostics build 20240205.1 (#5989) Microsoft.Diagnostics.Monitoring , Microsoft.Diagnostics.Monitoring.EventPipe From Version 8.0.510202 -> To Version 8.0.510501 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d40b7b16224..7876a032003 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -4,13 +4,13 @@ https://github.com/dotnet/aspnetcore b1beadfe0ad3d02eb5207681a5328793c4b3822c - + https://github.com/dotnet/diagnostics - 3cdae8a23a1b060baa09703b39eeee71474e1908 + 8c08c89a0643d31db91e119b1adb463be3e0ffe5 - + https://github.com/dotnet/diagnostics - 3cdae8a23a1b060baa09703b39eeee71474e1908 + 8c08c89a0643d31db91e119b1adb463be3e0ffe5 https://github.com/dotnet/command-line-api diff --git a/eng/Versions.props b/eng/Versions.props index 092279bd845..40df7fbd914 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -62,8 +62,8 @@ 2.0.0-beta4.24102.1 - 8.0.510202 - 8.0.510202 + 8.0.510501 + 8.0.510501 9.0.100-preview.1.24101.4 From f44ae3f4186f8b261c3915b2d6c1dc227b257e59 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 15:28:23 -0800 Subject: [PATCH 014/174] [release/9.x] Update dependencies from dotnet/installer (#6170) * Update dependencies from https://github.com/dotnet/installer build 20240304.2 Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.1.24101.4 -> To Version 9.0.100-preview.2.24154.2 Dependency coherency updates Microsoft.AspNetCore.App.Runtime.win-x64,Microsoft.NETCore.App.Runtime.win-x64,VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0,VS.Redist.Common.NetCore.SharedFramework.x64.9.0 From Version 9.0.0-preview.1.24081.5 -> To Version 9.0.0-preview.2.24128.4 (parent: Microsoft.Dotnet.Sdk.Internal * Update dependencies from https://github.com/dotnet/installer build 20240304.2 Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.1.24101.4 -> To Version 9.0.100-preview.2.24154.2 Dependency coherency updates Microsoft.AspNetCore.App.Runtime.win-x64,Microsoft.NETCore.App.Runtime.win-x64,VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0,VS.Redist.Common.NetCore.SharedFramework.x64.9.0 From Version 9.0.0-preview.1.24081.5 -> To Version 9.0.0-preview.2.24128.4 (parent: Microsoft.Dotnet.Sdk.Internal --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 7876a032003..26c60407e09 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/aspnetcore - b1beadfe0ad3d02eb5207681a5328793c4b3822c + e1ad9117a4dac3b0f5f2a7e2b10b43b7016379b9 https://github.com/dotnet/diagnostics @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade 8cfc9489d3e51071fedec9dcb99071dc912718bd - + https://github.com/dotnet/installer - 103ff6d4866ae1feff84a1865df0c1a7494ceffc + 1f23db25f3ebade102a338496f7d46a1128307f3 https://github.com/dotnet/arcade @@ -50,17 +50,17 @@ https://github.com/dotnet/symstore 0c7b75fc18db3a4f9b7737ae55a0d04e913ac40c - + https://github.com/dotnet/runtime - 1d1bf92fcf43aa6981804dc53c5174445069c9e4 + 8e5e748c5c06d3e40244c725bd2124f06998f6c1 - + https://github.com/dotnet/aspnetcore - b1beadfe0ad3d02eb5207681a5328793c4b3822c + e1ad9117a4dac3b0f5f2a7e2b10b43b7016379b9 - + https://github.com/dotnet/runtime - 1d1bf92fcf43aa6981804dc53c5174445069c9e4 + 8e5e748c5c06d3e40244c725bd2124f06998f6c1 diff --git a/eng/Versions.props b/eng/Versions.props index 40df7fbd914..85e92c6ac56 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -57,20 +57,20 @@ 9.0.0-beta.24105.3 9.0.0-beta.24105.3 - 9.0.0-preview.1.24081.5 - 9.0.0-preview.1.24081.5 + 9.0.0-preview.2.24128.4 + 9.0.0-preview.2.24128.4 2.0.0-beta4.24102.1 8.0.510501 8.0.510501 - 9.0.100-preview.1.24101.4 + 9.0.100-preview.2.24154.2 9.0.0-preview.24075.1 - 9.0.0-preview.1.24080.9 - 9.0.0-preview.1.24080.9 + 9.0.0-preview.2.24128.5 + 9.0.0-preview.2.24128.5 1.0.507901 From cae0f31b180be63f8189cfde66c3127d90329f96 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 23:01:09 +0000 Subject: [PATCH 015/174] Update dependencies from https://github.com/dotnet/diagnostics build 20240205.1 (#6186) Microsoft.Diagnostics.Monitoring , Microsoft.Diagnostics.Monitoring.EventPipe From Version 8.0.0-preview.24151.1 -> To Version 8.0.510501 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index bb0f45a56e2..d2355c274cd 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -4,13 +4,13 @@ https://github.com/dotnet/aspnetcore 3e5155276f3d486ef49e1f06ee875d6757983695 - + https://github.com/dotnet/diagnostics - 831eee3a9e69dd886fa190a9914a7f66260c653a + 8c08c89a0643d31db91e119b1adb463be3e0ffe5 - + https://github.com/dotnet/diagnostics - 831eee3a9e69dd886fa190a9914a7f66260c653a + 8c08c89a0643d31db91e119b1adb463be3e0ffe5 https://github.com/dotnet/command-line-api diff --git a/eng/Versions.props b/eng/Versions.props index dacf34b8f28..a26f7b2df71 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -57,8 +57,8 @@ 2.0.0-beta4.24126.1 - 8.0.0-preview.24151.1 - 8.0.0-preview.24151.1 + 8.0.510501 + 8.0.510501 9.0.100-preview.3.24153.2 From 9c7a2793a338f250c82a49166d6ca70f2a4b5045 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 23:02:02 +0000 Subject: [PATCH 016/174] update release information (#6187) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index a26f7b2df71..645d10da81f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -5,7 +5,7 @@ https://github.com/dotnet/dotnet-monitor 9.0.0 preview - 1 + 2 true - daily + release From 528729f366d2438fb2da4fc337e1497257d45bbf Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 23:07:00 +0000 Subject: [PATCH 017/174] Update dependencies from https://github.com/dotnet/installer build 20240305.1 (#6188) Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.3.24153.2 -> To Version 9.0.100-preview.2.24155.1 Dependency coherency updates Microsoft.AspNetCore.App.Runtime.win-x64,Microsoft.NETCore.App.Runtime.win-x64,VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0,VS.Redist.Common.NetCore.SharedFramework.x64.9.0 From Version 9.0.0-preview.3.24151.1 -> To Version 9.0.0-preview.2.24128.4 (parent: Microsoft.Dotnet.Sdk.Internal Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d2355c274cd..439432e3712 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/aspnetcore - 3e5155276f3d486ef49e1f06ee875d6757983695 + e1ad9117a4dac3b0f5f2a7e2b10b43b7016379b9 https://github.com/dotnet/diagnostics @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade 87d89025bdd8827c016e4083660d31f497670e5c - + https://github.com/dotnet/installer - 893b762b6e36d558df7ae6fccdfd8034f83a1c2e + 1aa497b81a545f7ce3ec08eaaf80e03dfdb2433b https://github.com/dotnet/arcade @@ -50,17 +50,17 @@ https://github.com/dotnet/symstore 96a152a28e86ecc5c68ec9a73e02bb1e93163338 - + https://github.com/dotnet/runtime - 5e603d595e63ddc5cdce9777a40608279abdcc37 + 8e5e748c5c06d3e40244c725bd2124f06998f6c1 - + https://github.com/dotnet/aspnetcore - 3e5155276f3d486ef49e1f06ee875d6757983695 + e1ad9117a4dac3b0f5f2a7e2b10b43b7016379b9 - + https://github.com/dotnet/runtime - 5e603d595e63ddc5cdce9777a40608279abdcc37 + 8e5e748c5c06d3e40244c725bd2124f06998f6c1 diff --git a/eng/Versions.props b/eng/Versions.props index 645d10da81f..dfd4f112b1f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,20 +52,20 @@ 9.0.0-beta.24151.5 9.0.0-beta.24151.5 - 9.0.0-preview.3.24151.1 - 9.0.0-preview.3.24151.1 + 9.0.0-preview.2.24128.4 + 9.0.0-preview.2.24128.4 2.0.0-beta4.24126.1 8.0.510501 8.0.510501 - 9.0.100-preview.3.24153.2 + 9.0.100-preview.2.24155.1 9.0.0-preview.24151.1 - 9.0.0-preview.3.24129.2 - 9.0.0-preview.3.24129.2 + 9.0.0-preview.2.24128.5 + 9.0.0-preview.2.24128.5 1.0.511901 From a43c7f278462d88206e245571a8c2e9717f39e31 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Mar 2024 10:54:06 -0800 Subject: [PATCH 018/174] Bifurcate official pipeline from public pipeline (#6209) Co-authored-by: Justin Anderson --- eng/pipelines/dotnet-monitor-official.yml | 162 ++++++++++++++++++++++ eng/pipelines/dotnet-monitor-public.yml | 162 ++++++++++++++++++++++ 2 files changed, 324 insertions(+) create mode 100644 eng/pipelines/dotnet-monitor-official.yml create mode 100644 eng/pipelines/dotnet-monitor-public.yml diff --git a/eng/pipelines/dotnet-monitor-official.yml b/eng/pipelines/dotnet-monitor-official.yml new file mode 100644 index 00000000000..396d0b318b8 --- /dev/null +++ b/eng/pipelines/dotnet-monitor-official.yml @@ -0,0 +1,162 @@ +trigger: none + +pr: + autoCancel: true + branches: + include: + - main + - release/* + - internal/release/* + - feature/* + paths: + exclude: + - .devcontainer + - .github + - .vscode + - .gitignore + - cspell.json + - eng/actions + - samples + - '**.md' + +schedules: +# Schedule before docker update pipeline +- cron: "0 3 * * Mon-Fri" + displayName: M-F Scheduled Build + branches: + include: + - main + +parameters: +- name: testGroup + displayName: 'Test Group' + type: string + default: Default + values: + - Default + - All + - None + - CI + - PR +- name: updateDocker + displayName: 'Update dotnet-docker? (Only for release branches)' + type: boolean + default: false +- name: useHelix + displayName: Use Helix Testing + type: boolean + default: true + +variables: +- template: /eng/common/templates/variables/pool-providers.yml +- name: _TeamName + value: DotNetCore +- name: _TPNFile + value: THIRD-PARTY-NOTICES.TXT + +- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + # DotNet-Diagnostics-SDL-Params provides Tsa* variables for SDL checks. + - group: DotNet-Diagnostics-SDL-Params + +stages: +- stage: Build + displayName: Build and Test + jobs: + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + # Generate a TPN for only the dotnet-monitor project + - template: /eng/pipelines/jobs/tpn.yml + + # Build and (optionally) test binaries + - template: /eng/pipelines/jobs/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/jobs/build-binaries.yml + includeArm64: ${{ or(ne(variables['System.TeamProject'], 'public'), eq(parameters.useHelix, 'true')) }} + includeDebug: true + jobParameters: + publishBinaries: true + publishArtifacts: ${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }} + + - ${{ if ne(parameters.testGroup, 'None') }}: + - template: /eng/pipelines/jobs/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/jobs/test-binaries.yml + includeArm64: ${{ parameters.useHelix }} + jobParameters: + testGroup: ${{ parameters.testGroup }} + useHelix: ${{ parameters.useHelix }} + +- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - stage: Archive + displayName: Archive + dependsOn: + - Build + jobs: + # Sign binaries before archiving + - template: /eng/pipelines/jobs/sign-binaries.yml + + # Build RID (runtime identifier) archives + - template: /eng/pipelines/jobs/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/jobs/build-archive.yml + includeArm64: true +# This stage creates NuGet packages and generates the BAR manifests +- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - stage: PackSignPublish + displayName: Pack, Sign, and Generate Manifests + dependsOn: + - Archive + jobs: + # Pack, sign, and publish manifest + - template: /eng/pipelines/jobs/pack-sign-publish.yml + + # Register with BAR + - template: /eng/common/templates/job/publish-build-assets.yml + parameters: + configuration: Release + dependsOn: + - Pack_Sign + publishUsingPipelines: true + pool: + name: $(DncEngInternalBuildPool) + demands: ImageOverride -equals 1es-windows-2019 +# These are the stages that perform validation of several SDL requirements and publish the bits required to the designated feed. + - template: /eng/common/templates/post-build/post-build.yml + parameters: + # This is to enable SDL runs part of Post-Build Validation Stage. + # as well as NuGet, SourceLink, and signing validation. + # The variables get imported from group dotnet-diagnostics-sdl-params + validateDependsOn: + - PackSignPublish + publishingInfraVersion: 3 + enableSourceLinkValidation: ${{ and(not(startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/')), not(startsWith(variables['Build.SourceBranch'], 'refs/heads/test/release/'))) }} + enableSigningValidation: true + enableSymbolValidation: false + enableNugetValidation: true + publishInstallersAndChecksums: true + SDLValidationParameters: + enable: true + continueOnError: true + publishGdn: true + params: >- + -SourceToolsList @("policheck","credscan") + -TsaInstanceURL $(_TsaInstanceURL) + -TsaProjectName $(_TsaProjectName) + -TsaNotificationEmail $(_TsaNotificationEmail) + -TsaCodebaseAdmin $(_TsaCodebaseAdmin) + -TsaBugAreaPath $(_TsaBugAreaPath) + -TsaIterationPath $(_TsaIterationPath) + -TsaRepositoryName "dotnet-monitor" + -TsaCodebaseName "dotnet-monitor" + -TsaPublish $True + -PoliCheckAdditionalRunConfigParams @("UserExclusionPath < $(Build.SourcesDirectory)/eng/PoliCheckExclusions.xml") + artifactNames: + - 'PackageArtifacts' +# This sets up the bits to do a Release. +- template: /eng/pipelines/stages/preparerelease.yml + parameters: + ${{ if eq(parameters.updateDocker, 'true') }}: + updateDockerCondition: true + ${{ else }}: + # If scheduled build from main and nightly update from main enabled + updateDockerCondition: and(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.Reason'], 'Schedule'), eq(variables['NightlyUpdateDockerFromMain'], 'true')) + diff --git a/eng/pipelines/dotnet-monitor-public.yml b/eng/pipelines/dotnet-monitor-public.yml new file mode 100644 index 00000000000..396d0b318b8 --- /dev/null +++ b/eng/pipelines/dotnet-monitor-public.yml @@ -0,0 +1,162 @@ +trigger: none + +pr: + autoCancel: true + branches: + include: + - main + - release/* + - internal/release/* + - feature/* + paths: + exclude: + - .devcontainer + - .github + - .vscode + - .gitignore + - cspell.json + - eng/actions + - samples + - '**.md' + +schedules: +# Schedule before docker update pipeline +- cron: "0 3 * * Mon-Fri" + displayName: M-F Scheduled Build + branches: + include: + - main + +parameters: +- name: testGroup + displayName: 'Test Group' + type: string + default: Default + values: + - Default + - All + - None + - CI + - PR +- name: updateDocker + displayName: 'Update dotnet-docker? (Only for release branches)' + type: boolean + default: false +- name: useHelix + displayName: Use Helix Testing + type: boolean + default: true + +variables: +- template: /eng/common/templates/variables/pool-providers.yml +- name: _TeamName + value: DotNetCore +- name: _TPNFile + value: THIRD-PARTY-NOTICES.TXT + +- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + # DotNet-Diagnostics-SDL-Params provides Tsa* variables for SDL checks. + - group: DotNet-Diagnostics-SDL-Params + +stages: +- stage: Build + displayName: Build and Test + jobs: + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + # Generate a TPN for only the dotnet-monitor project + - template: /eng/pipelines/jobs/tpn.yml + + # Build and (optionally) test binaries + - template: /eng/pipelines/jobs/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/jobs/build-binaries.yml + includeArm64: ${{ or(ne(variables['System.TeamProject'], 'public'), eq(parameters.useHelix, 'true')) }} + includeDebug: true + jobParameters: + publishBinaries: true + publishArtifacts: ${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }} + + - ${{ if ne(parameters.testGroup, 'None') }}: + - template: /eng/pipelines/jobs/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/jobs/test-binaries.yml + includeArm64: ${{ parameters.useHelix }} + jobParameters: + testGroup: ${{ parameters.testGroup }} + useHelix: ${{ parameters.useHelix }} + +- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - stage: Archive + displayName: Archive + dependsOn: + - Build + jobs: + # Sign binaries before archiving + - template: /eng/pipelines/jobs/sign-binaries.yml + + # Build RID (runtime identifier) archives + - template: /eng/pipelines/jobs/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/jobs/build-archive.yml + includeArm64: true +# This stage creates NuGet packages and generates the BAR manifests +- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - stage: PackSignPublish + displayName: Pack, Sign, and Generate Manifests + dependsOn: + - Archive + jobs: + # Pack, sign, and publish manifest + - template: /eng/pipelines/jobs/pack-sign-publish.yml + + # Register with BAR + - template: /eng/common/templates/job/publish-build-assets.yml + parameters: + configuration: Release + dependsOn: + - Pack_Sign + publishUsingPipelines: true + pool: + name: $(DncEngInternalBuildPool) + demands: ImageOverride -equals 1es-windows-2019 +# These are the stages that perform validation of several SDL requirements and publish the bits required to the designated feed. + - template: /eng/common/templates/post-build/post-build.yml + parameters: + # This is to enable SDL runs part of Post-Build Validation Stage. + # as well as NuGet, SourceLink, and signing validation. + # The variables get imported from group dotnet-diagnostics-sdl-params + validateDependsOn: + - PackSignPublish + publishingInfraVersion: 3 + enableSourceLinkValidation: ${{ and(not(startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/')), not(startsWith(variables['Build.SourceBranch'], 'refs/heads/test/release/'))) }} + enableSigningValidation: true + enableSymbolValidation: false + enableNugetValidation: true + publishInstallersAndChecksums: true + SDLValidationParameters: + enable: true + continueOnError: true + publishGdn: true + params: >- + -SourceToolsList @("policheck","credscan") + -TsaInstanceURL $(_TsaInstanceURL) + -TsaProjectName $(_TsaProjectName) + -TsaNotificationEmail $(_TsaNotificationEmail) + -TsaCodebaseAdmin $(_TsaCodebaseAdmin) + -TsaBugAreaPath $(_TsaBugAreaPath) + -TsaIterationPath $(_TsaIterationPath) + -TsaRepositoryName "dotnet-monitor" + -TsaCodebaseName "dotnet-monitor" + -TsaPublish $True + -PoliCheckAdditionalRunConfigParams @("UserExclusionPath < $(Build.SourcesDirectory)/eng/PoliCheckExclusions.xml") + artifactNames: + - 'PackageArtifacts' +# This sets up the bits to do a Release. +- template: /eng/pipelines/stages/preparerelease.yml + parameters: + ${{ if eq(parameters.updateDocker, 'true') }}: + updateDockerCondition: true + ${{ else }}: + # If scheduled build from main and nightly update from main enabled + updateDockerCondition: and(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.Reason'], 'Schedule'), eq(variables['NightlyUpdateDockerFromMain'], 'true')) + From 12cccf45f9e5aa6328434f3cada9e3374f1a0be2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:33:19 -0700 Subject: [PATCH 019/174] [release/9.x] Update dependencies from dotnet/installer (#6197) * Update dependencies from https://github.com/dotnet/installer build 20240305.28 Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.2.24155.1 -> To Version 9.0.100-preview.2.24155.28 * Update dependencies from https://github.com/dotnet/installer build 20240307.14 Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.2.24155.1 -> To Version 9.0.100-preview.2.24157.14 * Update dependencies from https://github.com/dotnet/installer build 20240307.14 Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.2.24155.1 -> To Version 9.0.100-preview.2.24157.14 * Update dependencies from https://github.com/dotnet/installer build 20240307.14 Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.2.24155.1 -> To Version 9.0.100-preview.2.24157.14 * Update dependencies from https://github.com/dotnet/installer build 20240310.12 Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.2.24155.1 -> To Version 9.0.100-preview.2.24160.12 * Update dependencies from https://github.com/dotnet/installer build 20240312.3 Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.2.24155.1 -> To Version 9.0.100-preview.2.24162.3 --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 439432e3712..b1609f7a987 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade 87d89025bdd8827c016e4083660d31f497670e5c - + https://github.com/dotnet/installer - 1aa497b81a545f7ce3ec08eaaf80e03dfdb2433b + 8cbba02f68a3dfe1a70f526761a6f24861a78005 https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index dfd4f112b1f..19439585759 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -60,7 +60,7 @@ 8.0.510501 8.0.510501 - 9.0.100-preview.2.24155.1 + 9.0.100-preview.2.24162.3 9.0.0-preview.24151.1 From daf0e28deec0cbd70a3a3f395c42cbb11e84f401 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 09:15:36 -0700 Subject: [PATCH 020/174] Update dependencies from https://github.com/dotnet/installer build (#6239) Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.2.24162.3 -> To Version 9.0.100-preview.2.24163.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b1609f7a987..823d4eb4ea7 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade 87d89025bdd8827c016e4083660d31f497670e5c - + https://github.com/dotnet/installer - 8cbba02f68a3dfe1a70f526761a6f24861a78005 + 79819c38bf73d2c051080127d92e94c8e54ae953 https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index 19439585759..d48d2c0fdc3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -60,7 +60,7 @@ 8.0.510501 8.0.510501 - 9.0.100-preview.2.24162.3 + 9.0.100-preview.2.24163.3 9.0.0-preview.24151.1 From 61bd085d801fcf4a18ad2e5e3c14aa775f1cbd7f Mon Sep 17 00:00:00 2001 From: kkeirstead Date: Fri, 29 Mar 2024 14:04:04 -0700 Subject: [PATCH 021/174] Included missing conflict resolution --- eng/Version.Details.xml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 98f143e616f..4c8650f07a1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -38,15 +38,9 @@ https://github.com/dotnet/arcade 4345e14684eab24fa2f8217706756dd7c0787d84 -<<<<<<< HEAD - - https://github.com/dotnet/installer - 79819c38bf73d2c051080127d92e94c8e54ae953 -======= https://github.com/dotnet/installer 6cb99adb7aea19d43c6af6aecae7526dfe61d763 ->>>>>>> feature/9.x https://github.com/dotnet/arcade @@ -56,19 +50,6 @@ https://github.com/dotnet/symstore 550601c12a227c87ded32316345934101a8a2422 -<<<<<<< HEAD - - https://github.com/dotnet/runtime - 8e5e748c5c06d3e40244c725bd2124f06998f6c1 - - - https://github.com/dotnet/aspnetcore - e1ad9117a4dac3b0f5f2a7e2b10b43b7016379b9 - - - https://github.com/dotnet/runtime - 8e5e748c5c06d3e40244c725bd2124f06998f6c1 -======= https://github.com/dotnet/runtime e612bf4d0b6f08623092902c34a504e932388664 @@ -80,7 +61,6 @@ https://github.com/dotnet/runtime e612bf4d0b6f08623092902c34a504e932388664 ->>>>>>> feature/9.x From 7a97b6ea7ade1625a221b2c05794eedc26eff491 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sat, 30 Mar 2024 00:13:03 +0000 Subject: [PATCH 022/174] Update dependencies from https://github.com/dotnet/installer build 20240325.24 (#6361) Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.4.24178.10 -> To Version 9.0.100-preview.3.24175.24 Dependency coherency updates Microsoft.AspNetCore.App.Runtime.win-x64,Microsoft.NETCore.App.Runtime.win-x64,VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0,VS.Redist.Common.NetCore.SharedFramework.x64.9.0 From Version 9.0.0-preview.4.24177.3 -> To Version 9.0.0-preview.3.24172.13 (parent: Microsoft.Dotnet.Sdk.Internal Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4c8650f07a1..e776c1c6988 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/aspnetcore - 1c8f20be1fc4e97044d7ca93edae3af528bc3521 + d4eca39c3fc1944b2c6431bf6b22036bdb176c0d https://github.com/dotnet/diagnostics @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade 4345e14684eab24fa2f8217706756dd7c0787d84 - + https://github.com/dotnet/installer - 6cb99adb7aea19d43c6af6aecae7526dfe61d763 + 09d6f381e6917ee70cf6cbc6109c675c4a51bf77 https://github.com/dotnet/arcade @@ -50,17 +50,17 @@ https://github.com/dotnet/symstore 550601c12a227c87ded32316345934101a8a2422 - + https://github.com/dotnet/runtime - e612bf4d0b6f08623092902c34a504e932388664 + 9e6ba1f68c6a9c7206dacdf1e4cac67ea19931eb - + https://github.com/dotnet/aspnetcore - 1c8f20be1fc4e97044d7ca93edae3af528bc3521 + d4eca39c3fc1944b2c6431bf6b22036bdb176c0d - + https://github.com/dotnet/runtime - e612bf4d0b6f08623092902c34a504e932388664 + 9e6ba1f68c6a9c7206dacdf1e4cac67ea19931eb diff --git a/eng/Versions.props b/eng/Versions.props index 9267660d01e..d8b24e17b6c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,20 +52,20 @@ 9.0.0-beta.24178.6 9.0.0-beta.24178.6 - 9.0.0-preview.4.24177.3 - 9.0.0-preview.4.24177.3 + 9.0.0-preview.3.24172.13 + 9.0.0-preview.3.24172.13 2.0.0-beta4.24126.1 8.0.0-preview.24178.4 8.0.0-preview.24178.4 - 9.0.100-preview.4.24178.10 + 9.0.100-preview.3.24175.24 9.0.0-preview.24177.1 - 9.0.0-preview.4.24178.3 - 9.0.0-preview.4.24178.3 + 9.0.0-preview.3.24172.9 + 9.0.0-preview.3.24172.9 1.0.517501 From b9b6e9a7362430317f3c1671fa14dc86df335b63 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 12:58:38 -0700 Subject: [PATCH 023/174] Update dependencies from https://github.com/dotnet/installer build 20240404.13 (#6383) Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.3.24175.24 -> To Version 9.0.100-preview.3.24204.13 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e776c1c6988..b430ecbf3bf 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade 4345e14684eab24fa2f8217706756dd7c0787d84 - + https://github.com/dotnet/installer - 09d6f381e6917ee70cf6cbc6109c675c4a51bf77 + 81f61d829031f71887c49938993e8e2c4cc1eb70 https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index d8b24e17b6c..e1079642f86 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -60,7 +60,7 @@ 8.0.0-preview.24178.4 8.0.0-preview.24178.4 - 9.0.100-preview.3.24175.24 + 9.0.100-preview.3.24204.13 9.0.0-preview.24177.1 From a1df6dd520541c58d7e4241d38fec084e5c836e3 Mon Sep 17 00:00:00 2001 From: Justin Anderson Date: Tue, 14 May 2024 15:04:47 -0700 Subject: [PATCH 024/174] Update framework dependencies to latest --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1b12f4bdd9b..ee3d15aedcf 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/aspnetcore - d4eca39c3fc1944b2c6431bf6b22036bdb176c0d + 839d2527fb7a5ec63342bfae04d0e739d3e1c76d https://github.com/dotnet/diagnostics @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade 480401b003bfd2eb989c315da5d6b99ad13a968c - + https://github.com/dotnet/installer - 81f61d829031f71887c49938993e8e2c4cc1eb70 + 91824b5bf7b89f1e9832061d6bdaf0cc9ecc1f55 https://github.com/dotnet/arcade @@ -50,17 +50,17 @@ https://github.com/dotnet/diagnostics 363760fa9a030cbd6c8eb73e7352c8728ba62a9a - + https://github.com/dotnet/runtime - 9e6ba1f68c6a9c7206dacdf1e4cac67ea19931eb + 2270e3185f538a1581dcf11dd5317da1bd92909c - + https://github.com/dotnet/aspnetcore - d4eca39c3fc1944b2c6431bf6b22036bdb176c0d + 839d2527fb7a5ec63342bfae04d0e739d3e1c76d - + https://github.com/dotnet/runtime - 9e6ba1f68c6a9c7206dacdf1e4cac67ea19931eb + 2270e3185f538a1581dcf11dd5317da1bd92909c diff --git a/eng/Versions.props b/eng/Versions.props index 44383c0b18b..ef764c5d1c9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,20 +52,20 @@ 9.0.0-beta.24260.2 9.0.0-beta.24260.2 - 9.0.0-preview.3.24172.13 - 9.0.0-preview.3.24172.13 + 9.0.0-preview.4.24260.3 + 9.0.0-preview.4.24260.3 2.0.0-beta4.24209.3 8.0.0-preview.24263.1 8.0.0-preview.24263.1 - 9.0.100-preview.3.24204.13 + 9.0.100-preview.4.24260.3 9.0.0-preview.24225.1 - 9.0.0-preview.3.24172.9 - 9.0.0-preview.3.24172.9 + 9.0.0-preview.4.24260.3 + 9.0.0-preview.4.24260.3 8.0.0-preview.24263.1 From 619c0a027f0c61741ecc83ec67c4b85b465c359f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 18:36:24 +0000 Subject: [PATCH 025/174] Update dependencies from https://github.com/dotnet/installer build 20240515.4 (#6661) Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.4.24260.3 -> To Version 9.0.100-preview.4.24265.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ee3d15aedcf..d7fad14fa0a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade 480401b003bfd2eb989c315da5d6b99ad13a968c - + https://github.com/dotnet/installer - 91824b5bf7b89f1e9832061d6bdaf0cc9ecc1f55 + df80b5eb607242b1d8ded158ec97a25e5d5e5e05 https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index ef764c5d1c9..30fdc142481 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -60,7 +60,7 @@ 8.0.0-preview.24263.1 8.0.0-preview.24263.1 - 9.0.100-preview.4.24260.3 + 9.0.100-preview.4.24265.4 9.0.0-preview.24225.1 From 8f2be405e51332bd85911818084f22f78da696fa Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 07:31:55 +0000 Subject: [PATCH 026/174] Update dependencies from https://github.com/dotnet/installer build 20240517.66 (#6681) Microsoft.Dotnet.Sdk.Internal From Version 9.0.100-preview.4.24265.4 -> To Version 9.0.100-preview.4.24267.66 Dependency coherency updates Microsoft.AspNetCore.App.Runtime.win-x64,Microsoft.NETCore.App.Runtime.win-x64,VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0,VS.Redist.Common.NetCore.SharedFramework.x64.9.0 From Version 9.0.0-preview.4.24260.3 -> To Version 9.0.0-preview.4.24267.6 (parent: Microsoft.Dotnet.Sdk.Internal Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d7fad14fa0a..33136a2f422 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/aspnetcore - 839d2527fb7a5ec63342bfae04d0e739d3e1c76d + ada5ad97d2114250a05550cb28cc18b9cf9f8993 https://github.com/dotnet/diagnostics @@ -38,9 +38,9 @@ https://github.com/dotnet/arcade 480401b003bfd2eb989c315da5d6b99ad13a968c - + https://github.com/dotnet/installer - df80b5eb607242b1d8ded158ec97a25e5d5e5e05 + 26d3d259e4d0d9c5076a66f37d6e99c0e7c7f6cc https://github.com/dotnet/arcade @@ -50,17 +50,17 @@ https://github.com/dotnet/diagnostics 363760fa9a030cbd6c8eb73e7352c8728ba62a9a - + https://github.com/dotnet/runtime - 2270e3185f538a1581dcf11dd5317da1bd92909c + d0d6fed6c0eedd962ddc0f68554682064e9e11ca - + https://github.com/dotnet/aspnetcore - 839d2527fb7a5ec63342bfae04d0e739d3e1c76d + ada5ad97d2114250a05550cb28cc18b9cf9f8993 - + https://github.com/dotnet/runtime - 2270e3185f538a1581dcf11dd5317da1bd92909c + d0d6fed6c0eedd962ddc0f68554682064e9e11ca diff --git a/eng/Versions.props b/eng/Versions.props index 30fdc142481..40c77da3c6f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,20 +52,20 @@ 9.0.0-beta.24260.2 9.0.0-beta.24260.2 - 9.0.0-preview.4.24260.3 - 9.0.0-preview.4.24260.3 + 9.0.0-preview.4.24267.6 + 9.0.0-preview.4.24267.6 2.0.0-beta4.24209.3 8.0.0-preview.24263.1 8.0.0-preview.24263.1 - 9.0.100-preview.4.24265.4 + 9.0.100-preview.4.24267.66 9.0.0-preview.24225.1 - 9.0.0-preview.4.24260.3 - 9.0.0-preview.4.24260.3 + 9.0.0-preview.4.24266.19 + 9.0.0-preview.4.24266.19 8.0.0-preview.24263.1 From 09d94acb2e86ae80a306b0a847def4b3475e1228 Mon Sep 17 00:00:00 2001 From: Wiktor Kopec Date: Tue, 4 Jun 2024 19:53:15 -0700 Subject: [PATCH 027/174] Fixup merge --- eng/Version.Details.xml | 1 + eng/Versions.props | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b913e618908..21d40c5919b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -61,5 +61,6 @@ https://github.com/dotnet/runtime d0d6fed6c0eedd962ddc0f68554682064e9e11ca + diff --git a/eng/Versions.props b/eng/Versions.props index c9f69d109d8..71a59499f0d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -67,7 +67,7 @@ 9.0.0-preview.4.24266.19 9.0.0-preview.4.24266.19 - 9.0.100-preview.4.24266.19 + 9.0.0-preview.5.24272.2 1.0.530301 From 90316cf4dc8627578e27fc82182d256a8fdedcda Mon Sep 17 00:00:00 2001 From: Wiktor Kopec Date: Tue, 4 Jun 2024 23:15:11 -0700 Subject: [PATCH 028/174] Try updated placeholder version --- eng/Version.Details.xml | 2 +- eng/Versions.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 21d40c5919b..d54bfc1072c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -54,7 +54,7 @@ https://github.com/dotnet/aspnetcore ada5ad97d2114250a05550cb28cc18b9cf9f8993 - + https://github.com/dotnet/sdk 5c06e5d01fa0ea4122e7202cefb921a779f9843a diff --git a/eng/Versions.props b/eng/Versions.props index 71a59499f0d..c835826e3a6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -67,7 +67,7 @@ 9.0.0-preview.4.24266.19 9.0.0-preview.4.24266.19 - 9.0.0-preview.5.24272.2 + 9.0.100-preview.5.24272.19 1.0.530301 From f8ee54ff0f38ebeaf52fadb48f32bc6afa5d97ec Mon Sep 17 00:00:00 2001 From: Wiktor Kopec Date: Wed, 5 Jun 2024 11:39:59 -0700 Subject: [PATCH 029/174] Fake version for sdkplacholder (#6781) --- eng/Version.Details.xml | 2 +- eng/Versions.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d54bfc1072c..e7b29a6c0d2 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -54,7 +54,7 @@ https://github.com/dotnet/aspnetcore ada5ad97d2114250a05550cb28cc18b9cf9f8993 - + https://github.com/dotnet/sdk 5c06e5d01fa0ea4122e7202cefb921a779f9843a diff --git a/eng/Versions.props b/eng/Versions.props index c835826e3a6..4e8e019e19e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -67,7 +67,7 @@ 9.0.0-preview.4.24266.19 9.0.0-preview.4.24266.19 - 9.0.100-preview.5.24272.19 + 9.0.100-preview.4.24272.19 1.0.530301 From 7e2ef884b421eb1db280fec6deb90626d6553137 Mon Sep 17 00:00:00 2001 From: Wiktor Kopec Date: Wed, 5 Jun 2024 11:50:32 -0700 Subject: [PATCH 030/174] Update parent dependency (#6782) --- eng/Version.Details.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e7b29a6c0d2..c442bb01d04 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,6 +1,6 @@ - + https://github.com/dotnet/aspnetcore ada5ad97d2114250a05550cb28cc18b9cf9f8993 From b0e580ec05d71cee6c75b110c49890b4dc0e0b0d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 13:06:39 -0700 Subject: [PATCH 031/174] Update dependencies from https://github.com/dotnet/sdk build 20240605.12 (#6783) VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0 From Version 9.0.100-preview.4.24272.19 -> To Version 9.0.100-preview.5.24305.12 Dependency coherency updates Microsoft.AspNetCore.App.Runtime.win-x64,Microsoft.NETCore.App.Runtime.win-x64,VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0,VS.Redist.Common.NetCore.SharedFramework.x64.9.0 From Version 9.0.0-preview.4.24267.6 -> To Version 9.0.0-preview.5.24305.1 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c442bb01d04..91471c24890 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/aspnetcore - ada5ad97d2114250a05550cb28cc18b9cf9f8993 + 4c7f0dc105d8348f12e1eebb984e85fc8d3c501c https://github.com/dotnet/diagnostics @@ -46,21 +46,21 @@ https://github.com/dotnet/diagnostics 05f88f687a02aa865384beda97a8910d4d57b17b - + https://github.com/dotnet/runtime - d0d6fed6c0eedd962ddc0f68554682064e9e11ca + 4049205d3a0889def4a7b911ba0754b382959a8d - + https://github.com/dotnet/aspnetcore - ada5ad97d2114250a05550cb28cc18b9cf9f8993 + 4c7f0dc105d8348f12e1eebb984e85fc8d3c501c - + https://github.com/dotnet/sdk - 5c06e5d01fa0ea4122e7202cefb921a779f9843a + b578d95670266ce6884f594e3d998a459f9d5100 - + https://github.com/dotnet/runtime - d0d6fed6c0eedd962ddc0f68554682064e9e11ca + 4049205d3a0889def4a7b911ba0754b382959a8d diff --git a/eng/Versions.props b/eng/Versions.props index 4e8e019e19e..987f2ce87f2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,8 +52,8 @@ 9.0.0-beta.24303.1 9.0.0-beta.24303.1 - 9.0.0-preview.4.24267.6 - 9.0.0-preview.4.24267.6 + 9.0.0-preview.5.24305.1 + 9.0.0-preview.5.24305.1 2.0.0-beta4.24209.3 @@ -64,10 +64,10 @@ 9.0.0-preview.24303.1 - 9.0.0-preview.4.24266.19 - 9.0.0-preview.4.24266.19 + 9.0.0-preview.5.24304.9 + 9.0.0-preview.5.24304.9 - 9.0.100-preview.4.24272.19 + 9.0.100-preview.5.24305.12 1.0.530301 From b6ca445944084c4d0d5fa27cc0b3dfe80915b755 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 16:27:28 -0700 Subject: [PATCH 032/174] Fixup nuget authentication (#6790) Co-authored-by: Wiktor Kopec --- eng/pipelines/steps/setup-nuget-sources.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/eng/pipelines/steps/setup-nuget-sources.yml b/eng/pipelines/steps/setup-nuget-sources.yml index 386306d03de..5c12f50f91f 100644 --- a/eng/pipelines/steps/setup-nuget-sources.yml +++ b/eng/pipelines/steps/setup-nuget-sources.yml @@ -8,7 +8,7 @@ steps: displayName: Setup Private Feeds Credentials inputs: filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 - arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token + arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config env: Token: $(dn-bot-dnceng-artifact-feeds-rw) - ${{ else }}: @@ -19,3 +19,7 @@ steps: arguments: $(Build.SourcesDirectory)/NuGet.config $Token env: Token: $(dn-bot-dnceng-artifact-feeds-rw) +# Run the NuGetAuthenticate task after the internal feeds are added to the nuget.config +# This ensures that creds are set appropriately for all feeds in the config, and that the +# credential provider is installed. +- task: NuGetAuthenticate@1 \ No newline at end of file From 567ba94ab9df51a74ea7dac26e963dbcacf60047 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 7 Jun 2024 11:09:51 -0700 Subject: [PATCH 033/174] Update dependencies from https://github.com/dotnet/sdk build 20240607.3 (#6797) VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0 From Version 9.0.100-preview.5.24305.12 -> To Version 9.0.100-preview.5.24307.3 Dependency coherency updates Microsoft.AspNetCore.App.Runtime.win-x64,Microsoft.NETCore.App.Runtime.win-x64,VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0,VS.Redist.Common.NetCore.SharedFramework.x64.9.0 From Version 9.0.0-preview.5.24305.1 -> To Version 9.0.0-preview.5.24306.11 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 91471c24890..fb9956beb08 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/aspnetcore - 4c7f0dc105d8348f12e1eebb984e85fc8d3c501c + 8af96e042134fb3b2f21df26dd0f32ea1c00dd37 https://github.com/dotnet/diagnostics @@ -46,21 +46,21 @@ https://github.com/dotnet/diagnostics 05f88f687a02aa865384beda97a8910d4d57b17b - + https://github.com/dotnet/runtime - 4049205d3a0889def4a7b911ba0754b382959a8d + a5cc707d976a14495462c9c492a921ff0927b8f5 - + https://github.com/dotnet/aspnetcore - 4c7f0dc105d8348f12e1eebb984e85fc8d3c501c + 8af96e042134fb3b2f21df26dd0f32ea1c00dd37 - + https://github.com/dotnet/sdk - b578d95670266ce6884f594e3d998a459f9d5100 + 35b2c21ea64c7b401b77076516d9319879d8314b - + https://github.com/dotnet/runtime - 4049205d3a0889def4a7b911ba0754b382959a8d + a5cc707d976a14495462c9c492a921ff0927b8f5 diff --git a/eng/Versions.props b/eng/Versions.props index 987f2ce87f2..102b87663dc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,8 +52,8 @@ 9.0.0-beta.24303.1 9.0.0-beta.24303.1 - 9.0.0-preview.5.24305.1 - 9.0.0-preview.5.24305.1 + 9.0.0-preview.5.24306.11 + 9.0.0-preview.5.24306.11 2.0.0-beta4.24209.3 @@ -64,10 +64,10 @@ 9.0.0-preview.24303.1 - 9.0.0-preview.5.24304.9 - 9.0.0-preview.5.24304.9 + 9.0.0-preview.5.24306.7 + 9.0.0-preview.5.24306.7 - 9.0.100-preview.5.24305.12 + 9.0.100-preview.5.24307.3 1.0.530301 From 3b0d3f249dd80af61412073baba597591f8045a5 Mon Sep 17 00:00:00 2001 From: Justin Anderson Date: Mon, 1 Jul 2024 12:32:00 -0700 Subject: [PATCH 034/174] Update Microsoft.Identity.Web to 2.20.0 (#6930) --- eng/dependabot/independent/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/dependabot/independent/Versions.props b/eng/dependabot/independent/Versions.props index a9d931e2b94..25d8f81a5d0 100644 --- a/eng/dependabot/independent/Versions.props +++ b/eng/dependabot/independent/Versions.props @@ -5,7 +5,7 @@ 1.12.0 12.20.0 12.18.0 - 2.19.1 + 2.20.0 1.6.15 4.3.2 5.0.0 From 6aecb614d0855bde65feb98ade7f5564d804303a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 11:43:11 -0700 Subject: [PATCH 035/174] Update dependencies from https://github.com/dotnet/sdk build 20240628.19 (#6938) VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0 From Version 9.0.100-preview.7.24329.1 -> To Version 9.0.100-preview.6.24328.19 Dependency coherency updates Microsoft.AspNetCore.App.Runtime.win-x64,Microsoft.NETCore.App.Runtime.win-x64,VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0,VS.Redist.Common.NetCore.SharedFramework.x64.9.0 From Version 9.0.0-preview.7.24328.7 -> To Version 9.0.0-preview.6.24328.4 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index bc22aa8a2ab..f3b0604fb8a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/aspnetcore - 77994c64cee73e0093fe25cd434bee8bd2580b4e + f5084525411d53b81d9950b68616117750b674d4 https://github.com/dotnet/diagnostics @@ -46,21 +46,21 @@ https://github.com/dotnet/diagnostics 36353b20e53e0c4af482e4fbe1d0a572515f14a2 - + https://github.com/dotnet/runtime - d88e6680e1f9e2cb4f5ee428aa169ab715158eab + 573461dc897731c11d6166574b77a8c3aabba220 - + https://github.com/dotnet/aspnetcore - 77994c64cee73e0093fe25cd434bee8bd2580b4e + f5084525411d53b81d9950b68616117750b674d4 - + https://github.com/dotnet/sdk - a081e8d8cdcce5cb0b0329cf68cf190060e870a6 + ef4c24166691977558e5312758df4313ab310dc0 - + https://github.com/dotnet/runtime - d88e6680e1f9e2cb4f5ee428aa169ab715158eab + 573461dc897731c11d6166574b77a8c3aabba220 diff --git a/eng/Versions.props b/eng/Versions.props index 3cce96a6727..5702527657d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,8 +52,8 @@ 9.0.0-beta.24327.1 9.0.0-beta.24327.1 - 9.0.0-preview.7.24328.7 - 9.0.0-preview.7.24328.7 + 9.0.0-preview.6.24328.4 + 9.0.0-preview.6.24328.4 2.0.0-beta4.24324.3 @@ -62,10 +62,10 @@ 9.0.0-preview.24324.1 - 9.0.0-preview.7.24327.11 - 9.0.0-preview.7.24327.11 + 9.0.0-preview.6.24327.7 + 9.0.0-preview.6.24327.7 - 9.0.100-preview.7.24329.1 + 9.0.100-preview.6.24328.19 1.0.532801 From 85af7ba669acd49fd816e5fbd760027308a99000 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 17:55:25 -0700 Subject: [PATCH 036/174] Update dependencies from https://github.com/dotnet/sdk build 20240802.8 (#7095) VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0 From Version 9.0.100-preview.6.24328.19 -> To Version 9.0.100-preview.7.24402.8 Dependency coherency updates Microsoft.AspNetCore.App.Runtime.win-x64,Microsoft.NETCore.App.Runtime.win-x64,VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0,VS.Redist.Common.NetCore.SharedFramework.x64.9.0 From Version 9.0.0-preview.6.24328.4 -> To Version 9.0.0-preview.7.24402.2 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f3b0604fb8a..f401452d70a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/aspnetcore - f5084525411d53b81d9950b68616117750b674d4 + 4e5de62265bf243bdb7b295ce0f6f06fceea83d1 https://github.com/dotnet/diagnostics @@ -46,21 +46,21 @@ https://github.com/dotnet/diagnostics 36353b20e53e0c4af482e4fbe1d0a572515f14a2 - + https://github.com/dotnet/runtime - 573461dc897731c11d6166574b77a8c3aabba220 + 61126f5d957b6089e8e97604a0fc79c3b4c3ee5a - + https://github.com/dotnet/aspnetcore - f5084525411d53b81d9950b68616117750b674d4 + 4e5de62265bf243bdb7b295ce0f6f06fceea83d1 - + https://github.com/dotnet/sdk - ef4c24166691977558e5312758df4313ab310dc0 + afec422ea7f93e774c804584e49bdc305f022c65 - + https://github.com/dotnet/runtime - 573461dc897731c11d6166574b77a8c3aabba220 + 61126f5d957b6089e8e97604a0fc79c3b4c3ee5a diff --git a/eng/Versions.props b/eng/Versions.props index 5702527657d..1a3aca6de0d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,8 +52,8 @@ 9.0.0-beta.24327.1 9.0.0-beta.24327.1 - 9.0.0-preview.6.24328.4 - 9.0.0-preview.6.24328.4 + 9.0.0-preview.7.24402.2 + 9.0.0-preview.7.24402.2 2.0.0-beta4.24324.3 @@ -62,10 +62,10 @@ 9.0.0-preview.24324.1 - 9.0.0-preview.6.24327.7 - 9.0.0-preview.6.24327.7 + 9.0.0-preview.7.24401.8 + 9.0.0-preview.7.24401.8 - 9.0.100-preview.6.24328.19 + 9.0.100-preview.7.24402.8 1.0.532801 From 8e327f63ee32c1071ecd7395d731c4fecad0e65f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 13:40:35 -0700 Subject: [PATCH 037/174] Update dependencies from https://github.com/dotnet/sdk build 20240807.12 (#7123) VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0 From Version 9.0.100-preview.7.24402.8 -> To Version 9.0.100-preview.7.24407.12 Dependency coherency updates Microsoft.AspNetCore.App.Runtime.win-x64,Microsoft.NETCore.App.Runtime.win-x64,VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0,VS.Redist.Common.NetCore.SharedFramework.x64.9.0 From Version 9.0.0-preview.7.24402.2 -> To Version 9.0.0-preview.7.24406.2 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4107ea74c6b..a6baabe447a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/aspnetcore - 4e5de62265bf243bdb7b295ce0f6f06fceea83d1 + abc2c7226ff616316cd1e05d76e6c36b49ce06a1 https://github.com/dotnet/diagnostics @@ -46,21 +46,21 @@ https://github.com/dotnet/diagnostics 2c1994334add963416f2f4431152c58504fbc443 - + https://github.com/dotnet/runtime - 61126f5d957b6089e8e97604a0fc79c3b4c3ee5a + 0d79e6de8dbc26a44dde336a9a680940e92e9904 - + https://github.com/dotnet/aspnetcore - 4e5de62265bf243bdb7b295ce0f6f06fceea83d1 + abc2c7226ff616316cd1e05d76e6c36b49ce06a1 - + https://github.com/dotnet/sdk - afec422ea7f93e774c804584e49bdc305f022c65 + d672b8a0459b4888b3e9a6530646e61dd14941b2 - + https://github.com/dotnet/runtime - 61126f5d957b6089e8e97604a0fc79c3b4c3ee5a + 0d79e6de8dbc26a44dde336a9a680940e92e9904 diff --git a/eng/Versions.props b/eng/Versions.props index 8c4df91c356..0860d8c2260 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,8 +52,8 @@ 9.0.0-beta.24405.1 9.0.0-beta.24405.1 - 9.0.0-preview.7.24402.2 - 9.0.0-preview.7.24402.2 + 9.0.0-preview.7.24406.2 + 9.0.0-preview.7.24406.2 2.0.0-beta4.24324.3 @@ -62,10 +62,10 @@ 9.0.0-preview.24402.1 - 9.0.0-preview.7.24401.8 - 9.0.0-preview.7.24401.8 + 9.0.0-preview.7.24405.7 + 9.0.0-preview.7.24405.7 - 9.0.100-preview.7.24402.8 + 9.0.100-preview.7.24407.12 1.0.540601 From 98619ba0ab7ffc33f06c03dcb39b10c59f1f32a0 Mon Sep 17 00:00:00 2001 From: Justin Anderson Date: Fri, 30 Aug 2024 13:50:15 -0700 Subject: [PATCH 038/174] Get runtime feed token for Helix (#7235) --- eng/pipelines/jobs/test-binaries.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/eng/pipelines/jobs/test-binaries.yml b/eng/pipelines/jobs/test-binaries.yml index 01078684b3e..2c8c9159da3 100644 --- a/eng/pipelines/jobs/test-binaries.yml +++ b/eng/pipelines/jobs/test-binaries.yml @@ -117,6 +117,12 @@ jobs: -DestinationFolder "$(HelixNodejsPayloadPath)" displayName: Hydrate Node.js Installation Non-Linux + # Populate dotnetbuilds-internal-container-read-token for Helix + - template: /eng/common/templates/steps/enable-internal-runtimes.yml + parameters: + outputVariableName: 'dotnetbuilds-internal-container-read-token' + base64Encode: false + - ${{ else }}: - ${{ if ne(parameters.osGroup, 'Windows') }}: - task: NodeTool@0 From d4679c2ccf9bf438f6e4d63380a0b0952c6f3ef9 Mon Sep 17 00:00:00 2001 From: Justin Anderson Date: Fri, 30 Aug 2024 18:58:28 -0700 Subject: [PATCH 039/174] Increase token expiration and retry until compatible token (#7239) --- .../steps/get-delegation-sas.yml | 19 ++++++++++++------- eng/pipelines/jobs/test-binaries.yml | 3 ++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/eng/common/core-templates/steps/get-delegation-sas.yml b/eng/common/core-templates/steps/get-delegation-sas.yml index d2901470a7f..b82f0c56bff 100644 --- a/eng/common/core-templates/steps/get-delegation-sas.yml +++ b/eng/common/core-templates/steps/get-delegation-sas.yml @@ -28,15 +28,20 @@ steps: scriptType: 'pscore' scriptLocation: 'inlineScript' inlineScript: | - # Calculate the expiration of the SAS token and convert to UTC - $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") + # Temporarily work around a helix issue where SAS tokens with / in them will cause incorrect downloads + # of correlation payloads. See https://github.com/dotnet/dnceng/issues/3484 + $sas = "" + do { + # Calculate the expiration of the SAS token and convert to UTC + $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") - $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv + $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv - if ($LASTEXITCODE -ne 0) { - Write-Error "Failed to generate SAS token." - exit 1 - } + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to generate SAS token." + exit 1 + } + } while($sas.IndexOf('/') -ne -1) if ('${{ parameters.base64Encode }}' -eq 'true') { $sas = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($sas)) diff --git a/eng/pipelines/jobs/test-binaries.yml b/eng/pipelines/jobs/test-binaries.yml index 2c8c9159da3..0f961756b5e 100644 --- a/eng/pipelines/jobs/test-binaries.yml +++ b/eng/pipelines/jobs/test-binaries.yml @@ -118,10 +118,11 @@ jobs: displayName: Hydrate Node.js Installation Non-Linux # Populate dotnetbuilds-internal-container-read-token for Helix - - template: /eng/common/templates/steps/enable-internal-runtimes.yml + - template: /eng/common/templates-official/steps/enable-internal-runtimes.yml parameters: outputVariableName: 'dotnetbuilds-internal-container-read-token' base64Encode: false + expiryInHours: 2 # Match the job timeout; Helix can take a long time to process tests depending on queue depth - ${{ else }}: - ${{ if ne(parameters.osGroup, 'Windows') }}: From 5b0d53ad633be463b84ee97235e986394759d239 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:59:38 +0000 Subject: [PATCH 040/174] Update dependencies from https://github.com/dotnet/sdk build 20240902.12 (#7255) VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0 From Version 9.0.100-preview.7.24407.12 -> To Version 9.0.100-rc.1.24452.12 Dependency coherency updates Microsoft.AspNetCore.App.Runtime.win-x64,Microsoft.NETCore.App.Runtime.win-x64,VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0,VS.Redist.Common.NetCore.SharedFramework.x64.9.0 From Version 9.0.0-preview.7.24406.2 -> To Version 9.0.0-rc.1.24452.1 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 761e712da7a..7a771238c9f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - + https://github.com/dotnet/aspnetcore - abc2c7226ff616316cd1e05d76e6c36b49ce06a1 + 280c613963a1768b810d09f32c998fe4490855e9 https://github.com/dotnet/diagnostics @@ -46,21 +46,21 @@ https://github.com/dotnet/diagnostics 14e21788fb5764ecf586abe0fa0633418c6f255b - + https://github.com/dotnet/runtime - 0d79e6de8dbc26a44dde336a9a680940e92e9904 + c4d7f7c6f2e2f34f07e64c6caa3bf9b2ce915cc1 - + https://github.com/dotnet/aspnetcore - abc2c7226ff616316cd1e05d76e6c36b49ce06a1 + 280c613963a1768b810d09f32c998fe4490855e9 - + https://github.com/dotnet/sdk - d672b8a0459b4888b3e9a6530646e61dd14941b2 + 81a714c6d3ad9ce8d045cfa7afd887147c3d69f2 - + https://github.com/dotnet/runtime - 0d79e6de8dbc26a44dde336a9a680940e92e9904 + c4d7f7c6f2e2f34f07e64c6caa3bf9b2ce915cc1 diff --git a/eng/Versions.props b/eng/Versions.props index e31b33e18c4..da1f84738e8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,8 +52,8 @@ 9.0.0-beta.24426.3 9.0.0-beta.24426.3 - 9.0.0-preview.7.24406.2 - 9.0.0-preview.7.24406.2 + 9.0.0-rc.1.24452.1 + 9.0.0-rc.1.24452.1 2.0.0-beta4.24324.3 @@ -62,10 +62,10 @@ 9.0.0-preview.24415.1 - 9.0.0-preview.7.24405.7 - 9.0.0-preview.7.24405.7 + 9.0.0-rc.1.24431.7 + 9.0.0-rc.1.24431.7 - 9.0.100-preview.7.24407.12 + 9.0.100-rc.1.24452.12 1.0.542704 From c8be1f8bf4e8f1492b8353fbd728f37f9c390dd5 Mon Sep 17 00:00:00 2001 From: maestro-prod-Primary Date: Thu, 3 Oct 2024 22:22:04 +0000 Subject: [PATCH 041/174] Merged PR 43342: [internal/release/9.x] Update dependencies from dnceng/internal/dotnet-sdk This pull request updates the following dependencies [marker]: <> (Begin:Coherency Updates) ## Coherency Updates The following updates ensure that dependencies with a *CoherentParentDependency* attribute were produced in a build used as input to the parent dependency's build. See [Dependency Description Format](https://github.com/dotnet/arcade/blob/master/Documentation/DependencyDescriptionFormat.md#dependency-description-overview) [DependencyUpdate]: <> (Begin) - **Coherency Updates**: - **Microsoft.AspNetCore.App.Runtime.win-x64**: from 9.0.0-rc.1.24452.1 to 9.0.0-rc.2.24474.3 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0) - **Microsoft.NETCore.App.Runtime.win-x64**: from 9.0.0-rc.1.24431.7 to 9.0.0-rc.2.24473.5 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0) - **VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0**: from 9.0.0-rc.1.24452.1 to 9.0.0-rc.2.24474.3 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0) - **VS.Redist.Common.NetCore.SharedFramework.x64.9.0**: from 9.0.0-rc.1.24431.7 to 9.0.0-rc.2.24473.5 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0) [DependencyUpdate]: <> (End) [marker]: <> (End:Coherency Updates) [marker]: <> (Begin:a3707f2a-b737-48ab-a194-a0970b0eb216) ## From https://dev.azure.com/dnceng/internal/_git/dotnet-sdk - **Subscription**: a3707f2a-b737-48ab-a194-a0970b0eb216 - **Build**: 20240924.11 - **Date Produced**: September 24, 2024 8:08:41 PM UTC - **Commit**: 315e1305dbe1a5ef5870faab5dc12d3a375f61eb - **Branch**: refs/heads/internal/release/9.0.1xx-rc2 [DependencyUpdate]: <> (Begin) - **Updates**: - **VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0**: [from 9.0.100-rc.1.24452.12 to 9.0.100-rc.2.24474.11][1] - **Microsoft.AspNetCore.App.Runtime.win-x64**: [from 9.0.0-rc.1.24452.1 to 9.0.0-rc.2.24474.3][2] - **Microsoft.NETCore.App.Runtime.win-x64**: [from 9.0.0-rc.1.24431.7 to 9.0.0-rc.2.24473.5][3] - **VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0**: [from 9.0.0-rc.1.24452.1 to 9.0.0-rc.2.24474.3][2] - **VS.Redist.Common.NetCore.SharedFramework.x64.9.0**: [from 9.0.0-rc.1.24431.7 to 9.0.0-rc.2.24473.5][3] [1]: https://dev.azure.com/dnceng/internal/_git/dotnet-sdk/branches?baseVersion=GC81a714c6d3ad9ce8d045cfa7afd887147c3d69f2&targetVersion=GC315e1305dbe1a5ef5870faab5dc12d3a375f61eb&_a=files [2]: https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore/branches?baseVersion=GC280c613963a1768b810d09f32c998fe4490855e9&targetVersion=GCc70204ae3c91d2b48fa6d9b92b62265f368421b4&_a=files [3]: https://dev.azure.com/dnceng/internal/_git/dotnet-runtime/branches?baseVersion=GCc4d7f7c6f2e2f34f07e64c6caa3bf9b2ce915cc1&targetVersion=GC990ebf52fc408ca45929fd176d2740675a67fab8&_a=files [DependencyUpdate]: <> (End) [marker]: <> (End:a3707f2a-b737-48ab-a194-a0970b0eb216) --- eng/Version.Details.xml | 30 +++++++++++++++--------------- eng/Versions.props | 10 +++++----- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f28780165a5..0a7390cc2ff 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - - https://github.com/dotnet/aspnetcore - 280c613963a1768b810d09f32c998fe4490855e9 + + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore + c70204ae3c91d2b48fa6d9b92b62265f368421b4 https://github.com/dotnet/diagnostics @@ -46,21 +46,21 @@ https://github.com/dotnet/diagnostics 8227c4f39865220c1e80b18b6a7fd8fe3d8e4546 - - https://github.com/dotnet/runtime - c4d7f7c6f2e2f34f07e64c6caa3bf9b2ce915cc1 + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 990ebf52fc408ca45929fd176d2740675a67fab8 - - https://github.com/dotnet/aspnetcore - 280c613963a1768b810d09f32c998fe4490855e9 + + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore + c70204ae3c91d2b48fa6d9b92b62265f368421b4 - - https://github.com/dotnet/sdk - 81a714c6d3ad9ce8d045cfa7afd887147c3d69f2 + + https://dev.azure.com/dnceng/internal/_git/dotnet-sdk + 315e1305dbe1a5ef5870faab5dc12d3a375f61eb - - https://github.com/dotnet/runtime - c4d7f7c6f2e2f34f07e64c6caa3bf9b2ce915cc1 + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 990ebf52fc408ca45929fd176d2740675a67fab8 diff --git a/eng/Versions.props b/eng/Versions.props index 927c116bb7e..ffab8216181 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,8 +52,8 @@ 9.0.0-beta.24501.3 9.0.0-beta.24501.3 - 9.0.0-rc.1.24452.1 - 9.0.0-rc.1.24452.1 + 9.0.0-rc.2.24474.3 + 9.0.0-rc.2.24474.3 2.0.0-beta4.24324.3 @@ -62,10 +62,10 @@ 9.0.0-preview.24479.1 - 9.0.0-rc.1.24431.7 - 9.0.0-rc.1.24431.7 + 9.0.0-rc.2.24473.5 + 9.0.0-rc.2.24473.5 - 9.0.100-rc.1.24452.12 + 9.0.100-rc.2.24474.11 1.0.547901 From e78281986a979ddcc017397b7a680ac2fcb2e0e5 Mon Sep 17 00:00:00 2001 From: Wiktor Kopec Date: Thu, 3 Oct 2024 22:22:38 +0000 Subject: [PATCH 042/174] Merged PR 43343: Update System.Text.Json version to rc2 Update System.Text.Json version to rc2 ---- #### AI description (iteration 1) #### PR Classification Dependency update #### PR Summary This pull request updates the version of `System.Text.Json` to the latest release candidate. - Updated `SystemTextJson90Version` in `eng/dependabot/net9.0/Versions.props` from `9.0.0-rc.1.24431.7` to `9.0.0-rc.2.24473.5`. --- eng/dependabot/net9.0/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/dependabot/net9.0/Versions.props b/eng/dependabot/net9.0/Versions.props index b2e79649173..3f694372110 100644 --- a/eng/dependabot/net9.0/Versions.props +++ b/eng/dependabot/net9.0/Versions.props @@ -1,6 +1,6 @@ - 9.0.0-rc.1.24431.7 + 9.0.0-rc.2.24473.5 From 5bf41dc1cc7b148fb793088ddc648f9a455423c3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 07:26:01 +0000 Subject: [PATCH 043/174] Use DotNetStaging service connection credentials to gather drop (#7414) --- eng/pipelines/stages/preparerelease.yml | 25 +------------------------ eng/release/Scripts/AcquireBuild.ps1 | 5 ++--- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/eng/pipelines/stages/preparerelease.yml b/eng/pipelines/stages/preparerelease.yml index 69a50657678..407676f28ea 100644 --- a/eng/pipelines/stages/preparerelease.yml +++ b/eng/pipelines/stages/preparerelease.yml @@ -49,39 +49,16 @@ stages: -BarId $(BARBuildId) -TaskVariableName 'BuildVersion' - # Populate dotnetbuilds-internal-container-read-token - - template: /eng/common/templates-official/steps/get-delegation-sas.yml - parameters: - federatedServiceConnection: 'dotnetbuilds-internal-read' - outputVariableName: 'dotnetbuilds-internal-checksums-container-read-token' - expiryInHours: 1 - base64Encode: false - storageAccount: dotnetbuilds - container: internal-checksums - permissions: rl - - # Populate dotnetbuilds-internal-container-read-token - - template: /eng/common/templates-official/steps/get-delegation-sas.yml - parameters: - federatedServiceConnection: 'dotnetbuilds-internal-read' - outputVariableName: 'dotnetbuilds-internal-container-read-token' - expiryInHours: 1 - base64Encode: false - storageAccount: dotnetbuilds - container: internal - permissions: rl - - task: AzureCLI@2 displayName: 'Download Build Assets' inputs: - azureSubscription: 'Darc: Maestro Production' + azureSubscription: 'DotNetStaging' scriptType: ps scriptPath: '$(Build.Repository.LocalPath)/eng/release/Scripts/AcquireBuild.ps1' arguments: >- -BarBuildId "$(BARBuildId)" -AzdoToken "$(dn-bot-all-drop-rw-code-rw-release-all)" -DownloadTargetPath "$(System.ArtifactsDirectory)\BuildAssets" - -SasSuffixes "$(dotnetbuilds-internal-checksums-container-read-token),$(dotnetbuilds-internal-container-read-token)" -ReleaseVersion "$(Build.BuildNumber)" workingDirectory: '$(Build.Repository.LocalPath)' continueOnError: true diff --git a/eng/release/Scripts/AcquireBuild.ps1 b/eng/release/Scripts/AcquireBuild.ps1 index 220c6ff13fd..71382e413a6 100644 --- a/eng/release/Scripts/AcquireBuild.ps1 +++ b/eng/release/Scripts/AcquireBuild.ps1 @@ -2,7 +2,6 @@ param( [Parameter(Mandatory=$true)][int] $BarBuildId, [Parameter(Mandatory=$true)][string] $ReleaseVersion, [Parameter(Mandatory=$true)][string] $DownloadTargetPath, - [Parameter(Mandatory=$true)][string] $SasSuffixes, [Parameter(Mandatory=$true)][string] $AzdoToken, [Parameter(Mandatory=$false)][string] $DarcVersion = $null, [Parameter(Mandatory=$false)][bool] $Separated = $true, @@ -14,7 +13,6 @@ function Write-Help() { Write-Host " -BarBuildId BAR Build ID of the diagnostics build to publish." Write-Host " -ReleaseVersion Name to give the diagnostics release." Write-Host " -DownloadTargetPath Path to download the build to." - Write-Host " -SasSuffixes Comma separated list of potential uri suffixes that can be used if anonymous access to a blob uri fails. Appended directly to the end of the URI. Use full SAS syntax with ?." Write-Host " -AzdoToken Azure DevOps token to use for builds queries" Write-Host " -Separated <`$true|`$false> Download files to their repo separated locations." Write-Host "" @@ -55,11 +53,12 @@ try { --release-name $ReleaseVersion ` --output-dir $DownloadTargetPath ` --overwrite ` - --sas-suffixes $SasSuffixes ` + --use-azure-credential-for-blobs ` --azdev-pat $AzdoToken ` --verbose ` --continue-on-error ` --ci ` + --verbose ` $separatedArgs if ($LastExitCode -ne 0) { From 2d7ecf9ada4024b631b0b2dd50dad536bc80c380 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 08:42:34 -0700 Subject: [PATCH 044/174] Remove extra verbose switch (#7420) --- eng/release/Scripts/AcquireBuild.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/eng/release/Scripts/AcquireBuild.ps1 b/eng/release/Scripts/AcquireBuild.ps1 index 71382e413a6..d8bb485a116 100644 --- a/eng/release/Scripts/AcquireBuild.ps1 +++ b/eng/release/Scripts/AcquireBuild.ps1 @@ -58,7 +58,6 @@ try { --verbose ` --continue-on-error ` --ci ` - --verbose ` $separatedArgs if ($LastExitCode -ne 0) { From 7edf66f696d59cfa70d1207b2ab1337404153e61 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:47:56 -0800 Subject: [PATCH 045/174] Temporarily exclude flaky tests (#7616) Co-authored-by: Wiktor Kopec --- .../CollectionRuleActions.UnitTests/CollectDumpActionTests.cs | 2 +- .../CollectionRuleTests.cs | 2 +- .../ExceptionsTests.cs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs index f853d5e7208..96c486f34dd 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs @@ -36,7 +36,7 @@ public CollectDumpActionTests(ITestOutputHelper outputHelper) _endpointUtilities = new(_outputHelper); } - [Theory] + [Theory(Skip = "Flaky")] [MemberData(nameof(ActionTestsHelper.GetTfmsAndDumpTypes), MemberType = typeof(ActionTestsHelper))] public Task CollectDumpAction_Success(TargetFrameworkMoniker tfm, DumpType dumpType) { diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/CollectionRuleTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/CollectionRuleTests.cs index 34d19f35669..1b31d227059 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/CollectionRuleTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/CollectionRuleTests.cs @@ -76,7 +76,7 @@ await ScenarioRunner.SingleTarget( /// Validates that a non-startup rule will complete when it has an action limit specified /// without a sliding window duration. /// - [Theory] + [Theory(Skip = "Flaky")] [InlineData(DiagnosticPortConnectionMode.Listen)] public async Task CollectionRule_ActionLimitTest(DiagnosticPortConnectionMode mode) { diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/ExceptionsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/ExceptionsTests.cs index fd27b37f654..f5bc5d2ef0b 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/ExceptionsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/ExceptionsTests.cs @@ -348,7 +348,7 @@ await ScenarioRunner.SingleTarget( }); } - [Theory] + [Theory(Skip = "Flaky")] [MemberData(nameof(ProfilerHelper.GetArchitecture), MemberType = typeof(ProfilerHelper))] public async Task Exceptions_FilterIncludeBasic(Architecture targetArchitecture) { @@ -387,7 +387,7 @@ await ScenarioRunner.SingleTarget( }); } - [Theory] + [Theory(Skip = "Flaky")] [MemberData(nameof(ProfilerHelper.GetArchitecture), MemberType = typeof(ProfilerHelper))] public async Task Exceptions_FilterIncludeMultiple(Architecture targetArchitecture) { From 34dc0732ed8ae3f785552ec9c713bcbb4ae552fd Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 14:33:22 -0800 Subject: [PATCH 046/174] Update dependencies from https://github.com/dotnet/diagnostics build 20241031.1 (#7618) Microsoft.Diagnostics.Monitoring , Microsoft.Diagnostics.Monitoring.EventPipe , Microsoft.FileFormats From Version 9.0.0-preview.24554.2 -> To Version 9.0.553101 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c09caa4d5ad..4772367d6ab 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -4,13 +4,13 @@ https://github.com/dotnet/aspnetcore 1e7a7af6d2417242b244d2a0f4f23fcce8e88d2f - + https://github.com/dotnet/diagnostics - da9510470934a71eaa1165e3276a57e08148e061 + 5b61d34de04d6100e6003415f7d7e9c4b971afd4 - + https://github.com/dotnet/diagnostics - da9510470934a71eaa1165e3276a57e08148e061 + 5b61d34de04d6100e6003415f7d7e9c4b971afd4 https://github.com/dotnet/command-line-api @@ -42,9 +42,9 @@ https://github.com/dotnet/arcade 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d - + https://github.com/dotnet/diagnostics - da9510470934a71eaa1165e3276a57e08148e061 + 5b61d34de04d6100e6003415f7d7e9c4b971afd4 https://github.com/dotnet/runtime diff --git a/eng/Versions.props b/eng/Versions.props index 62787d28640..28c9938ff40 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -57,8 +57,8 @@ 2.0.0-beta4.24528.1 - 9.0.0-preview.24554.2 - 9.0.0-preview.24554.2 + 9.0.553101 + 9.0.553101 9.0.0-preview.24527.2 @@ -67,7 +67,7 @@ 9.0.100-rtm.24527.3 - 1.0.555402 + 1.0.553101 $(MicrosoftNETCoreApp31Version) From d7749bb3e56085dcd84ba2954a609cf39e3f3162 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 14:33:44 -0800 Subject: [PATCH 047/174] Update .NET 9 System.Text.Json to 9.0.0 (#7620) Co-authored-by: Justin Anderson --- eng/dependabot/net9.0/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/dependabot/net9.0/Versions.props b/eng/dependabot/net9.0/Versions.props index 3f694372110..4e54abecb78 100644 --- a/eng/dependabot/net9.0/Versions.props +++ b/eng/dependabot/net9.0/Versions.props @@ -1,6 +1,6 @@ - 9.0.0-rc.2.24473.5 + 9.0.0 From 59bc5ae17b694df7e98386e33d9ab5b6afa4bd0e Mon Sep 17 00:00:00 2001 From: maestro-prod-Primary Date: Thu, 7 Nov 2024 00:03:14 +0000 Subject: [PATCH 048/174] Merged PR 44784: [internal/release/9.x] Update dependencies from dnceng/internal/dotnet-sdk This pull request updates the following dependencies [marker]: <> (Begin:Coherency Updates) ## Coherency Updates The following updates ensure that dependencies with a *CoherentParentDependency* attribute were produced in a build used as input to the parent dependency's build. See [Dependency Description Format](https://github.com/dotnet/arcade/blob/master/Documentation/DependencyDescriptionFormat.md#dependency-description-overview) [DependencyUpdate]: <> (Begin) - **Coherency Updates**: - **Microsoft.AspNetCore.App.Runtime.win-x64**: from 9.0.0 to 9.0.0 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0) - **Microsoft.NETCore.App.Runtime.win-x64**: from 9.0.0 to 9.0.0 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0) - **VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0**: from 9.0.0-rtm.24516.19 to 9.0.0-rtm.24529.3 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0) - **VS.Redist.Common.NetCore.SharedFramework.x64.9.0**: from 9.0.0-rtm.24516.10 to 9.0.0-rtm.24528.9 (parent: VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0) [DependencyUpdate]: <> (End) [marker]: <> (End:Coherency Updates) [marker]: <> (Begin:b74caaea-4545-46c6-bd47-405c0b14bdb6) ## From https://dev.azure.com/dnceng/internal/_git/dotnet-sdk - **Subscription**: b74caaea-4545-46c6-bd47-405c0b14bdb6 - **Build**: 20241029.9 - **Date Produced**: October 29, 2024 4:48:28 PM UTC - **Commit**: 59db016f11bb27d359336cf37524b863d77e7fea - **Branch**: refs/heads/internal/release/9.0.1xx [DependencyUpdate]: <> (Begin) - **Updates**: - **VS.Redist.Common.NetCore.SdkPlaceholder.x64.9.0**: [from 9.0.100-rtm.24527.3 to 9.0.100-rtm.24529.9][1] - **Microsoft.AspNetCore.App.Runtime.win-x64**: [from 9.0.0 to 9.0.0][2] - **Microsoft.NETCore.App.Runtime.win-x64**: [from 9.0.0 to 9.0.0][3] - **VS.Redist.Common.AspNetCore.SharedFramework.x64.9.0**: [from 9.0.0-rtm.24516.19 to 9.0.0-rtm.24529.3][2] - **VS.Redist.Common.NetCore.SharedFramework.x64.9.0**: [from 9.0.0-rtm.24516.10 to 9.0.0-rtm.24528.9][3] [1]: https://dev.azure.com/dnceng/internal/_git/dotnet-sdk/branches?baseVersion=GC50e04b8d1d8ff413de90383aa799e4189612f685&targetVersion=GC59db016f11bb27d359336cf37524b863d77e7fea&_a=files [2]: https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore/branches?baseVersion=GC1e7a7af6d2417242b244d2a0f4f23fcce8e88d2f&targetVersion=GCaf22effae4069a5dfb9b0735859de48820104f5b&_a=files [3]: https://dev.azure.com/dnceng/internal/_git/dotnet-runtime/branches?baseVersion=GCd3981726bc8b0e179db50301daf9f22d42393096&targetVersion=GC9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3&_a=files [DependencyUpdate]: <> (End) [marker]: <> (End:b74caaea-4545-46c6-bd47-405c0b14bdb6) --- NuGet.config | 28 ++++++++++++++++++++++++++-- eng/Version.Details.xml | 26 +++++++++++++------------- eng/Versions.props | 6 +++--- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/NuGet.config b/NuGet.config index f5a34821b11..9394f724a19 100644 --- a/NuGet.config +++ b/NuGet.config @@ -10,10 +10,21 @@ - + + + + + + + + + + - + + + @@ -32,8 +43,21 @@ + + + + + + + + + + + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4772367d6ab..d29446b3323 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,8 +1,8 @@ - https://github.com/dotnet/aspnetcore - 1e7a7af6d2417242b244d2a0f4f23fcce8e88d2f + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore + af22effae4069a5dfb9b0735859de48820104f5b https://github.com/dotnet/diagnostics @@ -47,20 +47,20 @@ 5b61d34de04d6100e6003415f7d7e9c4b971afd4 - https://github.com/dotnet/runtime - d3981726bc8b0e179db50301daf9f22d42393096 + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 - - https://github.com/dotnet/aspnetcore - 1e7a7af6d2417242b244d2a0f4f23fcce8e88d2f + + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore + af22effae4069a5dfb9b0735859de48820104f5b - - https://github.com/dotnet/sdk - 50e04b8d1d8ff413de90383aa799e4189612f685 + + https://dev.azure.com/dnceng/internal/_git/dotnet-sdk + 59db016f11bb27d359336cf37524b863d77e7fea - - https://github.com/dotnet/runtime - d3981726bc8b0e179db50301daf9f22d42393096 + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 9d5a6a9aa463d6d10b0b0ba6d5982cc82f363dc3 diff --git a/eng/Versions.props b/eng/Versions.props index 28c9938ff40..f9a58688d5a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -53,7 +53,7 @@ 9.0.0-beta.24516.2 9.0.0 - 9.0.0-rtm.24516.19 + 9.0.0-rtm.24529.3 2.0.0-beta4.24528.1 @@ -63,9 +63,9 @@ 9.0.0-preview.24527.2 9.0.0 - 9.0.0-rtm.24516.10 + 9.0.0-rtm.24528.9 - 9.0.100-rtm.24527.3 + 9.0.100-rtm.24529.9 1.0.553101 From 08fde9b80215d428826bc46228f136844d58ce28 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 01:11:31 +0000 Subject: [PATCH 049/174] Update ExceptionsStoreTests.cs (#7622) Co-authored-by: Joe Schmitt <1146681+schmittjoseph@users.noreply.github.com> --- .../ExceptionsStoreTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExceptionsStoreTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExceptionsStoreTests.cs index 1001e054c4c..0964afc88a6 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExceptionsStoreTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExceptionsStoreTests.cs @@ -199,7 +199,7 @@ public async Task ExceptionsStore_AddThreeRemoveThree_Empty() /// Validates adding exceptions and removing all exceptions in an unordered manner /// will invoke the callback and the store will be empty. /// - [Fact] + [Fact(Skip = "Flaky")] public async Task ExceptionsStore_AddThreeRemoveThreeOutOfOrder_Empty() { ulong ExpectedId1 = 1; From 4fe2a7b3a85bf36d927c07dd52b824a8d267d11c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 13:41:01 -0800 Subject: [PATCH 050/174] Add retry to notice generation (#7636) --- eng/pipelines/jobs/tpn.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/pipelines/jobs/tpn.yml b/eng/pipelines/jobs/tpn.yml index 7ec25caa3b4..9ca72f1aee5 100644 --- a/eng/pipelines/jobs/tpn.yml +++ b/eng/pipelines/jobs/tpn.yml @@ -43,6 +43,7 @@ jobs: - task: notice@0 displayName: Generate TPN file + retryCountOnTaskFailure: 5 inputs: outputfile: '$(Build.ArtifactStagingDirectory)/$(_TPNFile)' outputformat: text From a3504607342e1bc1ec97205c4eb0244761417423 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:16:06 -0800 Subject: [PATCH 051/174] Disable tarball signing (#7643) Co-authored-by: Justin Anderson --- eng/Signing.props | 5 ----- 1 file changed, 5 deletions(-) diff --git a/eng/Signing.props b/eng/Signing.props index 47fa59d2ac1..7f295f84768 100644 --- a/eng/Signing.props +++ b/eng/Signing.props @@ -9,11 +9,6 @@ - - + + false + + \ No newline at end of file From 3df09ea749fccaa7f9c766003df9b4d9f3abcbf8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 21:54:40 +0000 Subject: [PATCH 054/174] update release information (#7790) --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index f9a58688d5a..0c77cd1cff5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -3,8 +3,8 @@ https://github.com/dotnet/dotnet-monitor - 9.0.0 - rtm + 9.0.1 + servicing release true From 23ba7affc2a62d9fd26e22fab78a80c2173fb8b8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 21:56:49 +0000 Subject: [PATCH 055/174] Fix Directory.Build.props file name for tests (#7792) --- src/Tests/{Directory.Builds.props => Directory.Build.props} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Tests/{Directory.Builds.props => Directory.Build.props} (100%) diff --git a/src/Tests/Directory.Builds.props b/src/Tests/Directory.Build.props similarity index 100% rename from src/Tests/Directory.Builds.props rename to src/Tests/Directory.Build.props From 2495faea154a202ba1688b84597be8da88c2829d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:12:05 -0800 Subject: [PATCH 056/174] Update dependencies from https://github.com/dotnet/arcade build 20241223.3 (#7797) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24516.2 -> To Version 9.0.0-beta.24623.3 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 26 ------- eng/Version.Details.xml | 20 +++--- eng/Versions.props | 6 +- .../steps/get-delegation-sas.yml | 17 ++--- eng/common/cross/toolchain.cmake | 67 +++++++++---------- eng/common/sdk-task.ps1 | 2 +- eng/common/tools.ps1 | 6 +- eng/common/tools.sh | 2 +- global.json | 6 +- 9 files changed, 58 insertions(+), 94 deletions(-) diff --git a/NuGet.config b/NuGet.config index 9394f724a19..c59695f632b 100644 --- a/NuGet.config +++ b/NuGet.config @@ -10,21 +10,8 @@ - - - - - - - - - - - - - @@ -43,21 +30,8 @@ - - - - - - - - - - - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d29446b3323..33e554b5674 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -22,25 +22,25 @@ https://github.com/dotnet/roslyn-analyzers 3d61c57c73c3dd5f1f407ef9cd3414d94bf0eaf2 - + https://github.com/dotnet/arcade - 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d + e0e05154656254a735ebf19ffa5a37a8b915039b - + https://github.com/dotnet/arcade - 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d + e0e05154656254a735ebf19ffa5a37a8b915039b - + https://github.com/dotnet/arcade - 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d + e0e05154656254a735ebf19ffa5a37a8b915039b - + https://github.com/dotnet/arcade - 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d + e0e05154656254a735ebf19ffa5a37a8b915039b - + https://github.com/dotnet/arcade - 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d + e0e05154656254a735ebf19ffa5a37a8b915039b https://github.com/dotnet/diagnostics diff --git a/eng/Versions.props b/eng/Versions.props index 0c77cd1cff5..9879dbfcba5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -48,9 +48,9 @@ --> - 9.0.0-beta.24516.2 - 9.0.0-beta.24516.2 - 9.0.0-beta.24516.2 + 9.0.0-beta.24623.3 + 9.0.0-beta.24623.3 + 9.0.0-beta.24623.3 9.0.0 9.0.0-rtm.24529.3 diff --git a/eng/common/core-templates/steps/get-delegation-sas.yml b/eng/common/core-templates/steps/get-delegation-sas.yml index 329e8f84b80..9db5617ea7d 100644 --- a/eng/common/core-templates/steps/get-delegation-sas.yml +++ b/eng/common/core-templates/steps/get-delegation-sas.yml @@ -28,12 +28,8 @@ steps: scriptType: 'pscore' scriptLocation: 'inlineScript' inlineScript: | - # Temporarily work around a helix issue where SAS tokens with / in them will cause incorrect downloads - # of correlation payloads. See https://github.com/dotnet/dnceng/issues/3484 - $sas = "" - do { - # Calculate the expiration of the SAS token and convert to UTC - $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") + # Calculate the expiration of the SAS token and convert to UTC + $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") # Temporarily work around a helix issue where SAS tokens with / in them will cause incorrect downloads # of correlation payloads. https://github.com/dotnet/dnceng/issues/3484 @@ -46,11 +42,10 @@ steps: } } while($sas.IndexOf('/') -ne -1) - if ($LASTEXITCODE -ne 0) { - Write-Error "Failed to generate SAS token." - exit 1 - } - } while($sas.IndexOf('/') -ne -1) + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to generate SAS token." + exit 1 + } if ('${{ parameters.base64Encode }}' -eq 'true') { $sas = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($sas)) diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake index 9a4e285a5ae..9a7ecfbd42c 100644 --- a/eng/common/cross/toolchain.cmake +++ b/eng/common/cross/toolchain.cmake @@ -40,7 +40,7 @@ if(TARGET_ARCH_NAME STREQUAL "arm") set(TOOLCHAIN "arm-linux-gnueabihf") endif() if(TIZEN) - set(TIZEN_TOOLCHAIN "armv7hl-tizen-linux-gnueabihf/9.2.0") + set(TIZEN_TOOLCHAIN "armv7hl-tizen-linux-gnueabihf") endif() elseif(TARGET_ARCH_NAME STREQUAL "arm64") set(CMAKE_SYSTEM_PROCESSOR aarch64) @@ -49,7 +49,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "arm64") elseif(LINUX) set(TOOLCHAIN "aarch64-linux-gnu") if(TIZEN) - set(TIZEN_TOOLCHAIN "aarch64-tizen-linux-gnu/9.2.0") + set(TIZEN_TOOLCHAIN "aarch64-tizen-linux-gnu") endif() elseif(FREEBSD) set(triple "aarch64-unknown-freebsd12") @@ -58,7 +58,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "armel") set(CMAKE_SYSTEM_PROCESSOR armv7l) set(TOOLCHAIN "arm-linux-gnueabi") if(TIZEN) - set(TIZEN_TOOLCHAIN "armv7l-tizen-linux-gnueabi/9.2.0") + set(TIZEN_TOOLCHAIN "armv7l-tizen-linux-gnueabi") endif() elseif(TARGET_ARCH_NAME STREQUAL "armv6") set(CMAKE_SYSTEM_PROCESSOR armv6l) @@ -81,7 +81,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "riscv64") else() set(TOOLCHAIN "riscv64-linux-gnu") if(TIZEN) - set(TIZEN_TOOLCHAIN "riscv64-tizen-linux-gnu/13.1.0") + set(TIZEN_TOOLCHAIN "riscv64-tizen-linux-gnu") endif() endif() elseif(TARGET_ARCH_NAME STREQUAL "s390x") @@ -98,7 +98,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "x64") elseif(LINUX) set(TOOLCHAIN "x86_64-linux-gnu") if(TIZEN) - set(TIZEN_TOOLCHAIN "x86_64-tizen-linux-gnu/9.2.0") + set(TIZEN_TOOLCHAIN "x86_64-tizen-linux-gnu") endif() elseif(FREEBSD) set(triple "x86_64-unknown-freebsd12") @@ -115,7 +115,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "x86") set(TOOLCHAIN "i686-linux-gnu") endif() if(TIZEN) - set(TIZEN_TOOLCHAIN "i586-tizen-linux-gnu/9.2.0") + set(TIZEN_TOOLCHAIN "i586-tizen-linux-gnu") endif() else() message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm, arm64, armel, armv6, ppc64le, riscv64, s390x, x64 and x86 are supported!") @@ -127,30 +127,25 @@ endif() # Specify include paths if(TIZEN) - if(TARGET_ARCH_NAME STREQUAL "arm") - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/) - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/armv7hl-tizen-linux-gnueabihf) - endif() - if(TARGET_ARCH_NAME STREQUAL "armel") - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/) - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/armv7l-tizen-linux-gnueabi) - endif() - if(TARGET_ARCH_NAME STREQUAL "arm64") - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/) - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/aarch64-tizen-linux-gnu) - endif() - if(TARGET_ARCH_NAME STREQUAL "x86") - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/) - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/i586-tizen-linux-gnu) - endif() - if(TARGET_ARCH_NAME STREQUAL "x64") - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/) - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/x86_64-tizen-linux-gnu) - endif() - if(TARGET_ARCH_NAME STREQUAL "riscv64") - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/) - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/riscv64-tizen-linux-gnu) + function(find_toolchain_dir prefix) + # Dynamically find the version subdirectory + file(GLOB DIRECTORIES "${prefix}/*") + list(GET DIRECTORIES 0 FIRST_MATCH) + get_filename_component(TOOLCHAIN_VERSION ${FIRST_MATCH} NAME) + + set(TIZEN_TOOLCHAIN_PATH "${prefix}/${TOOLCHAIN_VERSION}" PARENT_SCOPE) + endfunction() + + if(TARGET_ARCH_NAME MATCHES "^(arm|armel|x86)$") + find_toolchain_dir("${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + else() + find_toolchain_dir("${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") endif() + + message(STATUS "TIZEN_TOOLCHAIN_PATH set to: ${TIZEN_TOOLCHAIN_PATH}") + + include_directories(SYSTEM ${TIZEN_TOOLCHAIN_PATH}/include/c++) + include_directories(SYSTEM ${TIZEN_TOOLCHAIN_PATH}/include/c++/${TIZEN_TOOLCHAIN}) endif() if(ANDROID) @@ -272,21 +267,21 @@ endif() if(TARGET_ARCH_NAME MATCHES "^(arm|armel)$") if(TIZEN) - add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-B${TIZEN_TOOLCHAIN_PATH}") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib") - add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-L${TIZEN_TOOLCHAIN_PATH}") endif() elseif(TARGET_ARCH_NAME MATCHES "^(arm64|x64|riscv64)$") if(TIZEN) - add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-B${TIZEN_TOOLCHAIN_PATH}") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib64") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib64") - add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-L${TIZEN_TOOLCHAIN_PATH}") add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/lib64") add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64") - add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-Wl,--rpath-link=${TIZEN_TOOLCHAIN_PATH}") endif() elseif(TARGET_ARCH_NAME STREQUAL "s390x") add_toolchain_linker_flag("--target=${TOOLCHAIN}") @@ -297,10 +292,10 @@ elseif(TARGET_ARCH_NAME STREQUAL "x86") endif() add_toolchain_linker_flag(-m32) if(TIZEN) - add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-B${TIZEN_TOOLCHAIN_PATH}") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib") - add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-L${TIZEN_TOOLCHAIN_PATH}") endif() elseif(ILLUMOS) add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib/amd64") diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 index aab40de3fd9..4f0546dce12 100644 --- a/eng/common/sdk-task.ps1 +++ b/eng/common/sdk-task.ps1 @@ -64,7 +64,7 @@ try { $GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty } if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) { - $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.10.0-pre.4.0" -MemberType NoteProperty + $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.12.0" -MemberType NoteProperty } if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") { $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 22954477a57..a46b6deb759 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -320,7 +320,7 @@ function InstallDotNet([string] $dotnetRoot, $variations += @($installParameters) $dotnetBuilds = $installParameters.Clone() - $dotnetbuilds.AzureFeed = "https://dotnetbuilds.azureedge.net/public" + $dotnetbuilds.AzureFeed = "https://ci.dot.net/public" $variations += @($dotnetBuilds) if ($runtimeSourceFeed) { @@ -383,8 +383,8 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = # If the version of msbuild is going to be xcopied, # use this version. Version matches a package here: - # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.10.0-pre.4.0 - $defaultXCopyMSBuildVersion = '17.10.0-pre.4.0' + # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.12.0 + $defaultXCopyMSBuildVersion = '17.12.0' if (!$vsRequirements) { if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') { diff --git a/eng/common/tools.sh b/eng/common/tools.sh index 00473c9f918..1159726a10f 100644 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -232,7 +232,7 @@ function InstallDotNet { local public_location=("${installParameters[@]}") variations+=(public_location) - local dotnetbuilds=("${installParameters[@]}" --azure-feed "https://dotnetbuilds.azureedge.net/public") + local dotnetbuilds=("${installParameters[@]}" --azure-feed "https://ci.dot.net/public") variations+=(dotnetbuilds) if [[ -n "${6:-}" ]]; then diff --git a/global.json b/global.json index 13ae5e67e6b..baa1ab80f5a 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "tools": { - "dotnet": "9.0.100-rc.2.24474.11", + "dotnet": "9.0.100", "runtimes": { "aspnetcore": [ "$(MicrosoftAspNetCoreApp60Version)", @@ -31,7 +31,7 @@ }, "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.0", - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24516.2", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24516.2" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24623.3", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24623.3" } } From a140212949bdc106037fc1039658e5d88f7d2e4f Mon Sep 17 00:00:00 2001 From: kkeirstead <85592574+kkeirstead@users.noreply.github.com> Date: Wed, 8 Jan 2025 15:09:54 -0800 Subject: [PATCH 057/174] Remove xcopy-msbuild from global.json (#7799) --- global.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/global.json b/global.json index baa1ab80f5a..7e848733764 100644 --- a/global.json +++ b/global.json @@ -26,8 +26,7 @@ "$(MicrosoftNETCoreApp80Version)", "$(VSRedistCommonNetCoreSharedFrameworkx6490Version)" ] - }, - "xcopy-msbuild": "17.8.5" + } }, "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.0", From 174af426f8f9185d00cf7739f20103f78bda60fd Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:29:16 -0800 Subject: [PATCH 058/174] Update dependencies from https://github.com/dotnet/arcade build 20250108.5 (#7809) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24623.3 -> To Version 9.0.0-beta.25058.5 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 6 +++--- global.json | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 33e554b5674..41ae8519f2e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -22,25 +22,25 @@ https://github.com/dotnet/roslyn-analyzers 3d61c57c73c3dd5f1f407ef9cd3414d94bf0eaf2 - + https://github.com/dotnet/arcade - e0e05154656254a735ebf19ffa5a37a8b915039b + 8cc6ecd76c24ef6665579a5c5e386a211a1e7c54 - + https://github.com/dotnet/arcade - e0e05154656254a735ebf19ffa5a37a8b915039b + 8cc6ecd76c24ef6665579a5c5e386a211a1e7c54 - + https://github.com/dotnet/arcade - e0e05154656254a735ebf19ffa5a37a8b915039b + 8cc6ecd76c24ef6665579a5c5e386a211a1e7c54 - + https://github.com/dotnet/arcade - e0e05154656254a735ebf19ffa5a37a8b915039b + 8cc6ecd76c24ef6665579a5c5e386a211a1e7c54 - + https://github.com/dotnet/arcade - e0e05154656254a735ebf19ffa5a37a8b915039b + 8cc6ecd76c24ef6665579a5c5e386a211a1e7c54 https://github.com/dotnet/diagnostics diff --git a/eng/Versions.props b/eng/Versions.props index 9879dbfcba5..690d35fef11 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -48,9 +48,9 @@ --> - 9.0.0-beta.24623.3 - 9.0.0-beta.24623.3 - 9.0.0-beta.24623.3 + 9.0.0-beta.25058.5 + 9.0.0-beta.25058.5 + 9.0.0-beta.25058.5 9.0.0 9.0.0-rtm.24529.3 diff --git a/global.json b/global.json index 7e848733764..470ddaf9c46 100644 --- a/global.json +++ b/global.json @@ -30,7 +30,7 @@ }, "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.0", - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24623.3", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24623.3" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25058.5", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.25058.5" } } From fe18963096c8534d3b534c20ec4559c849c6636e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 22 Jan 2025 09:11:13 -0800 Subject: [PATCH 059/174] Update dependencies from https://github.com/dotnet/arcade build 20250115.2 (#7828) Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.25058.5 -> To Version 9.0.0-beta.25065.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 20 ++++++++++---------- eng/Versions.props | 6 +++--- eng/common/template-guidance.md | 2 +- global.json | 6 +++--- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 41ae8519f2e..12fabdb46cb 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -22,25 +22,25 @@ https://github.com/dotnet/roslyn-analyzers 3d61c57c73c3dd5f1f407ef9cd3414d94bf0eaf2 - + https://github.com/dotnet/arcade - 8cc6ecd76c24ef6665579a5c5e386a211a1e7c54 + c4bbc67763bf0c5a868862df874079380e647d61 - + https://github.com/dotnet/arcade - 8cc6ecd76c24ef6665579a5c5e386a211a1e7c54 + c4bbc67763bf0c5a868862df874079380e647d61 - + https://github.com/dotnet/arcade - 8cc6ecd76c24ef6665579a5c5e386a211a1e7c54 + c4bbc67763bf0c5a868862df874079380e647d61 - + https://github.com/dotnet/arcade - 8cc6ecd76c24ef6665579a5c5e386a211a1e7c54 + c4bbc67763bf0c5a868862df874079380e647d61 - + https://github.com/dotnet/arcade - 8cc6ecd76c24ef6665579a5c5e386a211a1e7c54 + c4bbc67763bf0c5a868862df874079380e647d61 https://github.com/dotnet/diagnostics diff --git a/eng/Versions.props b/eng/Versions.props index 690d35fef11..458343cbecc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -48,9 +48,9 @@ --> - 9.0.0-beta.25058.5 - 9.0.0-beta.25058.5 - 9.0.0-beta.25058.5 + 9.0.0-beta.25065.2 + 9.0.0-beta.25065.2 + 9.0.0-beta.25065.2 9.0.0 9.0.0-rtm.24529.3 diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md index 5ef6c30ba92..98bbc1ded0b 100644 --- a/eng/common/template-guidance.md +++ b/eng/common/template-guidance.md @@ -57,7 +57,7 @@ extends: Note: Multiple outputs are ONLY applicable to 1ES PT publishing (only usable when referencing `templates-official`). -# Development notes +## Development notes **Folder / file structure** diff --git a/global.json b/global.json index 470ddaf9c46..a9fca091c49 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "tools": { - "dotnet": "9.0.100", + "dotnet": "9.0.102", "runtimes": { "aspnetcore": [ "$(MicrosoftAspNetCoreApp60Version)", @@ -30,7 +30,7 @@ }, "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.0", - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25058.5", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.25058.5" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25065.2", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.25065.2" } } From 001ec3e11d5143a8ab1469b4567974600a0a21c4 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 27 Jan 2025 22:06:29 +0000 Subject: [PATCH 060/174] Update to .NET 10 --- NuGet.config | 1 + eng/Common.props | 2 +- eng/Versions.props | 16 +++++++++++++--- eng/common/tools.ps1 | 2 +- eng/common/tools.sh | 2 +- eng/dependabot/Versions.props | 1 + eng/dependabot/net10.0/Directory.Build.props | 5 +++++ eng/dependabot/net10.0/NuGet.config | 1 + eng/dependabot/net10.0/Packages.props | 18 ++++++++++++++++++ eng/dependabot/net10.0/Versions.props | 17 +++++++++++++++++ eng/dependabot/net10.0/dependabot.csproj | 6 ++++++ global.json | 12 ++++++++---- src/Directory.Build.targets | 8 ++++++++ .../GenerateDotNetHost.targets | 3 +++ .../TargetFrameworkMoniker.cs | 9 +++++++-- .../TestDotNetHost.cs | 2 ++ .../TestDotNetHost.cs.template | 1 + ...tics.Monitoring.Tool.FunctionalTests.csproj | 4 ++-- 18 files changed, 96 insertions(+), 14 deletions(-) create mode 100644 eng/dependabot/net10.0/Directory.Build.props create mode 120000 eng/dependabot/net10.0/NuGet.config create mode 100644 eng/dependabot/net10.0/Packages.props create mode 100644 eng/dependabot/net10.0/Versions.props create mode 100644 eng/dependabot/net10.0/dependabot.csproj diff --git a/NuGet.config b/NuGet.config index c59695f632b..a1ae90b5ff0 100644 --- a/NuGet.config +++ b/NuGet.config @@ -19,6 +19,7 @@ + diff --git a/eng/Common.props b/eng/Common.props index d52995badc9..83ba52308e5 100644 --- a/eng/Common.props +++ b/eng/Common.props @@ -1,7 +1,7 @@ - net9.0 + net10.0 $(LatestTargetFramework) $(ArtifactsDir)bundles\$(Configuration)\NonShipping\ diff --git a/eng/Versions.props b/eng/Versions.props index 458343cbecc..5dbd5de2667 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -29,7 +29,7 @@ net6.0;net7.0;net8.0;$(LatestTargetFramework) - net9.0 + net10.0 false @@ -60,7 +60,7 @@ 9.0.553101 9.0.553101 - 9.0.0-preview.24527.2 + 10.0.0-preview.25076.4 9.0.0 9.0.0-rtm.24528.9 @@ -78,6 +78,7 @@ $(MicrosoftNETCoreApp70Version) $(MicrosoftNETCoreApp80Version) $(MicrosoftAspNetCoreAppRuntimewinx64Version) + $(MicrosoftNETCoreApp100Version) @@ -103,7 +104,7 @@ $(MicrosoftExtensionsConfigurationAbstractions70Version) $(MicrosoftExtensionsLogging70Version) $(MicrosoftExtensionsLoggingAbstractions70Version) - $(MicrosoftExtensionsLoggingConsole70Version) + $(MicrosoftExte nsionsLoggingConsole70Version) $(SystemTextJson80Version) @@ -124,6 +125,15 @@ $(MicrosoftNETCoreApp90Version) $(SystemTextJson90Version) + + $(MicrosoftAspNetCoreApp100Version) + $(MicrosoftAspNetCoreApp100Version) + $(MicrosoftExtensionsConfigurationAbstractions100Version) + $(MicrosoftExtensionsLogging100Version) + $(MicrosoftExtensionsLoggingAbstractions100Version) + $(MicrosoftExtensionsLoggingConsole100Version) + $(SystemTextJson100Version) + $(MicrosoftDiagnosticsMonitoringShippedVersion) $(MicrosoftDiagnosticsMonitoringShippedVersion) diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index a46b6deb759..e4d21722752 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -606,7 +606,7 @@ function InitializeBuildTool() { # Use override if it exists - commonly set by source-build if ($null -eq $env:_OverrideArcadeInitializeBuildToolFramework) { - $initializeBuildToolFramework="net9.0" + $initializeBuildToolFramework="net10.0" } else { $initializeBuildToolFramework=$env:_OverrideArcadeInitializeBuildToolFramework } diff --git a/eng/common/tools.sh b/eng/common/tools.sh index 1159726a10f..58afa136c3c 100644 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -341,7 +341,7 @@ function InitializeBuildTool { _InitializeBuildToolCommand="msbuild" # use override if it exists - commonly set by source-build if [[ "${_OverrideArcadeInitializeBuildToolFramework:-x}" == "x" ]]; then - _InitializeBuildToolFramework="net9.0" + _InitializeBuildToolFramework="net10.0" else _InitializeBuildToolFramework="${_OverrideArcadeInitializeBuildToolFramework}" fi diff --git a/eng/dependabot/Versions.props b/eng/dependabot/Versions.props index 6bd4dac8dc1..1984e7aa15e 100644 --- a/eng/dependabot/Versions.props +++ b/eng/dependabot/Versions.props @@ -5,5 +5,6 @@ + diff --git a/eng/dependabot/net10.0/Directory.Build.props b/eng/dependabot/net10.0/Directory.Build.props new file mode 100644 index 00000000000..fe86741bd6c --- /dev/null +++ b/eng/dependabot/net10.0/Directory.Build.props @@ -0,0 +1,5 @@ + + + + + diff --git a/eng/dependabot/net10.0/NuGet.config b/eng/dependabot/net10.0/NuGet.config new file mode 120000 index 00000000000..941555881f8 --- /dev/null +++ b/eng/dependabot/net10.0/NuGet.config @@ -0,0 +1 @@ +../../../NuGet.config \ No newline at end of file diff --git a/eng/dependabot/net10.0/Packages.props b/eng/dependabot/net10.0/Packages.props new file mode 100644 index 00000000000..4b4d0b76d04 --- /dev/null +++ b/eng/dependabot/net10.0/Packages.props @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/eng/dependabot/net10.0/Versions.props b/eng/dependabot/net10.0/Versions.props new file mode 100644 index 00000000000..a230538cfbd --- /dev/null +++ b/eng/dependabot/net10.0/Versions.props @@ -0,0 +1,17 @@ + + + + + 10.0.0-alpha.1.25070.4 + + $(MicrosoftNETCoreApp100Version) + + $(MicrosoftNETCoreApp100Version) + + $(MicrosoftNETCoreApp100Version) + + $(MicrosoftNETCoreApp100Version) + + $(MicrosoftNETCoreApp100Version) + + diff --git a/eng/dependabot/net10.0/dependabot.csproj b/eng/dependabot/net10.0/dependabot.csproj new file mode 100644 index 00000000000..34fdf6e5f06 --- /dev/null +++ b/eng/dependabot/net10.0/dependabot.csproj @@ -0,0 +1,6 @@ + + + + net10.0 + + diff --git a/global.json b/global.json index a9fca091c49..9c42b9096c6 100644 --- a/global.json +++ b/global.json @@ -6,25 +6,29 @@ "$(MicrosoftAspNetCoreApp60Version)", "$(MicrosoftAspNetCoreApp70Version)", "$(MicrosoftAspNetCoreApp80Version)", - "$(VSRedistCommonAspNetCoreSharedFrameworkx6490Version)" + "$(VSRedistCommonAspNetCoreSharedFrameworkx6490Version)", + "$(MicrosoftAspNetCoreApp100Version)" ], "aspnetcore/x86": [ "$(MicrosoftAspNetCoreApp60Version)", "$(MicrosoftAspNetCoreApp70Version)", "$(MicrosoftAspNetCoreApp80Version)", - "$(VSRedistCommonAspNetCoreSharedFrameworkx6490Version)" + "$(VSRedistCommonAspNetCoreSharedFrameworkx6490Version)", + "$(MicrosoftAspNetCoreApp100Version)" ], "dotnet": [ "$(MicrosoftNETCoreApp60Version)", "$(MicrosoftNETCoreApp70Version)", "$(MicrosoftNETCoreApp80Version)", - "$(VSRedistCommonNetCoreSharedFrameworkx6490Version)" + "$(VSRedistCommonNetCoreSharedFrameworkx6490Version)", + "$(MicrosoftNETCoreApp100Version)" ], "dotnet/x86": [ "$(MicrosoftNETCoreApp60Version)", "$(MicrosoftNETCoreApp70Version)", "$(MicrosoftNETCoreApp80Version)", - "$(VSRedistCommonNetCoreSharedFrameworkx6490Version)" + "$(VSRedistCommonNetCoreSharedFrameworkx6490Version)", + "$(MicrosoftNETCoreApp100Version)" ] } }, diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index edc992f0ec6..e8fcf110ecd 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -119,6 +119,14 @@ $(MicrosoftAspNetCoreApp90Version) + + <_TestRuntimeFramework Include="@(RuntimeFramework)" Condition=" '%(Identity)' == 'Microsoft.NETCore.App' "> + $(MicrosoftNETCoreApp100Version) + + <_TestRuntimeFramework Include="@(RuntimeFramework)" Condition=" '%(Identity)' == 'Microsoft.AspNetCore.App' "> + $(MicrosoftAspNetCoreApp100Version) + + <_TestRuntimeFramework Include="@(RuntimeFramework)" Condition=" '%(Identity)' != 'Microsoft.NETCore.App' and '%(Identity)' != 'Microsoft.AspNetCore.App' " /> diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/GenerateDotNetHost.targets b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/GenerateDotNetHost.targets index 2c81c7df8ed..0b5eab3f4b4 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/GenerateDotNetHost.targets +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/GenerateDotNetHost.targets @@ -14,12 +14,14 @@ $(MicrosoftNETCoreApp70Version) $(MicrosoftNETCoreApp80Version) $(MicrosoftNETCoreApp90Version) + $(MicrosoftNETCoreApp100Version) $(MicrosoftAspNetCoreApp31Version) $(MicrosoftAspNetCoreApp50Version) $(MicrosoftAspNetCoreApp60Version) $(MicrosoftAspNetCoreApp70Version) $(MicrosoftAspNetCoreApp80Version) $(MicrosoftAspNetCoreApp90Version) + $(MicrosoftAspNetCoreApp100Version) @@ -33,6 +35,7 @@ $(TransformedContent.Replace('$MicrosoftNetCoreApp70Version$', '$(MicrosoftNETCoreApp70Version)')) $(TransformedContent.Replace('$MicrosoftNetCoreApp80Version$', '$(MicrosoftNETCoreApp80Version)')) $(TransformedContent.Replace('$MicrosoftNetCoreApp90Version$', '$(MicrosoftNETCoreApp90Version)')) + $(TransformedContent.Replace('$MicrosoftNetCoreApp100Version$', '$(MicrosoftNETCoreApp100Version)')) $(TransformedContent.Replace('$MicrosoftAspNetCoreApp31Version$', '$(MicrosoftAspNetCoreApp31Version)')) $(TransformedContent.Replace('$MicrosoftAspNetCoreApp50Version$', '$(MicrosoftAspNetCoreApp50Version)')) $(TransformedContent.Replace('$MicrosoftAspNetCoreApp60Version$', '$(MicrosoftAspNetCoreApp60Version)')) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TargetFrameworkMoniker.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TargetFrameworkMoniker.cs index d6727ced5a4..aba7120059e 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TargetFrameworkMoniker.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TargetFrameworkMoniker.cs @@ -13,7 +13,8 @@ public enum TargetFrameworkMoniker Net60, Net70, Net80, - Net90 + Net90, + Net100 } public static partial class TargetFrameworkMonikerExtensions @@ -34,6 +35,8 @@ public static string ToFolderName(this TargetFrameworkMoniker moniker) return "net8.0"; case TargetFrameworkMoniker.Net90: return "net9.0"; + case TargetFrameworkMoniker.Net100: + return "net10.0"; } throw CreateUnsupportedException(moniker); } @@ -44,7 +47,9 @@ private static ArgumentException CreateUnsupportedException(TargetFrameworkMonik } public const TargetFrameworkMoniker CurrentTargetFrameworkMoniker = -#if NET9_0 +#if NET10_0 + TargetFrameworkMoniker.Net100; +#elif NET9_0 TargetFrameworkMoniker.Net90; #elif NET8_0 TargetFrameworkMoniker.Net80; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TestDotNetHost.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TestDotNetHost.cs index 2d8fe68c07b..27c14f77b50 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TestDotNetHost.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TestDotNetHost.cs @@ -90,6 +90,8 @@ public static TargetFrameworkMoniker BuiltTargetFrameworkMoniker return TargetFrameworkMoniker.Net80; #elif NET9_0 return TargetFrameworkMoniker.Net90; +#elif NET10_0 + return TargetFrameworkMoniker.Net100; #endif } } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TestDotNetHost.cs.template b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TestDotNetHost.cs.template index cbc15afac94..eb48cf7dbb0 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TestDotNetHost.cs.template +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/TestDotNetHost.cs.template @@ -16,6 +16,7 @@ namespace Microsoft.Diagnostics.Monitoring.TestCommon public static readonly string NetCore70VersionString = "$MicrosoftNetCoreApp70Version$"; public static readonly string NetCore80VersionString = "$MicrosoftNetCoreApp80Version$"; public static readonly string NetCore90VersionString = "$MicrosoftNetCoreApp90Version$"; + public static readonly string NetCore100VersionString = "$MicrosoftNetCoreApp100Version$"; public static readonly string AspNetCore31VersionString = "$MicrosoftAspNetCoreApp31Version$"; public static readonly string AspNetCore50VersionString = "$MicrosoftAspNetCoreApp50Version$"; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj index d3212d57d1e..07fc67c6272 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj @@ -1,4 +1,4 @@ - + $(TestTargetFrameworks) @@ -92,7 +92,7 @@ false true - TargetFramework=net9.0 + TargetFramework=net10.0 From 40527c19602149121f366bce3b07e9c0e51d271b Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 29 Jan 2025 19:21:34 +0000 Subject: [PATCH 061/174] Remove ConfigureOptions --- .../ServiceCollectionExtensions.cs | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs index e28c9ce54ca..9437454b168 100644 --- a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs +++ b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Authentication; @@ -48,43 +48,43 @@ internal static class ServiceCollectionExtensions { public static IServiceCollection ConfigureCors(this IServiceCollection services, IConfiguration configuration) { - return ConfigureOptions(services, configuration, ConfigurationKeys.CorsConfiguration); + return services.Configure(configuration.GetSection(ConfigurationKeys.CorsConfiguration)); } public static IServiceCollection ConfigureDotnetMonitorDebug(this IServiceCollection services, IConfiguration configuration) { - return ConfigureOptions(services, configuration, ConfigurationKeys.DotnetMonitorDebug); + return services.Configure(configuration.GetSection(ConfigurationKeys.DotnetMonitorDebug)); } public static IServiceCollection ConfigureGlobalCounter(this IServiceCollection services, IConfiguration configuration) { - return ConfigureOptions(services, configuration, ConfigurationKeys.GlobalCounter) + return services.Configure(configuration.GetSection(ConfigurationKeys.GlobalCounter)) .AddSingleton, DataAnnotationValidateOptions>(); } public static IServiceCollection ConfigureCollectionRuleDefaults(this IServiceCollection services, IConfiguration configuration) { - return ConfigureOptions(services, configuration, ConfigurationKeys.CollectionRuleDefaults); + return services.Configure(configuration.GetSection(ConfigurationKeys.CollectionRuleDefaults)); } public static IServiceCollection ConfigureTemplates(this IServiceCollection services, IConfiguration configuration) { - return ConfigureOptions(services, configuration, ConfigurationKeys.Templates); + return services.Configure(configuration.GetSection(ConfigurationKeys.Templates)); } public static IServiceCollection ConfigureInProcessFeatures(this IServiceCollection services, IConfiguration configuration) { - ConfigureOptions(services, configuration, ConfigurationKeys.InProcessFeatures_CallStacks) + services.Configure(configuration.GetSection(ConfigurationKeys.InProcessFeatures_CallStacks)) .AddSingleton, CallStacksPostConfigureOptions>(); - ConfigureOptions(services, configuration, ConfigurationKeys.InProcessFeatures_Exceptions) + services.Configure(configuration.GetSection(ConfigurationKeys.InProcessFeatures_Exceptions)) .AddSingleton, ExceptionsPostConfigureOptions>(); - ConfigureOptions(services, configuration, ConfigurationKeys.InProcessFeatures_ParameterCapturing) - .AddSingleton, ParameterCapturingPostConfigureOptions>(); + services.Configure(configuration.GetSection(ConfigurationKeys.InProcessFeatures_ParameterCapturing)) + .AddSingleton, ParameterCapturingPostConfigureOptions>(); - ConfigureOptions(services, configuration, ConfigurationKeys.InProcessFeatures) + services.Configure(configuration.GetSection(ConfigurationKeys.InProcessFeatures)) .AddSingleton() .AddSingleton(); @@ -93,7 +93,7 @@ public static IServiceCollection ConfigureInProcessFeatures(this IServiceCollect public static IServiceCollection ConfigureMetrics(this IServiceCollection services, IConfiguration configuration) { - return ConfigureOptions(services, configuration, ConfigurationKeys.Metrics) + return services.Configure(configuration.GetSection(ConfigurationKeys.Metrics)) .AddSingleton, DataAnnotationValidateOptions>() .AddSingleton() .AddHostedService() @@ -102,7 +102,7 @@ public static IServiceCollection ConfigureMetrics(this IServiceCollection servic public static IServiceCollection ConfigureMonitorApiKeyOptions(this IServiceCollection services, IConfiguration configuration, bool allowConfigurationUpdates) { - ConfigureOptions(services, configuration, ConfigurationKeys.MonitorApiKey); + services.Configure(configuration.GetSection(ConfigurationKeys.MonitorApiKey)); // Loads and validates MonitorApiKeyOptions into MonitorApiKeyConfiguration services.AddSingleton, MonitorApiKeyPostConfigure>(); @@ -235,19 +235,14 @@ public static IServiceCollection RegisterCollectionRuleTrigger(services, configuration, ConfigurationKeys.Storage); + services.Configure(configuration.GetSection(ConfigurationKeys.Storage)); services.AddSingleton, StoragePostConfigureOptions>(); return services; } public static IServiceCollection ConfigureDefaultProcess(this IServiceCollection services, IConfiguration configuration) { - return ConfigureOptions(services, configuration, ConfigurationKeys.DefaultProcess); - } - - private static IServiceCollection ConfigureOptions(IServiceCollection services, IConfiguration configuration, string key) where T : class - { - return services.Configure(configuration.GetSection(key)); + return services.Configure(configuration.GetSection(ConfigurationKeys.DefaultProcess)); } public static IServiceCollection ConfigureExtensions(this IServiceCollection services) From 46f0b3d43027a7dff0c82b815d7eda12c0daa72d Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 28 Feb 2025 19:33:55 +0000 Subject: [PATCH 062/174] Replace AddControllers --- .../ActionContextExtensions.cs | 132 ----- .../Controllers/ControllerExtensions.cs | 36 +- .../Controllers/DiagController.Metrics.cs | 16 +- .../Controllers/DiagController.cs | 133 +---- .../Controllers/DiagnosticsControllerBase.cs | 23 +- .../Controllers/ExceptionsController.cs | 24 +- .../Controllers/MetricsController.cs | 11 +- .../Controllers/OperationsController.cs | 40 +- .../EgressValidationAttribute.cs | 90 ---- .../EgressValidationFilter.cs.cs | 118 +++++ .../HostRestrictionFilter.cs | 56 ++ .../HttpContextExtensions.cs | 121 +++++ .../OutputStreamResult.cs | 16 +- src/Tools/dotnet-monitor/Startup.cs | 497 +++++++++++++++++- 14 files changed, 863 insertions(+), 450 deletions(-) delete mode 100644 src/Microsoft.Diagnostics.Monitoring.WebApi/ActionContextExtensions.cs delete mode 100644 src/Microsoft.Diagnostics.Monitoring.WebApi/EgressValidationAttribute.cs create mode 100644 src/Microsoft.Diagnostics.Monitoring.WebApi/EgressValidationFilter.cs.cs create mode 100644 src/Microsoft.Diagnostics.Monitoring.WebApi/HostRestrictionFilter.cs diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/ActionContextExtensions.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/ActionContextExtensions.cs deleted file mode 100644 index 257a8318b86..00000000000 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/ActionContextExtensions.cs +++ /dev/null @@ -1,132 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.AspNetCore.Http.Features; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Diagnostics.NETCore.Client; -using Microsoft.Extensions.Logging; -using System; -using System.ComponentModel.DataAnnotations; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.Diagnostics.Monitoring.WebApi -{ - public sealed class ExecutionResult - { - private static readonly ExecutionResult _empty = new ExecutionResult(); - - public Exception? Exception { get; private set; } - public T? Result { get; private set; } - public ProblemDetails? ProblemDetails { get; private set; } - - private ExecutionResult() { } - - public static ExecutionResult Succeeded(T result) => new ExecutionResult { Result = result }; - - public static ExecutionResult Failed(Exception exception) => - new ExecutionResult { Exception = exception, ProblemDetails = exception.ToProblemDetails((int)HttpStatusCode.BadRequest) }; - - public static ExecutionResult Empty() => _empty; - } - - internal static class ExecutionHelper - { - public static async Task> InvokeAsync(Func>> action, ILogger logger, - CancellationToken token) - { - // Exceptions are logged in the "when" clause in order to preview the exception - // from the point of where it was thrown. This allows capturing of the log scopes - // that were active when the exception was thrown. Waiting to log during the exception - // handler will miss any scopes that were added during invocation of action. - try - { - return await action(token); - } - catch (ArgumentException ex) when (LogError(logger, ex)) - { - return ExecutionResult.Failed(ex); - } - catch (DiagnosticsClientException ex) when (LogError(logger, ex)) - { - return ExecutionResult.Failed(ex); - } - catch (InvalidOperationException ex) when (LogError(logger, ex)) - { - return ExecutionResult.Failed(ex); - } - catch (OperationCanceledException ex) when (token.IsCancellationRequested && LogInformation(logger, ex)) - { - return ExecutionResult.Failed(ex); - } - catch (OperationCanceledException ex) when (LogError(logger, ex)) - { - return ExecutionResult.Failed(ex); - } - catch (MonitoringException ex) when (LogError(logger, ex)) - { - return ExecutionResult.Failed(ex); - } - catch (ValidationException ex) when (LogError(logger, ex)) - { - return ExecutionResult.Failed(ex); - } - catch (UnauthorizedAccessException ex) when (LogError(logger, ex)) - { - return ExecutionResult.Failed(ex); - } - } - - private static bool LogError(ILogger logger, Exception ex) - { - logger.RequestFailed(ex); - return true; - } - - private static bool LogInformation(ILogger logger, Exception ex) - { - logger.RequestCanceled(); - return true; - } - } - - internal static class ActionContextExtensions - { - public static Task ProblemAsync(this ActionContext context, BadRequestObjectResult result) - { - if (context.HttpContext.Features.Get()?.HasStarted == true) - { - // If already started writing response, do not rewrite - // as this will throw an InvalidOperationException. - return Task.CompletedTask; - } - else - { - // Need to manually add this here because this ObjectResult is not processed by the filter pipeline, - // which would look up the applicable content types and apply them before executing the result. - result.ContentTypes.Add(ContentTypes.ApplicationProblemJson); - return result.ExecuteResultAsync(context); - } - } - - public static async Task InvokeAsync(this ActionContext context, Func action, ILogger logger) - { - //We want to handle two scenarios: - //1) These functions are part of an ExecuteResultAsync implementation, in which case - //they don't need to return anything. (The delegate below handles this case). - //2) They are part of deferred processing and return a result. - Func>> innerAction = async (CancellationToken token) => - { - await action(token); - return ExecutionResult.Empty(); - }; - - ExecutionResult result = await ExecutionHelper.InvokeAsync(innerAction, logger, context.HttpContext.RequestAborted); - if (result.ProblemDetails != null) - { - await context.ProblemAsync(new BadRequestObjectResult(result.ProblemDetails)); - } - } - } -} diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ControllerExtensions.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ControllerExtensions.cs index 16f207cbc2b..0a9ae6fa73d 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ControllerExtensions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ControllerExtensions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using Microsoft.Diagnostics.NETCore.Client; using Microsoft.Extensions.Logging; @@ -17,43 +18,30 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { internal static class ControllerExtensions { - public static ActionResult FeatureNotEnabled(this ControllerBase controller, string featureName) + public static ProblemHttpResult FeatureNotEnabled(this ControllerBase controller, string featureName) { - return new BadRequestObjectResult(new ProblemDetails() + return TypedResults.Problem(new ProblemDetails() { Detail = string.Format(Strings.Message_FeatureNotEnabled, featureName), Status = StatusCodes.Status400BadRequest }); } - public static ActionResult NotAcceptable(this ControllerBase controller) + public static IResult NotAcceptable(this ControllerBase controller) { - return new StatusCodeResult((int)HttpStatusCode.NotAcceptable); + return TypedResults.StatusCode((int)HttpStatusCode.NotAcceptable); } - public static ActionResult InvokeService(this ControllerBase controller, Func serviceCall, ILogger logger) + public static IResult InvokeService(this ControllerBase controller, Func serviceCall, ILogger logger) + where T : IResult { - //We can convert ActionResult to ActionResult - //and then safely convert back. - return controller.InvokeService(() => serviceCall(), logger).Result!; - } - - public static ActionResult InvokeService(this ControllerBase controller, Func> serviceCall, ILogger logger) - { - //Convert from ActionResult to Task> + //Convert from IResult to Task //and safely convert back. return controller.InvokeService(() => Task.FromResult(serviceCall()), logger).Result; } - public static async Task InvokeService(this ControllerBase controller, Func> serviceCall, ILogger logger) - { - //Task -> Task> - //Then unwrap the result back to ActionResult - ActionResult result = await controller.InvokeService(async () => await serviceCall(), logger); - return result.Result!; - } - - public static async Task> InvokeService(this ControllerBase controller, Func>> serviceCall, ILogger logger) + public static async Task InvokeService(this ControllerBase controller, Func> serviceCall, ILogger logger) + where T : IResult { CancellationToken token = controller.HttpContext.RequestAborted; // Exceptions are logged in the "when" clause in order to preview the exception @@ -98,9 +86,9 @@ public static async Task> InvokeService(this ControllerBase c } } - public static ObjectResult Problem(this ControllerBase controller, Exception ex, int statusCode = StatusCodes.Status400BadRequest) + public static ProblemHttpResult Problem(this ControllerBase controller, Exception ex, int statusCode = StatusCodes.Status400BadRequest) { - return new BadRequestObjectResult(ex.ToProblemDetails(statusCode)) { StatusCode = statusCode }; + return TypedResults.Problem(ex.ToProblemDetails(statusCode)); } private static bool LogError(ILogger logger, Exception ex) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs index 0c99f193dc8..8fd121d5a90 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs @@ -21,13 +21,7 @@ partial class DiagController /// The duration of the metrics session (in seconds). /// The egress provider to which the metrics are saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. - [HttpGet("livemetrics", Name = nameof(CaptureMetrics))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJsonSequence)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] - [EgressValidation] - public Task CaptureMetrics( + public Task CaptureMetrics( [FromQuery] int? pid = null, [FromQuery] @@ -69,13 +63,7 @@ public Task CaptureMetrics( /// The duration of the metrics session (in seconds). /// The egress provider to which the metrics are saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. - [HttpPost("livemetrics", Name = nameof(CaptureMetricsCustom))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJsonSequence)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] - [EgressValidation] - public Task CaptureMetricsCustom( + public Task CaptureMetricsCustom( [FromBody][Required] Models.EventMetricsConfiguration configuration, [FromQuery] diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs index d3b60e46165..83afaf56009 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using Microsoft.Diagnostics.Monitoring.EventPipe; using Microsoft.Diagnostics.Monitoring.Options; @@ -22,18 +22,9 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { - [Route("")] // Root - [ApiController] - [HostRestriction] - [Authorize(Policy = AuthConstants.PolicyName)] -#if NETCOREAPP3_1_OR_GREATER - [ProducesErrorResponseType(typeof(ValidationProblemDetails))] -#endif - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] public partial class DiagController : DiagnosticsControllerBase { - private const TraceProfile DefaultTraceProfiles = TraceProfile.Cpu | TraceProfile.Http | TraceProfile.Metrics | TraceProfile.GcCollect; + internal const TraceProfile DefaultTraceProfiles = TraceProfile.Cpu | TraceProfile.Http | TraceProfile.Metrics | TraceProfile.GcCollect; private readonly IOptions _diagnosticPortOptions; private readonly IOptions _callStacksOptions; @@ -70,10 +61,7 @@ public DiagController(IServiceProvider serviceProvider, ILogger /// /// Get the list of accessible processes. /// - [HttpGet("processes", Name = nameof(GetProcesses))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public Task>> GetProcesses() + public Task GetProcesses() { return this.InvokeService(async () => { @@ -108,7 +96,7 @@ public Task>> GetProcesses() }); } Logger.WrittenToHttpStream(); - return new ActionResult>(processesIdentifiers); + return TypedResults.Ok(processesIdentifiers); }, Logger); } @@ -118,10 +106,7 @@ public Task>> GetProcesses() /// Process ID used to identify the target process. /// The Runtime instance cookie used to identify the target process. /// Process name used to identify the target process. - [HttpGet("process", Name = nameof(GetProcessInfo))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(Models.ProcessInfo), StatusCodes.Status200OK)] - public Task> GetProcessInfo( + public Task GetProcessInfo( [FromQuery] int? pid = null, [FromQuery] @@ -131,7 +116,7 @@ public Task>> GetProcesses() { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); - return InvokeForProcess(processInfo => + return InvokeForProcess(processInfo => { Models.ProcessInfo processModel = new Models.ProcessInfo() { @@ -145,7 +130,7 @@ public Task>> GetProcesses() Logger.WrittenToHttpStream(); - return processModel; + return TypedResults.Ok(processModel); }, processKey); } @@ -156,10 +141,7 @@ public Task>> GetProcesses() /// Process ID used to identify the target process. /// The Runtime instance cookie used to identify the target process. /// Process name used to identify the target process. - [HttpGet("env", Name = nameof(GetProcessEnvironment))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(Dictionary), StatusCodes.Status200OK)] - public Task>> GetProcessEnvironment( + public Task GetProcessEnvironment( [FromQuery] int? pid = null, [FromQuery] @@ -169,7 +151,7 @@ public Task>> GetProcessEnvironment( { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); - return InvokeForProcess>(async processInfo => + return InvokeForProcess>>(async processInfo => { var client = new DiagnosticsClient(processInfo.EndpointInfo.Endpoint); @@ -179,7 +161,7 @@ public Task>> GetProcessEnvironment( Logger.WrittenToHttpStream(); - return environment; + return TypedResults.Ok(environment); } catch (ServerErrorException) { @@ -199,15 +181,9 @@ public Task>> GetProcessEnvironment( /// The egress provider to which the dump is saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. /// - [HttpGet("dump", Name = nameof(CaptureDump))] - [ProducesWithProblemDetails(ContentTypes.ApplicationOctetStream)] // FileResult is the closest representation of the output so that the OpenAPI document correctly // describes the result as a binary file. - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] - [EgressValidation] - public Task CaptureDump( + public Task CaptureDump( [FromQuery] int? pid = null, [FromQuery] @@ -243,15 +219,9 @@ public Task CaptureDump( /// The egress provider to which the GC dump is saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. /// - [HttpGet("gcdump", Name = nameof(CaptureGcDump))] - [ProducesWithProblemDetails(ContentTypes.ApplicationOctetStream)] // FileResult is the closest representation of the output so that the OpenAPI document correctly // describes the result as a binary file. - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] - [EgressValidation] - public Task CaptureGcDump( + public Task CaptureGcDump( [FromQuery] int? pid = null, [FromQuery] @@ -286,15 +256,9 @@ public Task CaptureGcDump( /// The duration of the trace session (in seconds). /// The egress provider to which the trace is saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. - [HttpGet("trace", Name = nameof(CaptureTrace))] - [ProducesWithProblemDetails(ContentTypes.ApplicationOctetStream)] // FileResult is the closest representation of the output so that the OpenAPI document correctly // describes the result as a binary file. - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] - [EgressValidation] - public Task CaptureTrace( + public Task CaptureTrace( [FromQuery] int? pid = null, [FromQuery] @@ -332,15 +296,9 @@ public Task CaptureTrace( /// The duration of the trace session (in seconds). /// The egress provider to which the trace is saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. - [HttpPost("trace", Name = nameof(CaptureTraceCustom))] - [ProducesWithProblemDetails(ContentTypes.ApplicationOctetStream)] // FileResult is the closest representation of the output so that the OpenAPI document correctly // describes the result as a binary file. - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] - [EgressValidation] - public Task CaptureTraceCustom( + public Task CaptureTraceCustom( [FromBody][Required] EventPipeConfiguration configuration, [FromQuery] @@ -387,13 +345,7 @@ public Task CaptureTraceCustom( /// The level of the logs to capture. /// The egress provider to which the logs are saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. - [HttpGet("logs", Name = nameof(CaptureLogs))] - [ProducesWithProblemDetails(ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] - [EgressValidation] - public Task CaptureLogs( + public Task CaptureLogs( [FromQuery] int? pid = null, [FromQuery] @@ -445,13 +397,7 @@ public Task CaptureLogs( /// The duration of the logs session (in seconds). /// The egress provider to which the logs are saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. - [HttpPost("logs", Name = nameof(CaptureLogsCustom))] - [ProducesWithProblemDetails(ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] - [EgressValidation] - public Task CaptureLogsCustom( + public Task CaptureLogsCustom( [FromBody] LogsConfiguration configuration, [FromQuery] @@ -488,10 +434,7 @@ public Task CaptureLogsCustom( /// /// Gets versioning and listening mode information about Dotnet-Monitor /// - [HttpGet("info", Name = nameof(GetInfo))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(DotnetMonitorInfo), StatusCodes.Status200OK)] - public ActionResult GetInfo() + public IResult GetInfo() { return this.InvokeService(() => { @@ -509,7 +452,7 @@ public ActionResult GetInfo() }; Logger.WrittenToHttpStream(); - return new ActionResult(dotnetMonitorInfo); + return TypedResults.Ok(dotnetMonitorInfo); }, Logger); } @@ -519,10 +462,7 @@ public ActionResult GetInfo() /// Process ID used to identify the target process. /// The Runtime instance cookie used to identify the target process. /// Process name used to identify the target process. - [HttpGet("collectionrules", Name = nameof(GetCollectionRulesDescription))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(Dictionary), StatusCodes.Status200OK)] - public Task>> GetCollectionRulesDescription( + public Task GetCollectionRulesDescription( [FromQuery] int? pid = null, [FromQuery] @@ -530,9 +470,9 @@ public Task>> GetColl [FromQuery] string? name = null) { - return InvokeForProcess>(processInfo => + return InvokeForProcess>>(processInfo => { - return _collectionRuleService.GetCollectionRulesDescriptions(processInfo.EndpointInfo); + return TypedResults.Ok(_collectionRuleService.GetCollectionRulesDescriptions(processInfo.EndpointInfo)); }, Utilities.GetProcessKey(pid, uid, name)); } @@ -544,10 +484,7 @@ public Task>> GetColl /// Process ID used to identify the target process. /// The Runtime instance cookie used to identify the target process. /// Process name used to identify the target process. - [HttpGet("collectionrules/{collectionRuleName}", Name = nameof(GetCollectionRuleDetailedDescription))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(CollectionRuleDetailedDescription), StatusCodes.Status200OK)] - public Task> GetCollectionRuleDetailedDescription( + public Task GetCollectionRuleDetailedDescription( string collectionRuleName, [FromQuery] int? pid = null, @@ -556,20 +493,14 @@ public Task>> GetColl [FromQuery] string? name = null) { - return InvokeForProcess(processInfo => + return InvokeForProcess>(processInfo => { - return _collectionRuleService.GetCollectionRuleDetailedDescription(collectionRuleName, processInfo.EndpointInfo); + return TypedResults.Ok(_collectionRuleService.GetCollectionRuleDetailedDescription(collectionRuleName, processInfo.EndpointInfo)); }, Utilities.GetProcessKey(pid, uid, name)); } - [HttpPost("parameters", Name = nameof(CaptureParameters))] - [ProducesWithProblemDetails(ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] - [EgressValidation] - public async Task CaptureParameters( + public async Task CaptureParameters( [FromBody][Required] CaptureParametersConfiguration configuration, [FromQuery][Range(-1, int.MaxValue)] @@ -609,13 +540,7 @@ public async Task CaptureParameters( }, processKey, Utilities.ArtifactType_Parameters); } - [HttpGet("stacks", Name = nameof(CaptureStacks))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson, ContentTypes.TextPlain, ContentTypes.ApplicationSpeedscopeJson)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] - [EgressValidation] - public Task CaptureStacks( + public Task CaptureStacks( [FromQuery] int? pid = null, [FromQuery] @@ -629,7 +554,7 @@ public Task CaptureStacks( { if (!_callStacksOptions.Value.GetEnabled()) { - return Task.FromResult(this.FeatureNotEnabled(Strings.FeatureName_CallStacks)); + return Task.FromResult(this.FeatureNotEnabled(Strings.FeatureName_CallStacks)); } ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -656,7 +581,7 @@ public Task CaptureStacks( return _diagnosticPortOptions.Value.EndpointName; } - private Task StartTrace( + private Task StartTrace( IProcessInfo processInfo, MonitoringSourceConfiguration configuration, TimeSpan duration, @@ -676,7 +601,7 @@ private Task StartTrace( tags); } - private Task StartLogs( + private Task StartLogs( IProcessInfo processInfo, EventLogsPipelineSettings settings, string? egressProvider, diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagnosticsControllerBase.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagnosticsControllerBase.cs index 4d7876ecb02..b392f41b7c9 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagnosticsControllerBase.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagnosticsControllerBase.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -22,27 +23,29 @@ private protected DiagnosticsControllerBase(IDiagnosticServices diagnosticServic Logger = logger ?? throw new ArgumentNullException(nameof(logger)); } - protected Task InvokeForProcess(Func func, ProcessKey? processKey, string? artifactType = null) + protected Task InvokeForProcess(Func func, ProcessKey? processKey, string? artifactType = null) { - Func> asyncFunc = + Func> asyncFunc = processInfo => Task.FromResult(func(processInfo)); return InvokeForProcess(asyncFunc, processKey, artifactType); } - protected async Task InvokeForProcess(Func> func, ProcessKey? processKey, string? artifactType) + protected async Task InvokeForProcess(Func> func, ProcessKey? processKey, string? artifactType) { - ActionResult result = await InvokeForProcess(async processInfo => await func(processInfo), processKey, artifactType); + IResult result = await InvokeForProcess(async processInfo => await func(processInfo), processKey, artifactType); - return result.Result!; + return result; } - protected Task> InvokeForProcess(Func> func, ProcessKey? processKey, string? artifactType = null) + protected Task InvokeForProcess(Func func, ProcessKey? processKey, string? artifactType = null) + where T : IResult { return InvokeForProcess(processInfo => Task.FromResult(func(processInfo)), processKey, artifactType); } - protected async Task> InvokeForProcess(Func>> func, ProcessKey? processKey, string? artifactType = null) + protected async Task InvokeForProcess(Func> func, ProcessKey? processKey, string? artifactType = null) + where T : IResult { IDisposable? artifactTypeRegistration = null; if (!string.IsNullOrEmpty(artifactType)) @@ -73,7 +76,7 @@ protected async Task> InvokeForProcess(Func Result( + protected async Task Result( string artifactType, string? providerName, IArtifactOperation operation, @@ -122,10 +125,10 @@ private async Task RegisterCurrentHttpResponseAsOperation(IProcessInfo processIn protocol: this.HttpContext.Request.Scheme, this.HttpContext.Request.Host.ToString()); } - private async Task SendToEgress(IEgressOperation egressOperation, string limitKey) + private async Task SendToEgress(IEgressOperation egressOperation, string limitKey) { string? operationUrl = await RegisterOperation(egressOperation, limitKey); - return Accepted(operationUrl); + return TypedResults.Accepted(operationUrl); } private protected IDiagnosticServices DiagnosticServices { get; } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs index 84023a6960a..1e34fce34ee 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Diagnostics.Monitoring.Options; @@ -17,12 +16,6 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { - [Route("")] - [ApiController] - [HostRestriction] - [Authorize(Policy = AuthConstants.PolicyName)] - [ProducesErrorResponseType(typeof(ValidationProblemDetails))] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public sealed class ExceptionsController : DiagnosticsControllerBase { @@ -44,12 +37,7 @@ public ExceptionsController( /// Process name used to identify the target process. /// The egress provider to which the exceptions are saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. - [HttpGet("exceptions", Name = nameof(GetExceptions))] - [ProducesWithProblemDetails(ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] - [EgressValidation] - public Task GetExceptions( + public Task GetExceptions( [FromQuery] int? pid = null, [FromQuery] @@ -63,7 +51,7 @@ public Task GetExceptions( { if (!_options.Value.GetEnabled()) { - return Task.FromResult(this.FeatureNotEnabled(Strings.FeatureName_Exceptions)); + return Task.FromResult(this.FeatureNotEnabled(Strings.FeatureName_Exceptions)); } ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -95,11 +83,7 @@ public Task GetExceptions( /// The egress provider to which the exceptions are saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. /// The exceptions configuration describing which exceptions to include in the response. - [HttpPost("exceptions", Name = nameof(CaptureExceptionsCustom))] - [ProducesWithProblemDetails(ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] - [EgressValidation] - public Task CaptureExceptionsCustom( + public Task CaptureExceptionsCustom( [FromBody] ExceptionsConfiguration configuration, [FromQuery] @@ -115,7 +99,7 @@ public Task CaptureExceptionsCustom( { if (!_options.Value.GetEnabled()) { - return Task.FromResult(NotFound()); + return Task.FromResult(TypedResults.NotFound()); } ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs index 1b14cb49b6c..ebe19f9fea5 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs @@ -10,12 +10,6 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { - [Route("")] - [ApiController] -#if NETCOREAPP3_1_OR_GREATER - [ProducesErrorResponseType(typeof(ValidationProblemDetails))] -#endif - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public class MetricsController : ControllerBase { private const string ArtifactType_Metrics = "metrics"; @@ -36,10 +30,7 @@ public MetricsController(ILogger logger, /// /// Get a list of the current backlog of metrics for a process in the Prometheus exposition format. /// - [HttpGet("metrics", Name = nameof(GetMetrics))] - [ProducesWithProblemDetails(ContentTypes.TextPlain_v0_0_4)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] - public ActionResult GetMetrics() + public IResult GetMetrics() { return this.InvokeService(() => { diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs index 9d6c9a3c570..360903654ff 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs @@ -1,21 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; -using System.Collections.Generic; namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { - [Route(ControllerName)] - [ApiController] - [HostRestriction] - [Authorize(Policy = AuthConstants.PolicyName)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] public class OperationsController : ControllerBase { private readonly ILogger _logger; @@ -36,10 +30,7 @@ public OperationsController(ILogger logger, IServiceProvid /// The Runtime instance cookie used to identify the target process. /// Process name used to identify the target process. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. - [HttpGet(Name = nameof(GetOperations))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public ActionResult> GetOperations( + public IResult GetOperations( [FromQuery] int? pid = null, [FromQuery] @@ -53,34 +44,29 @@ public OperationsController(ILogger logger, IServiceProvid return this.InvokeService(() => { - return new ActionResult>(_operationsStore.GetOperations(processKey, tags)); + return Results.Ok(_operationsStore.GetOperations(processKey, tags)); }, _logger); } - [HttpGet("{operationId}", Name = nameof(GetOperationStatus))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(Models.OperationStatus), StatusCodes.Status201Created)] - [ProducesResponseType(typeof(Models.OperationStatus), StatusCodes.Status200OK)] - public IActionResult GetOperationStatus(Guid operationId) + public IResult GetOperationStatus(Guid operationId) { return this.InvokeService(() => { Models.OperationStatus status = _operationsStore.GetOperationStatus(operationId); - int statusCode = (int)(status.Status == Models.OperationState.Succeeded ? StatusCodes.Status201Created : StatusCodes.Status200OK); - return this.StatusCode(statusCode, status); + return status.Status == Models.OperationState.Succeeded +#pragma warning disable CS8625 // Implementation accexts null, but nullable annotation was added in .NET 9 + ? TypedResults.Created((string?)null, status) +#pragma warning restore CS8625 + : Results.Ok(status); }, _logger); } - [HttpDelete("{operationId}", Name = nameof(CancelOperation))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] - public IActionResult CancelOperation( + public IResult CancelOperation( Guid operationId, [FromQuery] bool stop = false) { - return this.InvokeService(() => + return this.InvokeService>(() => { //Note that if the operation is not found, it will throw an InvalidOperationException and //return an error code. @@ -92,12 +78,12 @@ public IActionResult CancelOperation( _operationsStore.StopOperation(operationId, (ex) => _logger.StopOperationFailed(operationId, ex)); // Stop operations are not instant, they are instead queued and can take an indeterminate amount of time. - return Accepted(); + return TypedResults.Accepted((string?)null); } else { _operationsStore.CancelOperation(operationId); - return Ok(); + return TypedResults.Ok(); } }, _logger); } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/EgressValidationAttribute.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/EgressValidationAttribute.cs deleted file mode 100644 index 0a760e418f6..00000000000 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/EgressValidationAttribute.cs +++ /dev/null @@ -1,90 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Filters; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Primitives; -using System; - -namespace Microsoft.Diagnostics.Monitoring.WebApi -{ - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)] - public sealed class EgressValidationAttribute : ActionFilterAttribute, IFilterFactory - { - public bool IsReusable => true; - - IFilterMetadata IFilterFactory.CreateInstance(IServiceProvider serviceProvider) - { - var egressOutputConfiguration = serviceProvider.GetRequiredService(); - - EgressValidationActionFilter actionFilter = new EgressValidationActionFilter(egressOutputConfiguration); - - return actionFilter; - } - } - - [AttributeUsage(AttributeTargets.Class)] - internal class EgressValidationUnhandledExceptionFilter : ActionFilterAttribute, IExceptionFilter - { - private readonly ILogger _logger; - - public EgressValidationUnhandledExceptionFilter(ILogger logger) - { - _logger = logger; - } - - public void OnException(ExceptionContext context) - { - if (context.Exception is EgressValidationActionFilter.EgressDisabledException egressException) - { - context.Result = new BadRequestObjectResult(egressException.ToProblemDetails(StatusCodes.Status400BadRequest)); - - _logger.LogError(egressException.Message); - } - } - } - - internal class EgressValidationActionFilter : IActionFilter - { - private readonly IEgressOutputConfiguration _egressOutputConfiguration; - private const string EgressQuery = "egressprovider"; - - public EgressValidationActionFilter(IEgressOutputConfiguration egressOutputConfiguration) - { - _egressOutputConfiguration = egressOutputConfiguration; - } - - public void OnActionExecuted(ActionExecutedContext context) - { - } - - public void OnActionExecuting(ActionExecutingContext context) - { - StringValues value; - - bool egressProviderGiven = context.HttpContext.Request.Query.TryGetValue(EgressQuery, out value); - - if (!egressProviderGiven || StringValues.IsNullOrEmpty(value)) - { - if (!_egressOutputConfiguration.IsHttpEgressEnabled) - { - throw new EgressDisabledException(); - } - } - } - - public class EgressDisabledException : Exception - { - public override string Message - { - get - { - return Strings.ErrorMessage_HttpEgressDisabled; - } - } - } - } -} diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/EgressValidationFilter.cs.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/EgressValidationFilter.cs.cs new file mode 100644 index 00000000000..e82c52aee1e --- /dev/null +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/EgressValidationFilter.cs.cs @@ -0,0 +1,118 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Primitives; +using System; +using System.Threading.Tasks; + +namespace Microsoft.Diagnostics.Monitoring.WebApi +{ + public class EgressValidationFilter : IEndpointFilter + { + private readonly IEgressOutputConfiguration _egressOutputConfiguration; + private const string EgressQuery = "egressprovider"; + + public EgressValidationFilter(IEgressOutputConfiguration egressOutputConfiguration) + { + _egressOutputConfiguration = egressOutputConfiguration; + } + + public async ValueTask InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) + { + var httpContext = context.HttpContext; + if (!httpContext.Request.Query.TryGetValue(EgressQuery, out StringValues value) || StringValues.IsNullOrEmpty(value)) + { + if (!_egressOutputConfiguration.IsHttpEgressEnabled) + { + var logger = httpContext.RequestServices.GetRequiredService>(); + var exception = new EgressDisabledException(); + logger.LogError(exception.Message); + return Results.BadRequest(new ProblemDetails + { + Status = StatusCodes.Status400BadRequest, + Title = "Egress Disabled", + Detail = exception.Message + }); + } + } + + return await next(context); + } + + public class EgressDisabledException : Exception + { + public override string Message => "HTTP egress is disabled."; // Use appropriate error message + } + } + + public class EgressValidationUnhandledExceptionMiddleware + { + private readonly RequestDelegate _next; + private readonly ILogger _logger; + + public EgressValidationUnhandledExceptionMiddleware(RequestDelegate next, ILogger logger) + { + _next = next; + _logger = logger; + } + + public async Task InvokeAsync(HttpContext context) + { + try + { + await _next(context); + } + catch (EgressValidationExtensions.EgressDisabledException egressException) + { + var problemDetails = egressException.ToProblemDetails(StatusCodes.Status400BadRequest); + context.Response.StatusCode = StatusCodes.Status400BadRequest; + context.Response.ContentType = ContentTypes.ApplicationProblemJson; + await context.Response.WriteAsJsonAsync(problemDetails); + + _logger.LogError(egressException.Message); + } + } + } + + public static class EgressValidationExtensions + { + private const string EgressQuery = "egressprovider"; + + public static RouteHandlerBuilder RequireEgressValidation(this RouteHandlerBuilder builder) + { + return builder.AddEndpointFilter(async (context, next) => + { + var services = context.HttpContext.RequestServices; // Resolve per request + var egressOutputConfiguration = services.GetRequiredService(); + + StringValues value; + bool egressProviderGiven = context.HttpContext.Request.Query.TryGetValue(EgressQuery, out value); + + if (!egressProviderGiven || StringValues.IsNullOrEmpty(value)) + { + if (!egressOutputConfiguration.IsHttpEgressEnabled) + { + throw new EgressDisabledException(); + } + } + return await next(context); + }); + } + + public class EgressDisabledException : Exception + { + public override string Message + { + get + { + return Strings.ErrorMessage_HttpEgressDisabled; + } + } + } + } +} diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/HostRestrictionFilter.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/HostRestrictionFilter.cs new file mode 100644 index 00000000000..ff1b900d948 --- /dev/null +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/HostRestrictionFilter.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using System.Threading.Tasks; +using System; +using System.Linq; + +namespace Microsoft.Diagnostics.Monitoring.WebApi +{ + public class HostRestrictionFilter : IEndpointFilter + { + private readonly int[] _restrictedPorts; + + public HostRestrictionFilter(int[] restrictedPorts) + { + _restrictedPorts = restrictedPorts; + } + + public async ValueTask InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) + { + var httpContext = context.HttpContext; + var requestPort = httpContext.Request.Host.Port; + + if (requestPort.HasValue && _restrictedPorts.Contains(requestPort.Value)) + { + return Results.Forbid(); + } + + return await next(context); + } + } + + public static class HostRestrictionExtensions + { + public static RouteHandlerBuilder RequireHostRestriction(this RouteHandlerBuilder builder) + { + return builder.AddEndpointFilter(async (context, next) => + { + var services = context.HttpContext.RequestServices; // Resolve per request + var metricsPortsProvider = services.GetRequiredService(); + var restrictedPorts = metricsPortsProvider.MetricsPorts.ToArray(); // Fresh instance per request + + var requestPort = context.HttpContext.Request.Host.Port; + if (requestPort.HasValue && restrictedPorts.Contains(requestPort.Value)) + { + return Results.Forbid(); // 403 Forbidden - Access restricted + } + + return await next(context); + }); + } + } +} diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/HttpContextExtensions.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/HttpContextExtensions.cs index 4b2c31bcc41..b5718e56fc8 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/HttpContextExtensions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/HttpContextExtensions.cs @@ -2,8 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Diagnostics.NETCore.Client; +using Microsoft.Extensions.Logging; +using System; +using System.ComponentModel.DataAnnotations; using System.Diagnostics; +using System.Net; +using System.Threading; +using System.Threading.Tasks; namespace Microsoft.Diagnostics.Monitoring.WebApi { @@ -21,5 +30,117 @@ public static void AllowSynchronousIO(this HttpContext httpContext) syncIOFeature.AllowSynchronousIO = true; } } + public static Task ProblemAsync(this HttpContext context, ProblemHttpResult result) + { + if (context.Features.Get()?.HasStarted == true) + { + // If already started writing response, do not rewrite + // as this will throw an InvalidOperationException. + return Task.CompletedTask; + } + else + { + // Need to manually add this here because this ObjectResult is not processed by the filter pipeline, + // which would look up the applicable content types and apply them before executing the result. + context.Response.ContentType = ContentTypes.ApplicationProblemJson; + return result.ExecuteAsync(context); + } + } + + public static async Task InvokeAsync(this HttpContext context, Func action, ILogger logger) + { + //We want to handle two scenarios: + //1) These functions are part of an ExecuteResultAsync implementation, in which case + //they don't need to return anything. (The delegate below handles this case). + //2) They are part of deferred processing and return a result. + Func>> innerAction = async (CancellationToken token) => + { + await action(token); + return ExecutionResult.Empty(); + }; + + ExecutionResult result = await ExecutionHelper.InvokeAsync(innerAction, logger, context.RequestAborted); + if (result.ProblemDetails != null) + { + await context.ProblemAsync(TypedResults.Problem(result.ProblemDetails)); + } + } + } + + public sealed class ExecutionResult + { + private static readonly ExecutionResult _empty = new ExecutionResult(); + + public Exception? Exception { get; private set; } + public T? Result { get; private set; } + public ProblemDetails? ProblemDetails { get; private set; } + + private ExecutionResult() { } + + public static ExecutionResult Succeeded(T result) => new ExecutionResult { Result = result }; + + public static ExecutionResult Failed(Exception exception) => + new ExecutionResult { Exception = exception, ProblemDetails = exception.ToProblemDetails((int)HttpStatusCode.BadRequest) }; + + public static ExecutionResult Empty() => _empty; + } + internal static class ExecutionHelper + { + public static async Task> InvokeAsync(Func>> action, ILogger logger, + CancellationToken token) + { + // Exceptions are logged in the "when" clause in order to preview the exception + // from the point of where it was thrown. This allows capturing of the log scopes + // that were active when the exception was thrown. Waiting to log during the exception + // handler will miss any scopes that were added during invocation of action. + try + { + return await action(token); + } + catch (ArgumentException ex) when (LogError(logger, ex)) + { + return ExecutionResult.Failed(ex); + } + catch (DiagnosticsClientException ex) when (LogError(logger, ex)) + { + return ExecutionResult.Failed(ex); + } + catch (InvalidOperationException ex) when (LogError(logger, ex)) + { + return ExecutionResult.Failed(ex); + } + catch (OperationCanceledException ex) when (token.IsCancellationRequested && LogInformation(logger, ex)) + { + return ExecutionResult.Failed(ex); + } + catch (OperationCanceledException ex) when (LogError(logger, ex)) + { + return ExecutionResult.Failed(ex); + } + catch (MonitoringException ex) when (LogError(logger, ex)) + { + return ExecutionResult.Failed(ex); + } + catch (ValidationException ex) when (LogError(logger, ex)) + { + return ExecutionResult.Failed(ex); + } + catch (UnauthorizedAccessException ex) when (LogError(logger, ex)) + { + return ExecutionResult.Failed(ex); + } + } + + private static bool LogError(ILogger logger, Exception ex) + { + logger.RequestFailed(ex); + return true; + } + + private static bool LogInformation(ILogger logger, Exception ex) + { + logger.RequestCanceled(); + return true; + } } } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/OutputStreamResult.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/OutputStreamResult.cs index 7cb0ad242c2..3c9c4c34521 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/OutputStreamResult.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/OutputStreamResult.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; @@ -12,7 +12,7 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi { - internal sealed class OutputStreamResult : ActionResult + internal sealed class OutputStreamResult : IResult { private readonly Func _action; private readonly string _contentType; @@ -32,9 +32,9 @@ public OutputStreamResult(IArtifactOperation operation, string? fileDownloadName { } - public override async Task ExecuteResultAsync(ActionContext context) + public async Task ExecuteAsync(HttpContext context) { - ILogger logger = context.HttpContext.RequestServices + ILogger logger = context.RequestServices .GetRequiredService() .CreateLogger(); @@ -46,13 +46,13 @@ await context.InvokeAsync(async (token) => { ContentDispositionHeaderValue contentDispositionHeaderValue = new ContentDispositionHeaderValue("attachment"); contentDispositionHeaderValue.FileName = _fileDownloadName; - context.HttpContext.Response.Headers["Content-Disposition"] = contentDispositionHeaderValue.ToString(); + context.Response.Headers["Content-Disposition"] = contentDispositionHeaderValue.ToString(); } - context.HttpContext.Response.Headers["Content-Type"] = _contentType; + context.Response.Headers["Content-Type"] = _contentType; - context.HttpContext.Features.Get()?.DisableBuffering(); + context.Features.Get()?.DisableBuffering(); - await _action(context.HttpContext.Response.Body, token); + await _action(context.Response.Body, token); logger.WrittenToHttpStream(); }, logger); diff --git a/src/Tools/dotnet-monitor/Startup.cs b/src/Tools/dotnet-monitor/Startup.cs index 9253658b750..1a08cfc6c00 100644 --- a/src/Tools/dotnet-monitor/Startup.cs +++ b/src/Tools/dotnet-monitor/Startup.cs @@ -6,15 +6,20 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.ResponseCompression; +using Microsoft.Diagnostics.Monitoring.Options; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Controllers; +using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Tools.Monitor.Swagger; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Swashbuckle.AspNetCore.Swagger; +using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.IO; using System.IO.Compression; using System.Text.Json.Serialization; @@ -34,17 +39,8 @@ public Startup(IConfiguration configuration) public void ConfigureServices(IServiceCollection services) { // AddControllers is sufficient because the tool does not use Razor nor Views. - services.AddControllers() - .AddJsonOptions(options => - { - // Allow serialization of enum values into strings rather than numbers. - options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); - }) - .AddApplicationPart(typeof(DiagController).Assembly); - - services.AddControllers(options => - { - options.Filters.Add(typeof(EgressValidationUnhandledExceptionFilter)); + services.ConfigureHttpJsonOptions(options => { + options.SerializerOptions.Converters.Add(new JsonStringEnumConverter()); }); services.Configure(options => @@ -104,12 +100,491 @@ public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, I { builder.MapControllers(); + var serviceProvider = builder.ServiceProvider; + + // OperationsController: + { + var logger = serviceProvider.GetRequiredService>(); + var operationsController = new OperationsController(logger, serviceProvider); + + // GetOperations + builder.MapGet($"{OperationsController.ControllerName}/{nameof(OperationsController.GetOperations)}", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + string? tags) => + operationsController.GetOperations(pid, uid, name, tags)) + .WithName(nameof(OperationsController.GetOperations)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status401Unauthorized) + .Produces>(StatusCodes.Status200OK); + + // GetOperationStatus + builder.MapGet($"{OperationsController.ControllerName}/{nameof(OperationsController.GetOperationStatus)}/{{operationId}}", ( + Guid operationId) => + operationsController.GetOperationStatus(operationId)) + .WithName(nameof(OperationsController.GetOperationStatus)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status201Created); + + // CancelOperation + builder.MapDelete($"{OperationsController.ControllerName}/{nameof(OperationsController.CancelOperation)}/{{operationId}}", ( + Guid operationId) => + operationsController.CancelOperation(operationId)) + .WithName(nameof(OperationsController.CancelOperation)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status202Accepted); + } + + var diagLogger = serviceProvider.GetRequiredService>(); + var diagController = new DiagController(serviceProvider, diagLogger); + + // DiagController + { + // GetProcesses + builder.MapGet("processes", () => diagController.GetProcesses()) + .WithName(nameof(DiagController.GetProcesses)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces>(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // GetProcessInfo + builder.MapGet("process", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name) => + diagController.GetProcessInfo(pid, uid, name)) + .WithName(nameof(DiagController.GetProcessInfo)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // GetProcessEnvironment + builder.MapGet("env", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name) => + diagController.GetProcessEnvironment(pid, uid, name)) + .WithName(nameof(DiagController.GetProcessEnvironment)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces>(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // CaptureDump + builder.MapGet("dump", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + DumpType type = DumpType.WithHeap, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + diagController.CaptureDump(pid, uid, name, type, egressProvider, tags)) + .WithName(nameof(DiagController.CaptureDump)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CapturGcDump + builder.MapGet("gcdump", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + string? egressProvider, + [FromQuery] + string? tags) => + diagController.CaptureGcDump(pid, uid, name, egressProvider, tags)) + .WithName(nameof(DiagController.CaptureGcDump)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureTrace + builder.MapGet("trace", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + TraceProfile profile = DiagController.DefaultTraceProfiles, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + diagController.CaptureTrace(pid, uid, name, profile, durationSeconds, egressProvider, tags)) + .WithName(nameof(DiagController.CaptureTrace)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureTraceCustom + builder.MapGet("trace", ( + [FromBody][Required] + EventPipeConfiguration configuration, + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + diagController.CaptureTraceCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + .WithName(nameof(DiagController.CaptureTraceCustom)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureLogs + builder.MapGet("logs", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + LogLevel? level = null, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + diagController.CaptureLogs(pid, uid, name, durationSeconds, level, egressProvider, tags)) + .WithName(nameof(DiagController.CaptureLogs)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureLogsCustom + builder.MapPost("logs", ( + [FromBody] + LogsConfiguration configuration, + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + diagController.CaptureLogsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + .WithName(nameof(DiagController.CaptureLogs)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // GetInfo + builder.MapGet("info", () => diagController.GetInfo()) + .WithName(nameof(DiagController.GetInfo)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // GetCollectionRulesDescription + builder.MapGet("collectionrules", ( + [FromQuery] + int pid, + [FromQuery] + Guid uid, + [FromQuery] + string name) => + diagController.GetCollectionRulesDescription(pid, uid, name)) + .WithName(nameof(DiagController.GetCollectionRulesDescription)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces>(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // GetCollectionRuleDetailedDescription + builder.MapGet("collectionrules/{collectionRuleName}", ( + string collectionRuleName, + [FromQuery] + int pid, + [FromQuery] + Guid uid, + [FromQuery] + string name) => + diagController.GetCollectionRuleDetailedDescription(collectionRuleName, pid, uid, name)) + .WithName(nameof(DiagController.GetCollectionRuleDetailedDescription)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // CaptureParameters + builder.MapPost("parameters", ( + [FromBody][Required] + CaptureParametersConfiguration configuration, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + int? pid = null, + [FromQuery] + Guid? uid = null, + [FromQuery] + string? name = null, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + diagController.CaptureParameters(configuration, durationSeconds, pid, uid, name, egressProvider, tags)) + .WithName(nameof(DiagController.CaptureParameters)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureStacks + builder.MapGet("stacks", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + string? egressProvider, + [FromQuery] + string? tags) => + diagController.CaptureStacks(pid, uid, name, egressProvider, tags)) + .WithName(nameof(DiagController.CaptureStacks)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJson, ContentTypes.TextPlain, ContentTypes.ApplicationSpeedscopeJson) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + } + + // DiagController.Metrics + { + // CaptureMetrics + builder.MapGet("livemetrics", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + diagController.CaptureMetrics(pid, uid, name, durationSeconds, egressProvider, tags)) + .WithName(nameof(DiagController.CaptureMetrics)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJsonSequence) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + builder.MapGet("livemetrics", ( + [FromBody][Required] + Monitoring.WebApi.Models.EventMetricsConfiguration configuration, + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + diagController.CaptureMetricsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + .WithName(nameof(DiagController.CaptureMetricsCustom)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJsonSequence) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + } + + // ExceptionsController + { + var logger = serviceProvider.GetRequiredService>(); + var exceptionsController = new ExceptionsController(serviceProvider, logger); + + // GetExceptions + builder.MapGet("exceptions", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + exceptionsController.GetExceptions(pid, uid, name, egressProvider, tags)) + .WithName(nameof(ExceptionsController.GetExceptions)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureExceptionsCustom + builder.MapPost("exceptions", ( + [FromBody] + ExceptionsConfiguration configuration, + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + exceptionsController.CaptureExceptionsCustom(configuration, pid, uid, name, egressProvider, tags)) + .WithName(nameof(ExceptionsController.CaptureExceptionsCustom)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + } + + // MetricsController + { + var logger = serviceProvider.GetRequiredService>(); + var metricsOptions = serviceProvider.GetRequiredService>(); + var metricsController = new MetricsController(logger, serviceProvider, metricsOptions); + + // GetMetrics + builder.MapGet("metrics", () => metricsController.GetMetrics()) + .WithName(nameof(MetricsController.GetMetrics)) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status200OK, ContentTypes.TextPlain_v0_0_4) + .ProducesProblem(StatusCodes.Status400BadRequest); + } + builder.MapGet("/", (HttpResponse response, ISwaggerProvider provider) => { using Stream stream = response.BodyWriter.AsStream(true); provider.WriteTo(stream); }); + + app.UseMiddleware(); }); } } From 42cf7815bb6688a52a0a26e48f8bd686fc242615 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 28 Feb 2025 19:59:06 +0000 Subject: [PATCH 063/174] Move mapping to controller classes --- .../Controllers/DiagController.Metrics.cs | 59 +++ .../Controllers/DiagController.cs | 310 +++++++++++ .../Controllers/ExceptionsController.cs | 52 ++ .../Controllers/MetricsController.cs | 14 + .../Controllers/OperationsController.cs | 48 ++ src/Tools/dotnet-monitor/Startup.cs | 484 +----------------- 6 files changed, 492 insertions(+), 475 deletions(-) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs index 8fd121d5a90..a63f76987ce 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Routing; using Microsoft.Diagnostics.Monitoring.EventPipe; using System; using System.ComponentModel.DataAnnotations; @@ -12,6 +14,63 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { partial class DiagController { + public DiagController MapMetricsActionMethods(IEndpointRouteBuilder builder) + { + builder.MapGet("livemetrics", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + CaptureMetrics(pid, uid, name, durationSeconds, egressProvider, tags)) + .WithName(nameof(CaptureMetrics)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJsonSequence) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + builder.MapGet("livemetrics", ( + [FromBody][Required] + Monitoring.WebApi.Models.EventMetricsConfiguration configuration, + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + CaptureMetricsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + .WithName(nameof(CaptureMetricsCustom)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJsonSequence) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + return this; + } + /// /// Capture metrics for a process. /// diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs index 83afaf56009..09d068d5646 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs @@ -1,9 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Routing; using Microsoft.Diagnostics.Monitoring.EventPipe; using Microsoft.Diagnostics.Monitoring.Options; using Microsoft.Diagnostics.Monitoring.WebApi.Models; @@ -58,6 +60,314 @@ public DiagController(IServiceProvider serviceProvider, ILogger _stacksOperationFactory = serviceProvider.GetRequiredService(); } + public DiagController MapActionMethods(IEndpointRouteBuilder builder) + { + // GetProcesses + builder.MapGet("processes", () => this.GetProcesses()) + .WithName(nameof(GetProcesses)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces>(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // GetProcessInfo + builder.MapGet("process", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name) => + GetProcessInfo(pid, uid, name)) + .WithName(nameof(GetProcessInfo)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // GetProcessEnvironment + builder.MapGet("env", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name) => + GetProcessEnvironment(pid, uid, name)) + .WithName(nameof(GetProcessEnvironment)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces>(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // CaptureDump + builder.MapGet("dump", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + Models.DumpType type = Models.DumpType.WithHeap, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + CaptureDump(pid, uid, name, type, egressProvider, tags)) + .WithName(nameof(CaptureDump)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CapturGcDump + builder.MapGet("gcdump", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + string? egressProvider, + [FromQuery] + string? tags) => + CaptureGcDump(pid, uid, name, egressProvider, tags)) + .WithName(nameof(CaptureGcDump)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureTrace + builder.MapGet("trace", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + TraceProfile profile = DefaultTraceProfiles, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + CaptureTrace(pid, uid, name, profile, durationSeconds, egressProvider, tags)) + .WithName(nameof(CaptureTrace)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureTraceCustom + builder.MapGet("trace", ( + [FromBody][Required] + EventPipeConfiguration configuration, + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + CaptureTraceCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + .WithName(nameof(CaptureTraceCustom)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureLogs + builder.MapGet("logs", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + LogLevel? level = null, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + CaptureLogs(pid, uid, name, durationSeconds, level, egressProvider, tags)) + .WithName(nameof(CaptureLogs)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureLogsCustom + builder.MapPost("logs", ( + [FromBody] + LogsConfiguration configuration, + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + CaptureLogsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + .WithName(nameof(CaptureLogs)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // GetInfo + builder.MapGet("info", () => GetInfo()) + .WithName(nameof(GetInfo)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // GetCollectionRulesDescription + builder.MapGet("collectionrules", ( + [FromQuery] + int pid, + [FromQuery] + Guid uid, + [FromQuery] + string name) => + GetCollectionRulesDescription(pid, uid, name)) + .WithName(nameof(GetCollectionRulesDescription)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces>(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // GetCollectionRuleDetailedDescription + builder.MapGet("collectionrules/{collectionRuleName}", ( + string collectionRuleName, + [FromQuery] + int pid, + [FromQuery] + Guid uid, + [FromQuery] + string name) => + GetCollectionRuleDetailedDescription(collectionRuleName, pid, uid, name)) + .WithName(nameof(GetCollectionRuleDetailedDescription)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // CaptureParameters + builder.MapPost("parameters", ( + [FromBody][Required] + CaptureParametersConfiguration configuration, + [FromQuery][Range(-1, int.MaxValue)] + int durationSeconds = 30, + [FromQuery] + int? pid = null, + [FromQuery] + Guid? uid = null, + [FromQuery] + string? name = null, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + CaptureParameters(configuration, durationSeconds, pid, uid, name, egressProvider, tags)) + .WithName(nameof(CaptureParameters)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureStacks + builder.MapGet("stacks", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + string? egressProvider, + [FromQuery] + string? tags) => + CaptureStacks(pid, uid, name, egressProvider, tags)) + .WithName(nameof(CaptureStacks)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJson, ContentTypes.TextPlain, ContentTypes.ApplicationSpeedscopeJson) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + return this; + } + /// /// Get the list of accessible processes. /// diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs index 1e34fce34ee..b9b6e8eec9c 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Routing; using Microsoft.Diagnostics.Monitoring.Options; using Microsoft.Diagnostics.Monitoring.WebApi.Exceptions; using Microsoft.Extensions.DependencyInjection; @@ -29,6 +31,56 @@ public ExceptionsController( _options = serviceProvider.GetRequiredService>(); } + public ExceptionsController MapActionMethods(IEndpointRouteBuilder builder) + { + // GetExceptions + builder.MapGet("exceptions", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + GetExceptions(pid, uid, name, egressProvider, tags)) + .WithName(nameof(GetExceptions)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureExceptionsCustom + builder.MapPost("exceptions", ( + [FromBody] + ExceptionsConfiguration configuration, + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + string? egressProvider = null, + [FromQuery] + string? tags = null) => + CaptureExceptionsCustom(configuration, pid, uid, name, egressProvider, tags)) + .WithName(nameof(CaptureExceptionsCustom)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + return this; + } + /// /// Gets the exceptions from the target process. /// diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs index ebe19f9fea5..6aecf9c68ca 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs @@ -1,8 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -27,6 +29,18 @@ public MetricsController(ILogger logger, _metricsOptions = metricsOptions.Value; } + public MetricsController MapActionMethods(IEndpointRouteBuilder builder) + { + // GetMetrics + builder.MapGet("metrics", () => GetMetrics()) + .WithName(nameof(GetMetrics)) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .Produces(StatusCodes.Status200OK, ContentTypes.TextPlain_v0_0_4) + .ProducesProblem(StatusCodes.Status400BadRequest); + + return this; + } + /// /// Get a list of the current backlog of metrics for a process in the Prometheus exposition format. /// diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs index 360903654ff..292047ca8bb 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs @@ -1,12 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Routing; +using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; +using System.Collections.Generic; namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { @@ -23,6 +27,50 @@ public OperationsController(ILogger logger, IServiceProvid _operationsStore = serviceProvider.GetRequiredService(); } + public OperationsController MapActionMethods(IEndpointRouteBuilder builder) + { + // GetOperations + builder.MapGet($"{ControllerName}/{nameof(GetOperations)}", ( + [FromQuery] + int? pid, + [FromQuery] + Guid? uid, + [FromQuery] + string? name, + [FromQuery] + string? tags) => + GetOperations(pid, uid, name, tags)) + .WithName(nameof(GetOperations)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status401Unauthorized) + .Produces>(StatusCodes.Status200OK); + + // GetOperationStatus + builder.MapGet($"{ControllerName}/{nameof(GetOperationStatus)}/{{operationId}}", ( + Guid operationId) => + GetOperationStatus(operationId)) + .WithName(nameof(GetOperationStatus)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status201Created); + + // CancelOperation + builder.MapDelete($"{ControllerName}/{nameof(CancelOperation)}/{{operationId}}", ( + Guid operationId) => + CancelOperation(operationId)) + .WithName(nameof(CancelOperation)) + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status202Accepted); + + return this; + } + /// /// Gets the operations list for the specified process (or all processes if left unspecified). /// diff --git a/src/Tools/dotnet-monitor/Startup.cs b/src/Tools/dotnet-monitor/Startup.cs index 1a08cfc6c00..e8b4fe9161e 100644 --- a/src/Tools/dotnet-monitor/Startup.cs +++ b/src/Tools/dotnet-monitor/Startup.cs @@ -6,10 +6,8 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.ResponseCompression; -using Microsoft.Diagnostics.Monitoring.Options; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Controllers; -using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Tools.Monitor.Swagger; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -17,9 +15,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Swashbuckle.AspNetCore.Swagger; -using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; using System.IO; using System.IO.Compression; using System.Text.Json.Serialization; @@ -102,480 +98,18 @@ public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, I var serviceProvider = builder.ServiceProvider; - // OperationsController: - { - var logger = serviceProvider.GetRequiredService>(); - var operationsController = new OperationsController(logger, serviceProvider); - - // GetOperations - builder.MapGet($"{OperationsController.ControllerName}/{nameof(OperationsController.GetOperations)}", ( - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name, - [FromQuery] - string? tags) => - operationsController.GetOperations(pid, uid, name, tags)) - .WithName(nameof(OperationsController.GetOperations)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status401Unauthorized) - .Produces>(StatusCodes.Status200OK); - - // GetOperationStatus - builder.MapGet($"{OperationsController.ControllerName}/{nameof(OperationsController.GetOperationStatus)}/{{operationId}}", ( - Guid operationId) => - operationsController.GetOperationStatus(operationId)) - .WithName(nameof(OperationsController.GetOperationStatus)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status201Created); - - // CancelOperation - builder.MapDelete($"{OperationsController.ControllerName}/{nameof(OperationsController.CancelOperation)}/{{operationId}}", ( - Guid operationId) => - operationsController.CancelOperation(operationId)) - .WithName(nameof(OperationsController.CancelOperation)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status202Accepted); - } - - var diagLogger = serviceProvider.GetRequiredService>(); - var diagController = new DiagController(serviceProvider, diagLogger); - - // DiagController - { - // GetProcesses - builder.MapGet("processes", () => diagController.GetProcesses()) - .WithName(nameof(DiagController.GetProcesses)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces>(StatusCodes.Status200OK) - .ProducesProblem(StatusCodes.Status400BadRequest); - - // GetProcessInfo - builder.MapGet("process", ( - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name) => - diagController.GetProcessInfo(pid, uid, name)) - .WithName(nameof(DiagController.GetProcessInfo)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status200OK) - .ProducesProblem(StatusCodes.Status400BadRequest); - - // GetProcessEnvironment - builder.MapGet("env", ( - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name) => - diagController.GetProcessEnvironment(pid, uid, name)) - .WithName(nameof(DiagController.GetProcessEnvironment)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces>(StatusCodes.Status200OK) - .ProducesProblem(StatusCodes.Status400BadRequest); - - // CaptureDump - builder.MapGet("dump", ( - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name, - [FromQuery] - DumpType type = DumpType.WithHeap, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) => - diagController.CaptureDump(pid, uid, name, type, egressProvider, tags)) - .WithName(nameof(DiagController.CaptureDump)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status429TooManyRequests) - .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) - .Produces(StatusCodes.Status202Accepted) - .ProducesProblem(StatusCodes.Status400BadRequest) - .RequireEgressValidation(); - - // CapturGcDump - builder.MapGet("gcdump", ( - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name, - [FromQuery] - string? egressProvider, - [FromQuery] - string? tags) => - diagController.CaptureGcDump(pid, uid, name, egressProvider, tags)) - .WithName(nameof(DiagController.CaptureGcDump)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status429TooManyRequests) - .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) - .Produces(StatusCodes.Status202Accepted) - .ProducesProblem(StatusCodes.Status400BadRequest) - .RequireEgressValidation(); - - // CaptureTrace - builder.MapGet("trace", ( - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name, - [FromQuery] - TraceProfile profile = DiagController.DefaultTraceProfiles, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) => - diagController.CaptureTrace(pid, uid, name, profile, durationSeconds, egressProvider, tags)) - .WithName(nameof(DiagController.CaptureTrace)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status429TooManyRequests) - .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) - .Produces(StatusCodes.Status202Accepted) - .ProducesProblem(StatusCodes.Status400BadRequest) - .RequireEgressValidation(); - - // CaptureTraceCustom - builder.MapGet("trace", ( - [FromBody][Required] - EventPipeConfiguration configuration, - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) => - diagController.CaptureTraceCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) - .WithName(nameof(DiagController.CaptureTraceCustom)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status429TooManyRequests) - .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) - .Produces(StatusCodes.Status202Accepted) - .ProducesProblem(StatusCodes.Status400BadRequest) - .RequireEgressValidation(); + new OperationsController(serviceProvider.GetRequiredService>(), serviceProvider) + .MapActionMethods(builder); - // CaptureLogs - builder.MapGet("logs", ( - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - LogLevel? level = null, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) => - diagController.CaptureLogs(pid, uid, name, durationSeconds, level, egressProvider, tags)) - .WithName(nameof(DiagController.CaptureLogs)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status429TooManyRequests) - .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) - .Produces(StatusCodes.Status202Accepted) - .ProducesProblem(StatusCodes.Status400BadRequest) - .RequireEgressValidation(); + new DiagController(serviceProvider, serviceProvider.GetRequiredService>()) + .MapActionMethods(builder) + .MapMetricsActionMethods(builder); - // CaptureLogsCustom - builder.MapPost("logs", ( - [FromBody] - LogsConfiguration configuration, - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) => - diagController.CaptureLogsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) - .WithName(nameof(DiagController.CaptureLogs)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status429TooManyRequests) - .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) - .Produces(StatusCodes.Status202Accepted) - .ProducesProblem(StatusCodes.Status400BadRequest) - .RequireEgressValidation(); - - // GetInfo - builder.MapGet("info", () => diagController.GetInfo()) - .WithName(nameof(DiagController.GetInfo)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status200OK) - .ProducesProblem(StatusCodes.Status400BadRequest); - - // GetCollectionRulesDescription - builder.MapGet("collectionrules", ( - [FromQuery] - int pid, - [FromQuery] - Guid uid, - [FromQuery] - string name) => - diagController.GetCollectionRulesDescription(pid, uid, name)) - .WithName(nameof(DiagController.GetCollectionRulesDescription)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces>(StatusCodes.Status200OK) - .ProducesProblem(StatusCodes.Status400BadRequest); - - // GetCollectionRuleDetailedDescription - builder.MapGet("collectionrules/{collectionRuleName}", ( - string collectionRuleName, - [FromQuery] - int pid, - [FromQuery] - Guid uid, - [FromQuery] - string name) => - diagController.GetCollectionRuleDetailedDescription(collectionRuleName, pid, uid, name)) - .WithName(nameof(DiagController.GetCollectionRuleDetailedDescription)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status200OK) - .ProducesProblem(StatusCodes.Status400BadRequest); - - // CaptureParameters - builder.MapPost("parameters", ( - [FromBody][Required] - CaptureParametersConfiguration configuration, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) => - diagController.CaptureParameters(configuration, durationSeconds, pid, uid, name, egressProvider, tags)) - .WithName(nameof(DiagController.CaptureParameters)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status429TooManyRequests) - .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) - .Produces(StatusCodes.Status202Accepted) - .ProducesProblem(StatusCodes.Status400BadRequest) - .RequireEgressValidation(); - - // CaptureStacks - builder.MapGet("stacks", ( - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name, - [FromQuery] - string? egressProvider, - [FromQuery] - string? tags) => - diagController.CaptureStacks(pid, uid, name, egressProvider, tags)) - .WithName(nameof(DiagController.CaptureStacks)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status429TooManyRequests) - .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJson, ContentTypes.TextPlain, ContentTypes.ApplicationSpeedscopeJson) - .Produces(StatusCodes.Status202Accepted) - .ProducesProblem(StatusCodes.Status400BadRequest) - .RequireEgressValidation(); - } - - // DiagController.Metrics - { - // CaptureMetrics - builder.MapGet("livemetrics", ( - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) => - diagController.CaptureMetrics(pid, uid, name, durationSeconds, egressProvider, tags)) - .WithName(nameof(DiagController.CaptureMetrics)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status429TooManyRequests) - .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJsonSequence) - .Produces(StatusCodes.Status202Accepted) - .ProducesProblem(StatusCodes.Status400BadRequest) - .RequireEgressValidation(); - - builder.MapGet("livemetrics", ( - [FromBody][Required] - Monitoring.WebApi.Models.EventMetricsConfiguration configuration, - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) => - diagController.CaptureMetricsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) - .WithName(nameof(DiagController.CaptureMetricsCustom)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status429TooManyRequests) - .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJsonSequence) - .Produces(StatusCodes.Status202Accepted) - .ProducesProblem(StatusCodes.Status400BadRequest) - .RequireEgressValidation(); - } - - // ExceptionsController - { - var logger = serviceProvider.GetRequiredService>(); - var exceptionsController = new ExceptionsController(serviceProvider, logger); - - // GetExceptions - builder.MapGet("exceptions", ( - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) => - exceptionsController.GetExceptions(pid, uid, name, egressProvider, tags)) - .WithName(nameof(ExceptionsController.GetExceptions)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) - .Produces(StatusCodes.Status202Accepted) - .ProducesProblem(StatusCodes.Status400BadRequest) - .RequireEgressValidation(); - - // CaptureExceptionsCustom - builder.MapPost("exceptions", ( - [FromBody] - ExceptionsConfiguration configuration, - [FromQuery] - int? pid, - [FromQuery] - Guid? uid, - [FromQuery] - string? name, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) => - exceptionsController.CaptureExceptionsCustom(configuration, pid, uid, name, egressProvider, tags)) - .WithName(nameof(ExceptionsController.CaptureExceptionsCustom)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) - .ProducesProblem(StatusCodes.Status400BadRequest) - .RequireEgressValidation(); - } - - // MetricsController - { - var logger = serviceProvider.GetRequiredService>(); - var metricsOptions = serviceProvider.GetRequiredService>(); - var metricsController = new MetricsController(logger, serviceProvider, metricsOptions); + new ExceptionsController(serviceProvider, serviceProvider.GetRequiredService>()) + .MapActionMethods(builder); - // GetMetrics - builder.MapGet("metrics", () => metricsController.GetMetrics()) - .WithName(nameof(MetricsController.GetMetrics)) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status200OK, ContentTypes.TextPlain_v0_0_4) - .ProducesProblem(StatusCodes.Status400BadRequest); - } + new MetricsController(serviceProvider.GetRequiredService>(), serviceProvider, serviceProvider.GetRequiredService>()) + .MapActionMethods(builder); builder.MapGet("/", (HttpResponse response, ISwaggerProvider provider) => { From ded4be3ff5b3d9d6c6655e723b2e4619beb91919 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 28 Feb 2025 20:11:07 +0000 Subject: [PATCH 064/174] Remove attributes/defaults from action methods --- .../Controllers/DiagController.Metrics.cs | 39 ++-- .../Controllers/DiagController.cs | 183 ++++++------------ .../Controllers/ExceptionsController.cs | 31 +-- .../Controllers/OperationsController.cs | 21 +- 4 files changed, 92 insertions(+), 182 deletions(-) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs index a63f76987ce..b3258378c13 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs @@ -43,7 +43,7 @@ public DiagController MapMetricsActionMethods(IEndpointRouteBuilder builder) builder.MapGet("livemetrics", ( [FromBody][Required] - Monitoring.WebApi.Models.EventMetricsConfiguration configuration, + Models.EventMetricsConfiguration configuration, [FromQuery] int? pid, [FromQuery] @@ -81,18 +81,12 @@ public DiagController MapMetricsActionMethods(IEndpointRouteBuilder builder) /// The egress provider to which the metrics are saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. public Task CaptureMetrics( - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) + int? pid, + Guid? uid, + string? name, + int durationSeconds, + string? egressProvider, + string? tags) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -123,20 +117,13 @@ public Task CaptureMetrics( /// The egress provider to which the metrics are saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. public Task CaptureMetricsCustom( - [FromBody][Required] Models.EventMetricsConfiguration configuration, - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) + int? pid, + Guid? uid, + string? name, + int durationSeconds, + string? egressProvider, + string? tags) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs index 09d068d5646..a651a3d18cf 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs @@ -417,12 +417,9 @@ public Task GetProcesses() /// The Runtime instance cookie used to identify the target process. /// Process name used to identify the target process. public Task GetProcessInfo( - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null) + int? pid, + Guid? uid, + string? name) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -452,12 +449,9 @@ public Task GetProcessInfo( /// The Runtime instance cookie used to identify the target process. /// Process name used to identify the target process. public Task GetProcessEnvironment( - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null) + int? pid, + Guid? uid, + string? name) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -494,18 +488,12 @@ public Task GetProcessEnvironment( // FileResult is the closest representation of the output so that the OpenAPI document correctly // describes the result as a binary file. public Task CaptureDump( - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery] - Models.DumpType type = Models.DumpType.WithHeap, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) + int? pid, + Guid? uid, + string? name, + Models.DumpType type, + string? egressProvider, + string? tags) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -532,16 +520,11 @@ public Task CaptureDump( // FileResult is the closest representation of the output so that the OpenAPI document correctly // describes the result as a binary file. public Task CaptureGcDump( - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) + int? pid, + Guid? uid, + string? name, + string? egressProvider, + string? tags) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -569,20 +552,13 @@ public Task CaptureGcDump( // FileResult is the closest representation of the output so that the OpenAPI document correctly // describes the result as a binary file. public Task CaptureTrace( - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery] - TraceProfile profile = DefaultTraceProfiles, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) + int? pid, + Guid? uid, + string? name, + TraceProfile profile, + int durationSeconds, + string? egressProvider, + string? tags) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -609,20 +585,13 @@ public Task CaptureTrace( // FileResult is the closest representation of the output so that the OpenAPI document correctly // describes the result as a binary file. public Task CaptureTraceCustom( - [FromBody][Required] EventPipeConfiguration configuration, - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) + int? pid, + Guid? uid, + string? name, + int durationSeconds, + string? egressProvider, + string? tags) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -656,20 +625,13 @@ public Task CaptureTraceCustom( /// The egress provider to which the logs are saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. public Task CaptureLogs( - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - LogLevel? level = null, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) + int? pid, + Guid? uid, + string? name, + int durationSeconds, + LogLevel? level, + string? egressProvider, + string? tags) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -708,20 +670,13 @@ public Task CaptureLogs( /// The egress provider to which the logs are saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. public Task CaptureLogsCustom( - [FromBody] LogsConfiguration configuration, - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) + int? pid, + Guid? uid, + string? name, + int durationSeconds, + string? egressProvider, + string? tags) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -773,12 +728,9 @@ public IResult GetInfo() /// The Runtime instance cookie used to identify the target process. /// Process name used to identify the target process. public Task GetCollectionRulesDescription( - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null) + int? pid, + Guid? uid, + string? name) { return InvokeForProcess>>(processInfo => { @@ -796,12 +748,9 @@ public Task GetCollectionRulesDescription( /// Process name used to identify the target process. public Task GetCollectionRuleDetailedDescription( string collectionRuleName, - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null) + int? pid, + Guid? uid, + string? name) { return InvokeForProcess>(processInfo => { @@ -811,20 +760,13 @@ public Task GetCollectionRuleDetailedDescription( } public async Task CaptureParameters( - [FromBody][Required] CaptureParametersConfiguration configuration, - [FromQuery][Range(-1, int.MaxValue)] - int durationSeconds = 30, - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) + int durationSeconds, + int? pid, + Guid? uid, + string? name, + string? egressProvider, + string? tags) { if (!_parameterCapturingOptions.Value.GetEnabled()) { @@ -851,16 +793,11 @@ public async Task CaptureParameters( } public Task CaptureStacks( - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) + int? pid, + Guid? uid, + string? name, + string? egressProvider, + string? tags) { if (!_callStacksOptions.Value.GetEnabled()) { diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs index b9b6e8eec9c..64b2ca0efed 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs @@ -90,16 +90,11 @@ public ExceptionsController MapActionMethods(IEndpointRouteBuilder builder) /// The egress provider to which the exceptions are saved. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. public Task GetExceptions( - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) + int? pid, + Guid? uid, + string? name, + string? egressProvider, + string? tags) { if (!_options.Value.GetEnabled()) { @@ -136,18 +131,12 @@ public Task GetExceptions( /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. /// The exceptions configuration describing which exceptions to include in the response. public Task CaptureExceptionsCustom( - [FromBody] ExceptionsConfiguration configuration, - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery] - string? egressProvider = null, - [FromQuery] - string? tags = null) + int? pid, + Guid? uid, + string? name, + string? egressProvider, + string? tags) { if (!_options.Value.GetEnabled()) { diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs index 292047ca8bb..b69bc0f5dce 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs @@ -59,8 +59,10 @@ public OperationsController MapActionMethods(IEndpointRouteBuilder builder) // CancelOperation builder.MapDelete($"{ControllerName}/{nameof(CancelOperation)}/{{operationId}}", ( - Guid operationId) => - CancelOperation(operationId)) + Guid operationId, + [FromQuery] + bool stop = false) => + CancelOperation(operationId, stop)) .WithName(nameof(CancelOperation)) .RequireHostRestriction() .RequireAuthorization(AuthConstants.PolicyName) @@ -79,14 +81,10 @@ public OperationsController MapActionMethods(IEndpointRouteBuilder builder) /// Process name used to identify the target process. /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. public IResult GetOperations( - [FromQuery] - int? pid = null, - [FromQuery] - Guid? uid = null, - [FromQuery] - string? name = null, - [FromQuery] - string? tags = null) + int? pid, + Guid? uid, + string? name, + string? tags) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -111,8 +109,7 @@ public IResult GetOperationStatus(Guid operationId) public IResult CancelOperation( Guid operationId, - [FromQuery] - bool stop = false) + bool stop) { return this.InvokeService>(() => { From ad18d4041539bd6b98f6a9484e426e0e08317eac Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 28 Feb 2025 20:29:08 +0000 Subject: [PATCH 065/174] Remove unnecessary FromQuery --- .../Controllers/DiagController.Metrics.cs | 16 ++--- .../Controllers/DiagController.cs | 67 ++----------------- .../Controllers/ExceptionsController.cs | 10 --- .../Controllers/OperationsController.cs | 5 -- 4 files changed, 10 insertions(+), 88 deletions(-) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs index b3258378c13..fc68d41d66a 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs @@ -16,18 +16,14 @@ partial class DiagController { public DiagController MapMetricsActionMethods(IEndpointRouteBuilder builder) { + // CaptureMetrics builder.MapGet("livemetrics", ( - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name, - [FromQuery][Range(-1, int.MaxValue)] + [Range(-1, int.MaxValue)] int durationSeconds = 30, - [FromQuery] string? egressProvider = null, - [FromQuery] string? tags = null) => CaptureMetrics(pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureMetrics)) @@ -41,20 +37,16 @@ public DiagController MapMetricsActionMethods(IEndpointRouteBuilder builder) .ProducesProblem(StatusCodes.Status400BadRequest) .RequireEgressValidation(); + // CaptureMetricsCustom builder.MapGet("livemetrics", ( [FromBody][Required] Models.EventMetricsConfiguration configuration, - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name, - [FromQuery][Range(-1, int.MaxValue)] + [Range(-1, int.MaxValue)] int durationSeconds = 30, - [FromQuery] string? egressProvider = null, - [FromQuery] string? tags = null) => CaptureMetricsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureMetricsCustom)) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs index a651a3d18cf..e73d3b29bf4 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs @@ -26,7 +26,7 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { public partial class DiagController : DiagnosticsControllerBase { - internal const TraceProfile DefaultTraceProfiles = TraceProfile.Cpu | TraceProfile.Http | TraceProfile.Metrics | TraceProfile.GcCollect; + private const TraceProfile DefaultTraceProfiles = TraceProfile.Cpu | TraceProfile.Http | TraceProfile.Metrics | TraceProfile.GcCollect; private readonly IOptions _diagnosticPortOptions; private readonly IOptions _callStacksOptions; @@ -74,11 +74,8 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // GetProcessInfo builder.MapGet("process", ( - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name) => GetProcessInfo(pid, uid, name)) .WithName(nameof(GetProcessInfo)) @@ -91,11 +88,8 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // GetProcessEnvironment builder.MapGet("env", ( - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name) => GetProcessEnvironment(pid, uid, name)) .WithName(nameof(GetProcessEnvironment)) @@ -108,17 +102,11 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CaptureDump builder.MapGet("dump", ( - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name, - [FromQuery] Models.DumpType type = Models.DumpType.WithHeap, - [FromQuery] string? egressProvider = null, - [FromQuery] string? tags = null) => CaptureDump(pid, uid, name, type, egressProvider, tags)) .WithName(nameof(CaptureDump)) @@ -134,15 +122,10 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CapturGcDump builder.MapGet("gcdump", ( - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name, - [FromQuery] string? egressProvider, - [FromQuery] string? tags) => CaptureGcDump(pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureGcDump)) @@ -158,19 +141,13 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CaptureTrace builder.MapGet("trace", ( - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name, - [FromQuery] TraceProfile profile = DefaultTraceProfiles, - [FromQuery][Range(-1, int.MaxValue)] + [Range(-1, int.MaxValue)] int durationSeconds = 30, - [FromQuery] string? egressProvider = null, - [FromQuery] string? tags = null) => CaptureTrace(pid, uid, name, profile, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureTrace)) @@ -188,17 +165,12 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) builder.MapGet("trace", ( [FromBody][Required] EventPipeConfiguration configuration, - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name, - [FromQuery][Range(-1, int.MaxValue)] + [Range(-1, int.MaxValue)] int durationSeconds = 30, - [FromQuery] string? egressProvider = null, - [FromQuery] string? tags = null) => CaptureTraceCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureTraceCustom)) @@ -214,19 +186,13 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CaptureLogs builder.MapGet("logs", ( - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name, - [FromQuery][Range(-1, int.MaxValue)] + [Range(-1, int.MaxValue)] int durationSeconds = 30, - [FromQuery] LogLevel? level = null, - [FromQuery] string? egressProvider = null, - [FromQuery] string? tags = null) => CaptureLogs(pid, uid, name, durationSeconds, level, egressProvider, tags)) .WithName(nameof(CaptureLogs)) @@ -244,17 +210,12 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) builder.MapPost("logs", ( [FromBody] LogsConfiguration configuration, - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name, - [FromQuery][Range(-1, int.MaxValue)] + [Range(-1, int.MaxValue)] int durationSeconds = 30, - [FromQuery] string? egressProvider = null, - [FromQuery] string? tags = null) => CaptureLogsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureLogs)) @@ -280,11 +241,8 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // GetCollectionRulesDescription builder.MapGet("collectionrules", ( - [FromQuery] int pid, - [FromQuery] Guid uid, - [FromQuery] string name) => GetCollectionRulesDescription(pid, uid, name)) .WithName(nameof(GetCollectionRulesDescription)) @@ -298,11 +256,8 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // GetCollectionRuleDetailedDescription builder.MapGet("collectionrules/{collectionRuleName}", ( string collectionRuleName, - [FromQuery] int pid, - [FromQuery] Guid uid, - [FromQuery] string name) => GetCollectionRuleDetailedDescription(collectionRuleName, pid, uid, name)) .WithName(nameof(GetCollectionRuleDetailedDescription)) @@ -317,17 +272,12 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) builder.MapPost("parameters", ( [FromBody][Required] CaptureParametersConfiguration configuration, - [FromQuery][Range(-1, int.MaxValue)] + [Range(-1, int.MaxValue)] int durationSeconds = 30, - [FromQuery] int? pid = null, - [FromQuery] Guid? uid = null, - [FromQuery] string? name = null, - [FromQuery] string? egressProvider = null, - [FromQuery] string? tags = null) => CaptureParameters(configuration, durationSeconds, pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureParameters)) @@ -343,15 +293,10 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CaptureStacks builder.MapGet("stacks", ( - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name, - [FromQuery] string? egressProvider, - [FromQuery] string? tags) => CaptureStacks(pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureStacks)) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs index 64b2ca0efed..3224234175b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs @@ -35,15 +35,10 @@ public ExceptionsController MapActionMethods(IEndpointRouteBuilder builder) { // GetExceptions builder.MapGet("exceptions", ( - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name, - [FromQuery] string? egressProvider = null, - [FromQuery] string? tags = null) => GetExceptions(pid, uid, name, egressProvider, tags)) .WithName(nameof(GetExceptions)) @@ -59,15 +54,10 @@ public ExceptionsController MapActionMethods(IEndpointRouteBuilder builder) builder.MapPost("exceptions", ( [FromBody] ExceptionsConfiguration configuration, - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name, - [FromQuery] string? egressProvider = null, - [FromQuery] string? tags = null) => CaptureExceptionsCustom(configuration, pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureExceptionsCustom)) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs index b69bc0f5dce..e32a6e2f6cd 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs @@ -31,13 +31,9 @@ public OperationsController MapActionMethods(IEndpointRouteBuilder builder) { // GetOperations builder.MapGet($"{ControllerName}/{nameof(GetOperations)}", ( - [FromQuery] int? pid, - [FromQuery] Guid? uid, - [FromQuery] string? name, - [FromQuery] string? tags) => GetOperations(pid, uid, name, tags)) .WithName(nameof(GetOperations)) @@ -60,7 +56,6 @@ public OperationsController MapActionMethods(IEndpointRouteBuilder builder) // CancelOperation builder.MapDelete($"{ControllerName}/{nameof(CancelOperation)}/{{operationId}}", ( Guid operationId, - [FromQuery] bool stop = false) => CancelOperation(operationId, stop)) .WithName(nameof(CancelOperation)) From 5ba727f029927865b21b32c9b64c388dfb981456 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 28 Feb 2025 20:34:09 +0000 Subject: [PATCH 066/174] Fix warning --- .../Controllers/DiagController.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs index e73d3b29bf4..6919132271f 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs @@ -26,7 +26,9 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { public partial class DiagController : DiagnosticsControllerBase { +#pragma warning disable CA1823 // Avoid unused field warning since this is used as default parameter of lambda private const TraceProfile DefaultTraceProfiles = TraceProfile.Cpu | TraceProfile.Http | TraceProfile.Metrics | TraceProfile.GcCollect; +#pragma warning restore CA1823 private readonly IOptions _diagnosticPortOptions; private readonly IOptions _callStacksOptions; From d670d95bba5a4a44ccef020c432c13670c761d60 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 28 Feb 2025 23:06:55 +0000 Subject: [PATCH 067/174] Factor out common builder calls --- .../Controllers/DiagController.Metrics.cs | 10 +-- .../Controllers/DiagController.cs | 82 ++++++------------- .../Controllers/ExceptionsController.cs | 19 +++-- .../Controllers/OperationsController.cs | 23 ++++-- 4 files changed, 55 insertions(+), 79 deletions(-) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs index fc68d41d66a..9f2c2769fea 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs @@ -27,10 +27,7 @@ public DiagController MapMetricsActionMethods(IEndpointRouteBuilder builder) string? tags = null) => CaptureMetrics(pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureMetrics)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJsonSequence) .Produces(StatusCodes.Status202Accepted) @@ -50,10 +47,7 @@ public DiagController MapMetricsActionMethods(IEndpointRouteBuilder builder) string? tags = null) => CaptureMetricsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureMetricsCustom)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJsonSequence) .Produces(StatusCodes.Status202Accepted) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs index 6919132271f..d6c104a04c4 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs @@ -24,6 +24,18 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { + static partial class RouteHandlerBuilderExtensions + { + public static RouteHandlerBuilder RequireDiagControllerCommon(this RouteHandlerBuilder builder) + { + return builder + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson); + } + } + public partial class DiagController : DiagnosticsControllerBase { #pragma warning disable CA1823 // Avoid unused field warning since this is used as default parameter of lambda @@ -67,10 +79,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // GetProcesses builder.MapGet("processes", () => this.GetProcesses()) .WithName(nameof(GetProcesses)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces>(StatusCodes.Status200OK) .ProducesProblem(StatusCodes.Status400BadRequest); @@ -81,10 +90,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string? name) => GetProcessInfo(pid, uid, name)) .WithName(nameof(GetProcessInfo)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status200OK) .ProducesProblem(StatusCodes.Status400BadRequest); @@ -95,10 +101,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string? name) => GetProcessEnvironment(pid, uid, name)) .WithName(nameof(GetProcessEnvironment)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces>(StatusCodes.Status200OK) .ProducesProblem(StatusCodes.Status400BadRequest); @@ -112,10 +115,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string? tags = null) => CaptureDump(pid, uid, name, type, egressProvider, tags)) .WithName(nameof(CaptureDump)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) .Produces(StatusCodes.Status202Accepted) @@ -131,10 +131,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string? tags) => CaptureGcDump(pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureGcDump)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) .Produces(StatusCodes.Status202Accepted) @@ -153,10 +150,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string? tags = null) => CaptureTrace(pid, uid, name, profile, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureTrace)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) .Produces(StatusCodes.Status202Accepted) @@ -176,10 +170,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string? tags = null) => CaptureTraceCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureTraceCustom)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) .Produces(StatusCodes.Status202Accepted) @@ -198,10 +189,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string? tags = null) => CaptureLogs(pid, uid, name, durationSeconds, level, egressProvider, tags)) .WithName(nameof(CaptureLogs)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) .Produces(StatusCodes.Status202Accepted) @@ -221,10 +209,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string? tags = null) => CaptureLogsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureLogs)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) .Produces(StatusCodes.Status202Accepted) @@ -234,10 +219,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // GetInfo builder.MapGet("info", () => GetInfo()) .WithName(nameof(GetInfo)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status200OK) .ProducesProblem(StatusCodes.Status400BadRequest); @@ -248,10 +230,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string name) => GetCollectionRulesDescription(pid, uid, name)) .WithName(nameof(GetCollectionRulesDescription)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces>(StatusCodes.Status200OK) .ProducesProblem(StatusCodes.Status400BadRequest); @@ -263,10 +242,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string name) => GetCollectionRuleDetailedDescription(collectionRuleName, pid, uid, name)) .WithName(nameof(GetCollectionRuleDetailedDescription)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status200OK) .ProducesProblem(StatusCodes.Status400BadRequest); @@ -283,10 +259,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string? tags = null) => CaptureParameters(configuration, durationSeconds, pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureParameters)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) .Produces(StatusCodes.Status202Accepted) @@ -302,10 +275,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string? tags) => CaptureStacks(pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureStacks)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) - .Produces(StatusCodes.Status401Unauthorized) + .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJson, ContentTypes.TextPlain, ContentTypes.ApplicationSpeedscopeJson) .Produces(StatusCodes.Status202Accepted) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs index 3224234175b..1fd7c87e667 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs @@ -18,6 +18,17 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { + static partial class RouteHandlerBuilderExtensions + { + public static RouteHandlerBuilder RequireExceptionsControllerCommon(this RouteHandlerBuilder builder) + { + return builder + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson); + } + } + public sealed class ExceptionsController : DiagnosticsControllerBase { @@ -42,9 +53,7 @@ public ExceptionsController MapActionMethods(IEndpointRouteBuilder builder) string? tags = null) => GetExceptions(pid, uid, name, egressProvider, tags)) .WithName(nameof(GetExceptions)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .RequireExceptionsControllerCommon() .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) .Produces(StatusCodes.Status202Accepted) .ProducesProblem(StatusCodes.Status400BadRequest) @@ -61,9 +70,7 @@ public ExceptionsController MapActionMethods(IEndpointRouteBuilder builder) string? tags = null) => CaptureExceptionsCustom(configuration, pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureExceptionsCustom)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .RequireExceptionsControllerCommon() .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) .ProducesProblem(StatusCodes.Status400BadRequest) .RequireEgressValidation(); diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs index e32a6e2f6cd..adccd16c450 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs @@ -14,6 +14,17 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { + static partial class RouteHandlerBuilderExtensions + { + public static RouteHandlerBuilder RequireOperationsControllerCommon(this RouteHandlerBuilder builder) + { + return builder + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status401Unauthorized); + } + } + public class OperationsController : ControllerBase { private readonly ILogger _logger; @@ -37,9 +48,7 @@ public OperationsController MapActionMethods(IEndpointRouteBuilder builder) string? tags) => GetOperations(pid, uid, name, tags)) .WithName(nameof(GetOperations)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status401Unauthorized) + .RequireOperationsControllerCommon() .Produces>(StatusCodes.Status200OK); // GetOperationStatus @@ -47,9 +56,7 @@ public OperationsController MapActionMethods(IEndpointRouteBuilder builder) Guid operationId) => GetOperationStatus(operationId)) .WithName(nameof(GetOperationStatus)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status401Unauthorized) + .RequireOperationsControllerCommon() .Produces(StatusCodes.Status200OK) .Produces(StatusCodes.Status201Created); @@ -59,9 +66,7 @@ public OperationsController MapActionMethods(IEndpointRouteBuilder builder) bool stop = false) => CancelOperation(operationId, stop)) .WithName(nameof(CancelOperation)) - .RequireHostRestriction() - .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status401Unauthorized) + .RequireOperationsControllerCommon() .Produces(StatusCodes.Status200OK) .Produces(StatusCodes.Status202Accepted); From 3d83389636bda56a2a873bcb2e24c1ef24ece452 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 3 Mar 2025 17:35:36 +0000 Subject: [PATCH 068/174] Remove net6.0 target --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index e8b6c13f5c2..fc4985ce1b7 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -27,7 +27,7 @@ $(LatestTargetFramework) - net6.0;net7.0;net8.0;$(LatestTargetFramework) + net7.0;net8.0;$(LatestTargetFramework) net9.0 From 4a300120ad8e051d5ed056236fa509d9d64a5f3d Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 5 Mar 2025 19:33:32 +0000 Subject: [PATCH 069/174] Create controllers in route handlers The services they depend on should be retrieved per request, not when mapping the route handlers. Retrieving them early causes issues for OpenApi generation, where the mock web host needs to be configured before these services are available. --- .../Controllers/DiagController.Metrics.cs | 13 ++-- .../Controllers/DiagController.cs | 62 ++++++++++++++----- .../Controllers/ExceptionsController.cs | 12 ++-- .../Controllers/MetricsController.cs | 10 +-- .../Controllers/OperationsController.cs | 16 +++-- src/Tools/dotnet-monitor/Startup.cs | 17 ++--- 6 files changed, 81 insertions(+), 49 deletions(-) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs index 9f2c2769fea..3ac36d36b23 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.Diagnostics.Monitoring.EventPipe; +using Microsoft.Extensions.Logging; using System; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; @@ -14,10 +15,12 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { partial class DiagController { - public DiagController MapMetricsActionMethods(IEndpointRouteBuilder builder) + public static void MapMetricsActionMethods(IEndpointRouteBuilder builder) { // CaptureMetrics builder.MapGet("livemetrics", ( + IServiceProvider serviceProvider, + ILogger logger, int? pid, Guid? uid, string? name, @@ -25,7 +28,7 @@ public DiagController MapMetricsActionMethods(IEndpointRouteBuilder builder) int durationSeconds = 30, string? egressProvider = null, string? tags = null) => - CaptureMetrics(pid, uid, name, durationSeconds, egressProvider, tags)) + new DiagController(serviceProvider, logger).CaptureMetrics(pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureMetrics)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -36,6 +39,8 @@ public DiagController MapMetricsActionMethods(IEndpointRouteBuilder builder) // CaptureMetricsCustom builder.MapGet("livemetrics", ( + IServiceProvider serviceProvider, + ILogger logger, [FromBody][Required] Models.EventMetricsConfiguration configuration, int? pid, @@ -45,7 +50,7 @@ public DiagController MapMetricsActionMethods(IEndpointRouteBuilder builder) int durationSeconds = 30, string? egressProvider = null, string? tags = null) => - CaptureMetricsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + new DiagController(serviceProvider, logger).CaptureMetricsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureMetricsCustom)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -53,8 +58,6 @@ public DiagController MapMetricsActionMethods(IEndpointRouteBuilder builder) .Produces(StatusCodes.Status202Accepted) .ProducesProblem(StatusCodes.Status400BadRequest) .RequireEgressValidation(); - - return this; } /// diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs index d6c104a04c4..f895d2acd2b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs @@ -74,10 +74,13 @@ public DiagController(IServiceProvider serviceProvider, ILogger _stacksOperationFactory = serviceProvider.GetRequiredService(); } - public DiagController MapActionMethods(IEndpointRouteBuilder builder) + public static void MapActionMethods(IEndpointRouteBuilder builder) { // GetProcesses - builder.MapGet("processes", () => this.GetProcesses()) + builder.MapGet("processes", ( + IServiceProvider serviceProvider, + ILogger logger) => + new DiagController(serviceProvider, logger).GetProcesses()) .WithName(nameof(GetProcesses)) .RequireDiagControllerCommon() .Produces>(StatusCodes.Status200OK) @@ -85,10 +88,12 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // GetProcessInfo builder.MapGet("process", ( + IServiceProvider serviceProvider, + ILogger logger, int? pid, Guid? uid, string? name) => - GetProcessInfo(pid, uid, name)) + new DiagController(serviceProvider, logger).GetProcessInfo(pid, uid, name)) .WithName(nameof(GetProcessInfo)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status200OK) @@ -96,10 +101,12 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // GetProcessEnvironment builder.MapGet("env", ( + IServiceProvider serviceProvider, + ILogger logger, int? pid, Guid? uid, string? name) => - GetProcessEnvironment(pid, uid, name)) + new DiagController(serviceProvider, logger).GetProcessEnvironment(pid, uid, name)) .WithName(nameof(GetProcessEnvironment)) .RequireDiagControllerCommon() .Produces>(StatusCodes.Status200OK) @@ -107,13 +114,15 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CaptureDump builder.MapGet("dump", ( + IServiceProvider serviceProvider, + ILogger logger, int? pid, Guid? uid, string? name, Models.DumpType type = Models.DumpType.WithHeap, string? egressProvider = null, string? tags = null) => - CaptureDump(pid, uid, name, type, egressProvider, tags)) + new DiagController(serviceProvider, logger).CaptureDump(pid, uid, name, type, egressProvider, tags)) .WithName(nameof(CaptureDump)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -124,12 +133,14 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CapturGcDump builder.MapGet("gcdump", ( + IServiceProvider serviceProvider, + ILogger logger, int? pid, Guid? uid, string? name, string? egressProvider, string? tags) => - CaptureGcDump(pid, uid, name, egressProvider, tags)) + new DiagController(serviceProvider, logger).CaptureGcDump(pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureGcDump)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -140,6 +151,8 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CaptureTrace builder.MapGet("trace", ( + IServiceProvider serviceProvider, + ILogger logger, int? pid, Guid? uid, string? name, @@ -148,7 +161,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) int durationSeconds = 30, string? egressProvider = null, string? tags = null) => - CaptureTrace(pid, uid, name, profile, durationSeconds, egressProvider, tags)) + new DiagController(serviceProvider, logger).CaptureTrace(pid, uid, name, profile, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureTrace)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -159,6 +172,8 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CaptureTraceCustom builder.MapGet("trace", ( + IServiceProvider serviceProvider, + ILogger logger, [FromBody][Required] EventPipeConfiguration configuration, int? pid, @@ -168,7 +183,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) int durationSeconds = 30, string? egressProvider = null, string? tags = null) => - CaptureTraceCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + new DiagController(serviceProvider, logger).CaptureTraceCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureTraceCustom)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -179,6 +194,8 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CaptureLogs builder.MapGet("logs", ( + IServiceProvider serviceProvider, + ILogger logger, int? pid, Guid? uid, string? name, @@ -187,7 +204,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) LogLevel? level = null, string? egressProvider = null, string? tags = null) => - CaptureLogs(pid, uid, name, durationSeconds, level, egressProvider, tags)) + new DiagController(serviceProvider, logger).CaptureLogs(pid, uid, name, durationSeconds, level, egressProvider, tags)) .WithName(nameof(CaptureLogs)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -198,6 +215,8 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CaptureLogsCustom builder.MapPost("logs", ( + IServiceProvider serviceProvider, + ILogger logger, [FromBody] LogsConfiguration configuration, int? pid, @@ -207,7 +226,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) int durationSeconds = 30, string? egressProvider = null, string? tags = null) => - CaptureLogsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + new DiagController(serviceProvider, logger).CaptureLogsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureLogs)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -217,7 +236,10 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) .RequireEgressValidation(); // GetInfo - builder.MapGet("info", () => GetInfo()) + builder.MapGet("info", ( + IServiceProvider serviceProvider, + ILogger logger) => + new DiagController(serviceProvider, logger).GetInfo()) .WithName(nameof(GetInfo)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status200OK) @@ -225,10 +247,12 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // GetCollectionRulesDescription builder.MapGet("collectionrules", ( + IServiceProvider serviceProvider, + ILogger logger, int pid, Guid uid, string name) => - GetCollectionRulesDescription(pid, uid, name)) + new DiagController(serviceProvider, logger).GetCollectionRulesDescription(pid, uid, name)) .WithName(nameof(GetCollectionRulesDescription)) .RequireDiagControllerCommon() .Produces>(StatusCodes.Status200OK) @@ -236,11 +260,13 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // GetCollectionRuleDetailedDescription builder.MapGet("collectionrules/{collectionRuleName}", ( + IServiceProvider serviceProvider, + ILogger logger, string collectionRuleName, int pid, Guid uid, string name) => - GetCollectionRuleDetailedDescription(collectionRuleName, pid, uid, name)) + new DiagController(serviceProvider, logger).GetCollectionRuleDetailedDescription(collectionRuleName, pid, uid, name)) .WithName(nameof(GetCollectionRuleDetailedDescription)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status200OK) @@ -248,6 +274,8 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CaptureParameters builder.MapPost("parameters", ( + IServiceProvider serviceProvider, + ILogger logger, [FromBody][Required] CaptureParametersConfiguration configuration, [Range(-1, int.MaxValue)] @@ -257,7 +285,7 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) string? name = null, string? egressProvider = null, string? tags = null) => - CaptureParameters(configuration, durationSeconds, pid, uid, name, egressProvider, tags)) + new DiagController(serviceProvider, logger).CaptureParameters(configuration, durationSeconds, pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureParameters)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -268,12 +296,14 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) // CaptureStacks builder.MapGet("stacks", ( + IServiceProvider serviceProvider, + ILogger logger, int? pid, Guid? uid, string? name, string? egressProvider, string? tags) => - CaptureStacks(pid, uid, name, egressProvider, tags)) + new DiagController(serviceProvider, logger).CaptureStacks(pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureStacks)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -281,8 +311,6 @@ public DiagController MapActionMethods(IEndpointRouteBuilder builder) .Produces(StatusCodes.Status202Accepted) .ProducesProblem(StatusCodes.Status400BadRequest) .RequireEgressValidation(); - - return this; } /// diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs index 1fd7c87e667..ba72770f418 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs @@ -42,16 +42,18 @@ public ExceptionsController( _options = serviceProvider.GetRequiredService>(); } - public ExceptionsController MapActionMethods(IEndpointRouteBuilder builder) + public static void MapActionMethods(IEndpointRouteBuilder builder) { // GetExceptions builder.MapGet("exceptions", ( + IServiceProvider serviceProvider, + ILogger logger, int? pid, Guid? uid, string? name, string? egressProvider = null, string? tags = null) => - GetExceptions(pid, uid, name, egressProvider, tags)) + new ExceptionsController(serviceProvider, logger).GetExceptions(pid, uid, name, egressProvider, tags)) .WithName(nameof(GetExceptions)) .RequireExceptionsControllerCommon() .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) @@ -61,6 +63,8 @@ public ExceptionsController MapActionMethods(IEndpointRouteBuilder builder) // CaptureExceptionsCustom builder.MapPost("exceptions", ( + IServiceProvider serviceProvider, + ILogger logger, [FromBody] ExceptionsConfiguration configuration, int? pid, @@ -68,14 +72,12 @@ public ExceptionsController MapActionMethods(IEndpointRouteBuilder builder) string? name, string? egressProvider = null, string? tags = null) => - CaptureExceptionsCustom(configuration, pid, uid, name, egressProvider, tags)) + new ExceptionsController(serviceProvider, logger).CaptureExceptionsCustom(configuration, pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureExceptionsCustom)) .RequireExceptionsControllerCommon() .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) .ProducesProblem(StatusCodes.Status400BadRequest) .RequireEgressValidation(); - - return this; } /// diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs index 6aecf9c68ca..16fe6185330 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs @@ -29,16 +29,18 @@ public MetricsController(ILogger logger, _metricsOptions = metricsOptions.Value; } - public MetricsController MapActionMethods(IEndpointRouteBuilder builder) + public static void MapActionMethods(IEndpointRouteBuilder builder) { // GetMetrics - builder.MapGet("metrics", () => GetMetrics()) + builder.MapGet("metrics", ( + ILogger logger, + IServiceProvider serviceProvider, + IOptions metricsOptions) => + new MetricsController(logger, serviceProvider, metricsOptions).GetMetrics()) .WithName(nameof(GetMetrics)) .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) .Produces(StatusCodes.Status200OK, ContentTypes.TextPlain_v0_0_4) .ProducesProblem(StatusCodes.Status400BadRequest); - - return this; } /// diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs index adccd16c450..cdbdc9a3b8c 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs @@ -38,23 +38,27 @@ public OperationsController(ILogger logger, IServiceProvid _operationsStore = serviceProvider.GetRequiredService(); } - public OperationsController MapActionMethods(IEndpointRouteBuilder builder) + public static void MapActionMethods(IEndpointRouteBuilder builder) { // GetOperations builder.MapGet($"{ControllerName}/{nameof(GetOperations)}", ( + ILogger logger, + IServiceProvider serviceProvider, int? pid, Guid? uid, string? name, string? tags) => - GetOperations(pid, uid, name, tags)) + new OperationsController(logger, serviceProvider).GetOperations(pid, uid, name, tags)) .WithName(nameof(GetOperations)) .RequireOperationsControllerCommon() .Produces>(StatusCodes.Status200OK); // GetOperationStatus builder.MapGet($"{ControllerName}/{nameof(GetOperationStatus)}/{{operationId}}", ( + ILogger logger, + IServiceProvider serviceProvider, Guid operationId) => - GetOperationStatus(operationId)) + new OperationsController(logger, serviceProvider).GetOperationStatus(operationId)) .WithName(nameof(GetOperationStatus)) .RequireOperationsControllerCommon() .Produces(StatusCodes.Status200OK) @@ -62,15 +66,15 @@ public OperationsController MapActionMethods(IEndpointRouteBuilder builder) // CancelOperation builder.MapDelete($"{ControllerName}/{nameof(CancelOperation)}/{{operationId}}", ( + ILogger logger, + IServiceProvider serviceProvider, Guid operationId, bool stop = false) => - CancelOperation(operationId, stop)) + new OperationsController(logger, serviceProvider).CancelOperation(operationId, stop)) .WithName(nameof(CancelOperation)) .RequireOperationsControllerCommon() .Produces(StatusCodes.Status200OK) .Produces(StatusCodes.Status202Accepted); - - return this; } /// diff --git a/src/Tools/dotnet-monitor/Startup.cs b/src/Tools/dotnet-monitor/Startup.cs index e8b4fe9161e..4a19a0276dc 100644 --- a/src/Tools/dotnet-monitor/Startup.cs +++ b/src/Tools/dotnet-monitor/Startup.cs @@ -12,7 +12,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Swashbuckle.AspNetCore.Swagger; using System.Collections.Generic; @@ -94,22 +93,16 @@ public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, I app.UseEndpoints(builder => { - builder.MapControllers(); - var serviceProvider = builder.ServiceProvider; - new OperationsController(serviceProvider.GetRequiredService>(), serviceProvider) - .MapActionMethods(builder); + OperationsController.MapActionMethods(builder); - new DiagController(serviceProvider, serviceProvider.GetRequiredService>()) - .MapActionMethods(builder) - .MapMetricsActionMethods(builder); + DiagController.MapActionMethods(builder); + DiagController.MapMetricsActionMethods(builder); - new ExceptionsController(serviceProvider, serviceProvider.GetRequiredService>()) - .MapActionMethods(builder); + ExceptionsController.MapActionMethods(builder); - new MetricsController(serviceProvider.GetRequiredService>(), serviceProvider, serviceProvider.GetRequiredService>()) - .MapActionMethods(builder); + MetricsController.MapActionMethods(builder); builder.MapGet("/", (HttpResponse response, ISwaggerProvider provider) => { From 73bb50784cd859fb0a588fdef4146ef6118fbf38 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 12 Mar 2025 21:11:59 +0000 Subject: [PATCH 070/174] WIP openapi --- Directory.Packages.props | 2 + documentation/openapi.json | 438 +++++---- .../ContentTypes.cs | 2 + .../Controllers/DiagController.Metrics.cs | 30 +- .../Controllers/DiagController.cs | 243 ++--- .../Controllers/DiagController.cs.bak | 859 ++++++++++++++++++ .../Controllers/ExceptionsController.cs | 41 +- .../Controllers/MetricsController.cs | 10 +- .../Controllers/OperationsController.cs | 32 +- .../Metrics/JsonCounterLogger.cs | 2 +- .../Metrics/MetricsStore.cs | 2 +- .../Models/CollectionRuleDescription.cs | 2 + .../CollectionRuleDetailedDescription.cs | 7 + .../Validation/CounterValidator.cs | 2 +- ...t.Diagnostics.Monitoring.OpenApiGen.csproj | 7 + .../Program.cs | 53 +- .../getvsdbgsh | 570 ++++++++++++ .../ApiKey/MonitorApiKeyAuthConfigurator.cs | 2 +- .../Commands/CollectCommandHandler.cs | 14 +- .../OpenApi/OpenApiOptionsExtensions.cs | 133 +++ .../{Swagger => OpenApi}/ResponseNames.cs | 2 +- .../{Swagger => OpenApi}/StatusCodeStrings.cs | 2 +- .../SwaggerProviderExtensions.cs | 2 +- .../BadRequestResponseDocumentTransformer.cs} | 12 +- ...BadRequestResponseOperationTransformer.cs} | 10 +- ...emoveFailureContentTypesOperationFilter.cs | 2 +- ...anyRequestsResponseDocumentTransformer.cs} | 10 +- ...nyRequestsResponseOperationTransformer.cs} | 10 +- ...nauthorizedResponseDocumentTransformer.cs} | 12 +- ...authorizedResponseOperationTransformer.cs} | 10 +- src/Tools/dotnet-monitor/Startup.cs | 26 +- .../Swagger/SwaggerGenOptionsExtensions.cs | 63 -- .../dotnet-monitor/dotnet-monitor.csproj | 2 + 33 files changed, 2091 insertions(+), 523 deletions(-) create mode 100644 src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs.bak create mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/getvsdbgsh create mode 100644 src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs rename src/Tools/dotnet-monitor/{Swagger => OpenApi}/ResponseNames.cs (89%) rename src/Tools/dotnet-monitor/{Swagger => OpenApi}/StatusCodeStrings.cs (92%) rename src/Tools/dotnet-monitor/{Swagger => OpenApi}/SwaggerProviderExtensions.cs (93%) rename src/Tools/dotnet-monitor/{Swagger/Filters/BadRequestResponseDocumentFilter.cs => OpenApi/Transformers/BadRequestResponseDocumentTransformer.cs} (69%) rename src/Tools/dotnet-monitor/{Swagger/Filters/BadRequestResponseOperationFilter.cs => OpenApi/Transformers/BadRequestResponseOperationTransformer.cs} (70%) rename src/Tools/dotnet-monitor/{Swagger/Filters => OpenApi/Transformers}/RemoveFailureContentTypesOperationFilter.cs (93%) rename src/Tools/dotnet-monitor/{Swagger/Filters/TooManyRequestsResponseDocumentFilter.cs => OpenApi/Transformers/TooManyRequestsResponseDocumentTransformer.cs} (72%) rename src/Tools/dotnet-monitor/{Swagger/Filters/TooManyRequestsResponseOperationFilter.cs => OpenApi/Transformers/TooManyRequestsResponseOperationTransformer.cs} (65%) rename src/Tools/dotnet-monitor/{Swagger/Filters/UnauthorizedResponseDocumentFilter.cs => OpenApi/Transformers/UnauthorizedResponseDocumentTransformer.cs} (62%) rename src/Tools/dotnet-monitor/{Swagger/Filters/UnauthorizedResponseOperationFilter.cs => OpenApi/Transformers/UnauthorizedResponseOperationTransformer.cs} (67%) delete mode 100644 src/Tools/dotnet-monitor/Swagger/SwaggerGenOptionsExtensions.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 2998d1aa653..46c34048b65 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -30,5 +30,7 @@ + + diff --git a/documentation/openapi.json b/documentation/openapi.json index 0cbd75e6961..7ecdeb74cbb 100644 --- a/documentation/openapi.json +++ b/documentation/openapi.json @@ -1,8 +1,8 @@ { "openapi": "3.0.1", "info": { - "title": "dotnet-monitor", - "version": "1.0" + "title": "dotnet-monitor | v1", + "version": "1.0.0" }, "paths": { "/processes": { @@ -13,9 +13,6 @@ "summary": "Get the list of accessible processes.", "operationId": "GetProcesses", "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -31,6 +28,9 @@ } } } + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -71,9 +71,6 @@ } ], "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -86,6 +83,9 @@ } } } + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -126,9 +126,6 @@ } ], "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -144,6 +141,9 @@ } } } + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -187,7 +187,13 @@ "in": "query", "description": "The type of dump to capture.", "schema": { - "$ref": "#/components/schemas/DumpType" + "enum": [ + "Full", + "Mini", + "WithHeap", + "Triage" + ], + "default": "WithHeap" } }, { @@ -195,7 +201,8 @@ "in": "query", "description": "The egress provider to which the dump is saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -203,14 +210,12 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -230,6 +235,9 @@ }, "202": { "description": "Accepted" + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -286,9 +294,6 @@ } ], "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -308,6 +313,9 @@ }, "202": { "description": "Accepted" + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -351,7 +359,8 @@ "in": "query", "description": "The profiles enabled for the trace session.", "schema": { - "$ref": "#/components/schemas/TraceProfile" + "type": "string", + "default": "Cpu, Http, Metrics, GcCollect" } }, { @@ -371,7 +380,8 @@ "in": "query", "description": "The egress provider to which the trace is saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -379,14 +389,12 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -406,6 +414,9 @@ }, "202": { "description": "Accepted" + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } }, @@ -459,7 +470,8 @@ "in": "query", "description": "The egress provider to which the trace is saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -467,7 +479,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -493,9 +506,6 @@ "required": true }, "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -515,6 +525,9 @@ }, "202": { "description": "Accepted" + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -570,7 +583,17 @@ "in": "query", "description": "The level of the logs to capture.", "schema": { - "$ref": "#/components/schemas/LogLevel" + "enum": [ + "Trace", + "Debug", + "Information", + "Warning", + "Error", + "Critical", + "None", + null + ], + "default": null } }, { @@ -578,7 +601,8 @@ "in": "query", "description": "The egress provider to which the logs are saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -586,14 +610,12 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -622,6 +644,9 @@ }, "202": { "description": "Accepted" + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } }, @@ -675,7 +700,8 @@ "in": "query", "description": "The egress provider to which the logs are saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -683,7 +709,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -705,12 +732,10 @@ "$ref": "#/components/schemas/LogsConfiguration" } } - } + }, + "required": true }, "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -739,6 +764,9 @@ }, "202": { "description": "Accepted" + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -751,9 +779,6 @@ "summary": "Gets versioning and listening mode information about Dotnet-Monitor", "operationId": "GetInfo", "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -766,6 +791,9 @@ } } } + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -806,9 +834,6 @@ } ], "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -824,6 +849,9 @@ } } } + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -873,9 +901,6 @@ } ], "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -888,6 +913,9 @@ } } } + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -915,7 +943,8 @@ "in": "query", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -923,28 +952,32 @@ "in": "query", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { "name": "name", "in": "query", "schema": { - "type": "string" + "type": "string", + "default": null } }, { "name": "egressProvider", "in": "query", "schema": { - "type": "string" + "type": "string", + "default": null } }, { "name": "tags", "in": "query", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -969,9 +1002,6 @@ "required": true }, "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -1000,6 +1030,9 @@ }, "202": { "description": "Accepted" + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -1050,9 +1083,6 @@ } ], "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -1081,6 +1111,9 @@ }, "202": { "description": "Accepted" + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -1136,7 +1169,8 @@ "in": "query", "description": "The egress provider to which the metrics are saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1144,14 +1178,12 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -1170,6 +1202,9 @@ }, "202": { "description": "Accepted" + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } }, @@ -1223,7 +1258,8 @@ "in": "query", "description": "The egress provider to which the metrics are saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1231,7 +1267,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -1257,9 +1294,6 @@ "required": true }, "responses": { - "400": { - "$ref": "#/components/responses/BadRequestResponse" - }, "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, @@ -1278,6 +1312,9 @@ }, "202": { "description": "Accepted" + }, + "400": { + "$ref": "#/components/responses/BadRequestResponse" } } } @@ -1321,7 +1358,8 @@ "in": "query", "description": "The egress provider to which the exceptions are saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1329,7 +1367,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -1400,7 +1439,8 @@ "in": "query", "description": "The egress provider to which the exceptions are saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1408,7 +1448,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -1430,7 +1471,8 @@ "$ref": "#/components/schemas/ExceptionsConfiguration" } } - } + }, + "required": true }, "responses": { "400": { @@ -1567,8 +1609,8 @@ "401": { "$ref": "#/components/responses/UnauthorizedResponse" }, - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "application/json": { "schema": { @@ -1577,8 +1619,8 @@ } } }, - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "application/json": { "schema": { @@ -1652,8 +1694,7 @@ "format": "int32", "nullable": true } - }, - "additionalProperties": false + } }, "CollectionRuleDescription": { "type": "object", @@ -1666,20 +1707,11 @@ "description": "Human-readable explanation for the current state of the collection rule.", "nullable": true } - }, - "additionalProperties": false + } }, "CollectionRuleDetailedDescription": { "type": "object", "properties": { - "state": { - "$ref": "#/components/schemas/CollectionRuleState" - }, - "stateReason": { - "type": "string", - "description": "Human-readable explanation for the current state of the collection rule.", - "nullable": true - }, "lifetimeOccurrences": { "type": "integer", "description": "The number of times the trigger has executed for a process in its lifetime.", @@ -1696,28 +1728,32 @@ "format": "int32" }, "actionCountSlidingWindowDurationLimit": { + "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$", "type": "string", "description": "The sliding window duration in which the actionCountLimit is the maximum number of occurrences (as defined by Limits).", - "format": "time-span", - "nullable": true, - "example": "00:00:30" + "nullable": true }, "slidingWindowDurationCountdown": { + "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$", "type": "string", "description": "The amount of time that needs to pass before the slidingWindowOccurrences drops below the actionCountLimit", - "format": "time-span", - "nullable": true, - "example": "00:00:30" + "nullable": true }, "ruleFinishedCountdown": { + "pattern": "^-?(\\d+\\.)?\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$", "type": "string", "description": "The amount of time that needs to pass before the rule is finished", - "format": "time-span", - "nullable": true, - "example": "00:00:30" + "nullable": true + }, + "state": { + "$ref": "#/components/schemas/CollectionRuleState" + }, + "stateReason": { + "type": "string", + "description": "Human-readable explanation for the current state of the collection rule.", + "nullable": true } - }, - "additionalProperties": false + } }, "CollectionRuleState": { "enum": [ @@ -1725,27 +1761,23 @@ "ActionExecuting", "Throttled", "Finished" - ], - "type": "string" + ] }, "DiagnosticPortConnectionMode": { "enum": [ "Connect", "Listen" - ], - "type": "string" + ] }, "DotnetMonitorInfo": { "type": "object", "properties": { "version": { "type": "string", - "description": "The dotnet monitor version.", "nullable": true }, "runtimeVersion": { "type": "string", - "description": "The dotnet runtime version.", "nullable": true }, "diagnosticPortMode": { @@ -1753,20 +1785,9 @@ }, "diagnosticPortName": { "type": "string", - "description": "The name of the named pipe or unix domain socket to use for connecting to the diagnostic server.", "nullable": true } - }, - "additionalProperties": false - }, - "DumpType": { - "enum": [ - "Full", - "Mini", - "WithHeap", - "Triage" - ], - "type": "string" + } }, "EventLevel": { "enum": [ @@ -1776,8 +1797,7 @@ "Warning", "Informational", "Verbose" - ], - "type": "string" + ] }, "EventMetricsConfiguration": { "type": "object", @@ -1799,8 +1819,7 @@ }, "nullable": true } - }, - "additionalProperties": false + } }, "EventMetricsMeter": { "required": [ @@ -1809,7 +1828,6 @@ "type": "object", "properties": { "meterName": { - "minLength": 1, "type": "string" }, "instrumentNames": { @@ -1819,8 +1837,7 @@ }, "nullable": true } - }, - "additionalProperties": false + } }, "EventMetricsProvider": { "required": [ @@ -1829,7 +1846,6 @@ "type": "object", "properties": { "providerName": { - "minLength": 1, "type": "string" }, "counterNames": { @@ -1839,8 +1855,7 @@ }, "nullable": true } - }, - "additionalProperties": false + } }, "EventPipeConfiguration": { "required": [ @@ -1864,8 +1879,7 @@ "type": "integer", "format": "int32" } - }, - "additionalProperties": false + } }, "EventPipeProvider": { "required": [ @@ -1874,7 +1888,6 @@ "type": "object", "properties": { "name": { - "minLength": 1, "type": "string" }, "keywords": { @@ -1891,8 +1904,7 @@ }, "nullable": true } - }, - "additionalProperties": false + } }, "ExceptionFilter": { "type": "object", @@ -1913,8 +1925,7 @@ "type": "string", "nullable": true } - }, - "additionalProperties": false + } }, "ExceptionsConfiguration": { "type": "object", @@ -1923,18 +1934,15 @@ "type": "array", "items": { "$ref": "#/components/schemas/ExceptionFilter" - }, - "nullable": true + } }, "exclude": { "type": "array", "items": { "$ref": "#/components/schemas/ExceptionFilter" - }, - "nullable": true + } } - }, - "additionalProperties": false + } }, "LogLevel": { "enum": [ @@ -1945,8 +1953,7 @@ "Error", "Critical", "None" - ], - "type": "string" + ] }, "LogsConfiguration": { "required": [ @@ -1960,40 +1967,45 @@ "filterSpecs": { "type": "object", "additionalProperties": { - "$ref": "#/components/schemas/LogLevel" + "$ref": "#/components/schemas/NullableOfLogLevel" }, - "description": "The logger categories and levels at which logs are collected. Setting the log level to null will have logs collected from the corresponding category at the level set in the LogLevel property.", "nullable": true }, "useAppFilters": { - "type": "boolean", - "description": "Set to true to collect logs at the application-defined categories and levels." + "type": "boolean" } - }, - "additionalProperties": false + } }, "MethodDescription": { "required": [ - "methodName", "moduleName", - "typeName" + "typeName", + "methodName" ], "type": "object", "properties": { "moduleName": { - "minLength": 1, "type": "string" }, "typeName": { - "minLength": 1, "type": "string" }, "methodName": { - "minLength": 1, "type": "string" } - }, - "additionalProperties": false + } + }, + "NullableOfLogLevel": { + "enum": [ + "Trace", + "Debug", + "Information", + "Warning", + "Error", + "Critical", + "None", + null + ] }, "OperationError": { "type": "object", @@ -2007,7 +2019,7 @@ "nullable": true } }, - "additionalProperties": false + "nullable": true }, "OperationProcessInfo": { "type": "object", @@ -2025,8 +2037,7 @@ "nullable": true } }, - "additionalProperties": false, - "description": "Represents the details of a given process used in an operation." + "nullable": true }, "OperationState": { "enum": [ @@ -2036,12 +2047,18 @@ "Failed", "Cancelled", "Stopping" - ], - "type": "string" + ] }, "OperationStatus": { "type": "object", "properties": { + "resourceLocation": { + "type": "string", + "nullable": true + }, + "error": { + "$ref": "#/components/schemas/OperationError" + }, "operationId": { "type": "string", "format": "uuid" @@ -2064,23 +2081,13 @@ "type": "boolean" }, "tags": { - "uniqueItems": true, "type": "array", "items": { "type": "string" }, "nullable": true - }, - "resourceLocation": { - "type": "string", - "nullable": true - }, - "error": { - "$ref": "#/components/schemas/OperationError" } - }, - "additionalProperties": false, - "description": "Represents the state of a long running operation. Used for all types of results, including successes and failures." + } }, "OperationSummary": { "type": "object", @@ -2107,16 +2114,13 @@ "type": "boolean" }, "tags": { - "uniqueItems": true, "type": "array", "items": { "type": "string" }, "nullable": true } - }, - "additionalProperties": false, - "description": "Represents a partial model when enumerating all operations." + } }, "ProblemDetails": { "type": "object", @@ -2142,8 +2146,7 @@ "type": "string", "nullable": true } - }, - "additionalProperties": { } + } }, "ProcessIdentifier": { "type": "object", @@ -2163,8 +2166,7 @@ "isDefault": { "type": "boolean" } - }, - "additionalProperties": false + } }, "ProcessInfo": { "type": "object", @@ -2193,55 +2195,7 @@ "type": "string", "nullable": true } - }, - "additionalProperties": false - }, - "TraceProfile": { - "enum": [ - "Cpu", - "Http", - "Logs", - "Metrics", - "GcCollect" - ], - "type": "string" - }, - "ValidationProblemDetails": { - "type": "object", - "properties": { - "type": { - "type": "string", - "nullable": true - }, - "title": { - "type": "string", - "nullable": true - }, - "status": { - "type": "integer", - "format": "int32", - "nullable": true - }, - "detail": { - "type": "string", - "nullable": true - }, - "instance": { - "type": "string", - "nullable": true - }, - "errors": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - }, - "nullable": true - } - }, - "additionalProperties": { } + } } }, "responses": { @@ -2276,5 +2230,19 @@ } } } - } + }, + "tags": [ + { + "name": "Diag" + }, + { + "name": "Exceptions" + }, + { + "name": "Metrics" + }, + { + "name": "Operations" + } + ] } \ No newline at end of file diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/ContentTypes.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/ContentTypes.cs index 063be35f7ed..f3e410b3e8c 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/ContentTypes.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/ContentTypes.cs @@ -13,5 +13,7 @@ public static class ContentTypes public const string ApplicationSpeedscopeJson = "application/speedscope+json"; public const string TextPlain = "text/plain"; public const string TextPlain_v0_0_4 = TextPlain + "; version=0.0.4"; + public const string TextJson = "text/json"; + public const string ApplicationAnyJson = "application/*+json"; } } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs index 3ac36d36b23..38fc50b9c6b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs @@ -8,6 +8,7 @@ using Microsoft.Diagnostics.Monitoring.EventPipe; using Microsoft.Extensions.Logging; using System; +using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; @@ -18,17 +19,24 @@ partial class DiagController public static void MapMetricsActionMethods(IEndpointRouteBuilder builder) { // CaptureMetrics - builder.MapGet("livemetrics", ( - IServiceProvider serviceProvider, + builder.MapGet("livemetrics", + [EndpointSummary("Capture metrics for a process.")] ( + HttpContext context, ILogger logger, + [Description("Process ID used to identify the target process.")] int? pid, + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [Description("Process name used to identify the target process.")] string? name, [Range(-1, int.MaxValue)] + [Description("The duration of the metrics session (in seconds).")] int durationSeconds = 30, + [Description("The egress provider to which the metrics are saved.")] string? egressProvider = null, + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) => - new DiagController(serviceProvider, logger).CaptureMetrics(pid, uid, name, durationSeconds, egressProvider, tags)) + new DiagController(context.RequestServices, logger).CaptureMetrics(pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureMetrics)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -38,25 +46,33 @@ public static void MapMetricsActionMethods(IEndpointRouteBuilder builder) .RequireEgressValidation(); // CaptureMetricsCustom - builder.MapGet("livemetrics", ( - IServiceProvider serviceProvider, + builder.MapPost("livemetrics", + [EndpointSummary("Capture metrics for a process.")] ( + HttpContext context, ILogger logger, - [FromBody][Required] + [FromBody][Required][Description("The metrics configuration describing which metrics to capture.")] Models.EventMetricsConfiguration configuration, + [Description("Process ID used to identify the target process.")] int? pid, + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [Description("Process name used to identify the target process.")] string? name, [Range(-1, int.MaxValue)] + [Description("The duration of the metrics session (in seconds).")] int durationSeconds = 30, + [Description("The egress provider to which the metrics are saved.")] string? egressProvider = null, + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) => - new DiagController(serviceProvider, logger).CaptureMetricsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + new DiagController(context.RequestServices, logger).CaptureMetricsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureMetricsCustom)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJsonSequence) .Produces(StatusCodes.Status202Accepted) .ProducesProblem(StatusCodes.Status400BadRequest) + .Accepts(ContentTypes.ApplicationJson, ContentTypes.TextJson, ContentTypes.ApplicationAnyJson) .RequireEgressValidation(); } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs index f895d2acd2b..8931108d9a7 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs @@ -19,6 +19,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.ComponentModel; using System.Reflection; using System.Threading.Tasks; @@ -32,7 +33,8 @@ public static RouteHandlerBuilder RequireDiagControllerCommon(this RouteHandlerB .RequireHostRestriction() .RequireAuthorization(AuthConstants.PolicyName) .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson); + // .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .WithTags("Diag"); } } @@ -77,70 +79,78 @@ public DiagController(IServiceProvider serviceProvider, ILogger public static void MapActionMethods(IEndpointRouteBuilder builder) { // GetProcesses - builder.MapGet("processes", ( - IServiceProvider serviceProvider, + builder.MapGet("processes", + [EndpointSummary("Get the list of accessible processes.")] ( + HttpContext context, ILogger logger) => - new DiagController(serviceProvider, logger).GetProcesses()) + new DiagController(context.RequestServices, logger).GetProcesses()) .WithName(nameof(GetProcesses)) .RequireDiagControllerCommon() .Produces>(StatusCodes.Status200OK) .ProducesProblem(StatusCodes.Status400BadRequest); // GetProcessInfo - builder.MapGet("process", ( - IServiceProvider serviceProvider, + builder.MapGet("process", + [EndpointSummary("Get information about the specified process.")] ( + HttpContext context, ILogger logger, - int? pid, - Guid? uid, - string? name) => - new DiagController(serviceProvider, logger).GetProcessInfo(pid, uid, name)) + [FromQuery, Description("Process ID used to identify the target process.")] int? pid, + [FromQuery, Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [FromQuery, Description("Process name used to identify the target process.")] string? name) => + new DiagController(context.RequestServices, logger).GetProcessInfo(pid, uid, name)) .WithName(nameof(GetProcessInfo)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status200OK) .ProducesProblem(StatusCodes.Status400BadRequest); // GetProcessEnvironment - builder.MapGet("env", ( - IServiceProvider serviceProvider, + builder.MapGet("env", + [EndpointSummary("Get the environment block of the specified process.")] ( + HttpContext context, ILogger logger, - int? pid, - Guid? uid, - string? name) => - new DiagController(serviceProvider, logger).GetProcessEnvironment(pid, uid, name)) + [FromQuery, Description("Process ID used to identify the target process.")] int? pid, + [FromQuery, Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [FromQuery, Description("Process name used to identify the target process.")] string? name) => + new DiagController(context.RequestServices, logger).GetProcessEnvironment(pid, uid, name)) .WithName(nameof(GetProcessEnvironment)) .RequireDiagControllerCommon() .Produces>(StatusCodes.Status200OK) .ProducesProblem(StatusCodes.Status400BadRequest); // CaptureDump - builder.MapGet("dump", ( - IServiceProvider serviceProvider, + builder.MapGet("dump", + [EndpointSummary("Capture a dump of a process.")] ( + HttpContext context, ILogger logger, - int? pid, - Guid? uid, - string? name, - Models.DumpType type = Models.DumpType.WithHeap, - string? egressProvider = null, - string? tags = null) => - new DiagController(serviceProvider, logger).CaptureDump(pid, uid, name, type, egressProvider, tags)) + [FromQuery, Description("Process ID used to identify the target process.")] int? pid, + [FromQuery, Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [FromQuery, Description("Process name used to identify the target process.")] string? name, + [FromQuery, Description("The type of dump to capture.")] Models.DumpType type = Models.DumpType.WithHeap, + [FromQuery, Description("The egress provider to which the dump is saved.")] string? egressProvider = null, + [FromQuery, Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) => + new DiagController(context.RequestServices, logger).CaptureDump(pid, uid, name, type, egressProvider, tags)) .WithName(nameof(CaptureDump)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + // .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + // .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + // .Produces(StatusCodes.Status200OK) .Produces(StatusCodes.Status202Accepted) .ProducesProblem(StatusCodes.Status400BadRequest) .RequireEgressValidation(); - // CapturGcDump - builder.MapGet("gcdump", ( - IServiceProvider serviceProvider, + // CaptureGcDump + builder.MapGet("gcdump", + [EndpointSummary("Capture a GC dump of a process.")] ( + HttpContext context, ILogger logger, - int? pid, - Guid? uid, - string? name, - string? egressProvider, - string? tags) => - new DiagController(serviceProvider, logger).CaptureGcDump(pid, uid, name, egressProvider, tags)) + [FromQuery, Description("Process ID used to identify the target process.")] int? pid, + [FromQuery, Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [FromQuery, Description("Process name used to identify the target process.")] string? name, + [FromQuery, Description("The egress provider to which the GC dump is saved.")] string? egressProvider, + [FromQuery, Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags) => + new DiagController(context.RequestServices, logger).CaptureGcDump(pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureGcDump)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -150,18 +160,18 @@ public static void MapActionMethods(IEndpointRouteBuilder builder) .RequireEgressValidation(); // CaptureTrace - builder.MapGet("trace", ( - IServiceProvider serviceProvider, + builder.MapGet("trace", + [EndpointSummary("Capture a trace of a process.")] ( + HttpContext context, ILogger logger, - int? pid, - Guid? uid, - string? name, - TraceProfile profile = DefaultTraceProfiles, - [Range(-1, int.MaxValue)] - int durationSeconds = 30, - string? egressProvider = null, - string? tags = null) => - new DiagController(serviceProvider, logger).CaptureTrace(pid, uid, name, profile, durationSeconds, egressProvider, tags)) + [FromQuery, Description("Process ID used to identify the target process.")] int? pid, + [FromQuery, Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [FromQuery, Description("Process name used to identify the target process.")] string? name, + [FromQuery, Description("The profiles enabled for the trace session.")] TraceProfile profile = DefaultTraceProfiles, + [FromQuery, Description("The duration of the trace session (in seconds)."), Range(-1, int.MaxValue)] int durationSeconds = 30, + [FromQuery, Description("The egress provider to which the trace is saved.")] string? egressProvider = null, + [FromQuery, Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) => + new DiagController(context.RequestServices, logger).CaptureTrace(pid, uid, name, profile, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureTrace)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -171,40 +181,41 @@ public static void MapActionMethods(IEndpointRouteBuilder builder) .RequireEgressValidation(); // CaptureTraceCustom - builder.MapGet("trace", ( - IServiceProvider serviceProvider, + builder.MapPost("trace", + [EndpointSummary("Capture a trace of a process.")] ( + HttpContext context, ILogger logger, - [FromBody][Required] - EventPipeConfiguration configuration, - int? pid, - Guid? uid, - string? name, - [Range(-1, int.MaxValue)] - int durationSeconds = 30, - string? egressProvider = null, - string? tags = null) => - new DiagController(serviceProvider, logger).CaptureTraceCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + [FromBody, Required, Description("The trace configuration describing which events to capture.")] EventPipeConfiguration configuration, + [FromQuery, Description("Process ID used to identify the target process.")] int? pid, + [FromQuery, Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [FromQuery, Description("Process name used to identify the target process.")] string? name, + [FromQuery, Description("The duration of the trace session (in seconds)."), Range(-1, int.MaxValue)] int durationSeconds = 30, + [FromQuery, Description("The egress provider to which the trace is saved.")] string? egressProvider = null, + [FromQuery, Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) => + new DiagController(context.RequestServices, logger).CaptureTraceCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) .WithName(nameof(CaptureTraceCustom)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) .Produces(StatusCodes.Status202Accepted) .ProducesProblem(StatusCodes.Status400BadRequest) + // TODO: does it actually accept these? + .Accepts(ContentTypes.ApplicationJson, ContentTypes.TextJson, ContentTypes.ApplicationAnyJson) .RequireEgressValidation(); // CaptureLogs - builder.MapGet("logs", ( - IServiceProvider serviceProvider, + builder.MapGet("logs", + [EndpointSummary("Capture a stream of logs from a process.")] ( + HttpContext context, ILogger logger, - int? pid, - Guid? uid, - string? name, - [Range(-1, int.MaxValue)] - int durationSeconds = 30, - LogLevel? level = null, - string? egressProvider = null, - string? tags = null) => - new DiagController(serviceProvider, logger).CaptureLogs(pid, uid, name, durationSeconds, level, egressProvider, tags)) + [FromQuery, Description("Process ID used to identify the target process.")] int? pid, + [FromQuery, Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [FromQuery, Description("Process name used to identify the target process.")] string? name, + [FromQuery, Description("The duration of the logs session (in seconds)."), Range(-1, int.MaxValue)] int durationSeconds = 30, + [FromQuery, Description("The level of the logs to capture.")] LogLevel? level = null, + [FromQuery, Description("The egress provider to which the logs are saved.")] string? egressProvider = null, + [FromQuery, Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) => + new DiagController(context.RequestServices, logger).CaptureLogs(pid, uid, name, durationSeconds, level, egressProvider, tags)) .WithName(nameof(CaptureLogs)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) @@ -214,59 +225,62 @@ public static void MapActionMethods(IEndpointRouteBuilder builder) .RequireEgressValidation(); // CaptureLogsCustom - builder.MapPost("logs", ( - IServiceProvider serviceProvider, + builder.MapPost("logs", + [EndpointSummary("Capture a stream of logs from a process.")] ( + HttpContext context, ILogger logger, - [FromBody] - LogsConfiguration configuration, - int? pid, - Guid? uid, - string? name, - [Range(-1, int.MaxValue)] - int durationSeconds = 30, - string? egressProvider = null, - string? tags = null) => - new DiagController(serviceProvider, logger).CaptureLogsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) - .WithName(nameof(CaptureLogs)) + [FromBody, Description("The logs configuration describing which logs to capture.")] LogsConfiguration configuration, + [FromQuery, Description("Process ID used to identify the target process.")] int? pid, + [FromQuery, Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [FromQuery, Description("Process name used to identify the target process.")] string? name, + [FromQuery, Description("The duration of the logs session (in seconds)."), Range(-1, int.MaxValue)] int durationSeconds = 30, + [FromQuery, Description("The egress provider to which the logs are saved.")] string? egressProvider = null, + [FromQuery, Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) => + new DiagController(context.RequestServices, logger).CaptureLogsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + .WithName(nameof(CaptureLogsCustom)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) .Produces(StatusCodes.Status202Accepted) .ProducesProblem(StatusCodes.Status400BadRequest) + .Accepts(ContentTypes.ApplicationJson, ContentTypes.TextJson, ContentTypes.ApplicationAnyJson) .RequireEgressValidation(); // GetInfo - builder.MapGet("info", ( - IServiceProvider serviceProvider, + builder.MapGet("info", + [EndpointSummary("Gets versioning and listening mode information about Dotnet-Monitor")] ( + HttpContext context, ILogger logger) => - new DiagController(serviceProvider, logger).GetInfo()) + new DiagController(context.RequestServices, logger).GetInfo()) .WithName(nameof(GetInfo)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status200OK) .ProducesProblem(StatusCodes.Status400BadRequest); // GetCollectionRulesDescription - builder.MapGet("collectionrules", ( - IServiceProvider serviceProvider, + builder.MapGet("collectionrules", + [EndpointSummary("Gets a brief summary about the current state of the collection rules.")] ( + HttpContext context, ILogger logger, - int pid, - Guid uid, - string name) => - new DiagController(serviceProvider, logger).GetCollectionRulesDescription(pid, uid, name)) + [FromQuery, Description("Process ID used to identify the target process.")] int? pid, + [FromQuery, Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [FromQuery, Description("Process name used to identify the target process.")] string? name) => + new DiagController(context.RequestServices, logger).GetCollectionRulesDescription(pid, uid, name)) .WithName(nameof(GetCollectionRulesDescription)) .RequireDiagControllerCommon() .Produces>(StatusCodes.Status200OK) .ProducesProblem(StatusCodes.Status400BadRequest); // GetCollectionRuleDetailedDescription - builder.MapGet("collectionrules/{collectionRuleName}", ( - IServiceProvider serviceProvider, + builder.MapGet("collectionrules/{collectionRuleName}", + [EndpointSummary("Gets detailed information about the current state of the specified collection rule.")] ( + HttpContext context, ILogger logger, - string collectionRuleName, - int pid, - Guid uid, - string name) => - new DiagController(serviceProvider, logger).GetCollectionRuleDetailedDescription(collectionRuleName, pid, uid, name)) + [FromRoute, Description("The name of the collection rule for which a detailed description should be provided.")] string collectionRuleName, + [FromQuery, Description("Process ID used to identify the target process.")] int? pid, + [FromQuery, Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [FromQuery, Description("Process name used to identify the target process.")] string? name) => + new DiagController(context.RequestServices, logger).GetCollectionRuleDetailedDescription(collectionRuleName, pid, uid, name)) .WithName(nameof(GetCollectionRuleDetailedDescription)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status200OK) @@ -274,36 +288,35 @@ public static void MapActionMethods(IEndpointRouteBuilder builder) // CaptureParameters builder.MapPost("parameters", ( - IServiceProvider serviceProvider, + HttpContext context, ILogger logger, - [FromBody][Required] - CaptureParametersConfiguration configuration, - [Range(-1, int.MaxValue)] - int durationSeconds = 30, - int? pid = null, - Guid? uid = null, - string? name = null, - string? egressProvider = null, - string? tags = null) => - new DiagController(serviceProvider, logger).CaptureParameters(configuration, durationSeconds, pid, uid, name, egressProvider, tags)) + [FromBody, Required] CaptureParametersConfiguration configuration, + [FromQuery, Range(-1, int.MaxValue)] int durationSeconds = 30, + [FromQuery] int? pid = null, + [FromQuery] Guid? uid = null, + [FromQuery] string? name = null, + [FromQuery] string? egressProvider = null, + [FromQuery] string? tags = null) => + new DiagController(context.RequestServices, logger).CaptureParameters(configuration, durationSeconds, pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureParameters)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) .Produces(StatusCodes.Status202Accepted) .ProducesProblem(StatusCodes.Status400BadRequest) + .Accepts(ContentTypes.ApplicationJson, ContentTypes.TextJson, ContentTypes.ApplicationAnyJson) .RequireEgressValidation(); // CaptureStacks builder.MapGet("stacks", ( - IServiceProvider serviceProvider, + HttpContext context, ILogger logger, - int? pid, - Guid? uid, - string? name, - string? egressProvider, - string? tags) => - new DiagController(serviceProvider, logger).CaptureStacks(pid, uid, name, egressProvider, tags)) + [FromQuery] int? pid, + [FromQuery] Guid? uid, + [FromQuery] string? name, + [FromQuery] string? egressProvider, + [FromQuery] string? tags) => + new DiagController(context.RequestServices, logger).CaptureStacks(pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureStacks)) .RequireDiagControllerCommon() .Produces(StatusCodes.Status429TooManyRequests) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs.bak b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs.bak new file mode 100644 index 00000000000..ee41be32bfa --- /dev/null +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs.bak @@ -0,0 +1,859 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.HttpResults; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Routing; +using Microsoft.Diagnostics.Monitoring.EventPipe; +using Microsoft.Diagnostics.Monitoring.Options; +using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Monitoring.WebApi.Validation; +using Microsoft.Diagnostics.NETCore.Client; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Microsoft.Net.Http.Headers; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers +{ + static partial class RouteHandlerBuilderExtensions + { + public static RouteHandlerBuilder RequireDiagControllerCommon(this RouteHandlerBuilder builder) + { + return builder + .RequireHostRestriction() + .RequireAuthorization(AuthConstants.PolicyName) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson); + } + } + + public partial class DiagController : DiagnosticsControllerBase + { +#pragma warning disable CA1823 // Avoid unused field warning since this is used as default parameter of lambda + private const TraceProfile DefaultTraceProfiles = TraceProfile.Cpu | TraceProfile.Http | TraceProfile.Metrics | TraceProfile.GcCollect; +#pragma warning restore CA1823 + + private readonly IOptions _diagnosticPortOptions; + private readonly IOptions _callStacksOptions; + private readonly IOptions _parameterCapturingOptions; + private readonly IOptionsMonitor _counterOptions; + private readonly IOptionsMonitor _metricsOptions; + private readonly ICollectionRuleService _collectionRuleService; + private readonly IDumpOperationFactory _dumpOperationFactory; + private readonly ILogsOperationFactory _logsOperationFactory; + private readonly IMetricsOperationFactory _metricsOperationFactory; + private readonly ITraceOperationFactory _traceOperationFactory; + private readonly ICaptureParametersOperationFactory _captureParametersFactory; + private readonly IGCDumpOperationFactory _gcdumpOperationFactory; + private readonly IStacksOperationFactory _stacksOperationFactory; + + public DiagController(IServiceProvider serviceProvider, ILogger logger) + : base(serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService(), logger) + { + _diagnosticPortOptions = serviceProvider.GetRequiredService>(); + _callStacksOptions = serviceProvider.GetRequiredService>(); + _parameterCapturingOptions = serviceProvider.GetRequiredService>(); + _counterOptions = serviceProvider.GetRequiredService>(); + _metricsOptions = serviceProvider.GetRequiredService>(); + _collectionRuleService = serviceProvider.GetRequiredService(); + _dumpOperationFactory = serviceProvider.GetRequiredService(); + _logsOperationFactory = serviceProvider.GetRequiredService(); + _metricsOperationFactory = serviceProvider.GetRequiredService(); + _traceOperationFactory = serviceProvider.GetRequiredService(); + _captureParametersFactory = serviceProvider.GetRequiredService(); + _gcdumpOperationFactory = serviceProvider.GetRequiredService(); + _stacksOperationFactory = serviceProvider.GetRequiredService(); + } + + public static void MapActionMethods(IEndpointRouteBuilder builder) + { + // GetProcesses + builder.MapGet("processes", ( + HttpContext context, + ILogger logger) => + new DiagController(context.RequestServices, logger).GetProcesses()) + .WithName(nameof(GetProcesses)) + .RequireDiagControllerCommon() + .Produces>(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // GetProcessInfo + builder.MapGet("process", ( + HttpContext context, + ILogger logger, + int? pid, + Guid? uid, + string? name) => + new DiagController(context.RequestServices, logger).GetProcessInfo(pid, uid, name)) + .WithName(nameof(GetProcessInfo)) + .RequireDiagControllerCommon() + .Produces(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // GetProcessEnvironment + builder.MapGet("env", ( + HttpContext context, + ILogger logger, + int? pid, + Guid? uid, + string? name) => + new DiagController(context.RequestServices, logger).GetProcessEnvironment(pid, uid, name)) + .WithName(nameof(GetProcessEnvironment)) + .RequireDiagControllerCommon() + .Produces>(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // CaptureDump + builder.MapGet("dump", ( + HttpContext context, + ILogger logger, + int? pid, + Guid? uid, + string? name, + Models.DumpType type = Models.DumpType.WithHeap, + string? egressProvider = null, + string? tags = null) => + new DiagController(context.RequestServices, logger).CaptureDump(pid, uid, name, type, egressProvider, tags)) + .WithName(nameof(CaptureDump)) + .RequireDiagControllerCommon() + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CapturGcDump + builder.MapGet("gcdump", ( + HttpContext context, + ILogger logger, + int? pid, + Guid? uid, + string? name, + string? egressProvider, + string? tags) => + new DiagController(context.RequestServices, logger).CaptureGcDump(pid, uid, name, egressProvider, tags)) + .WithName(nameof(CaptureGcDump)) + .RequireDiagControllerCommon() + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureTrace + builder.MapGet("trace", ( + HttpContext context, + ILogger logger, + int? pid, + Guid? uid, + string? name, + TraceProfile profile = DefaultTraceProfiles, + [Range(-1, int.MaxValue)] + int durationSeconds = 30, + string? egressProvider = null, + string? tags = null) => + new DiagController(context.RequestServices, logger).CaptureTrace(pid, uid, name, profile, durationSeconds, egressProvider, tags)) + .WithName(nameof(CaptureTrace)) + .RequireDiagControllerCommon() + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureTraceCustom + builder.MapGet("trace", ( + HttpContext context, + ILogger logger, + [FromBody][Required] + EventPipeConfiguration configuration, + int? pid, + Guid? uid, + string? name, + [Range(-1, int.MaxValue)] + int durationSeconds = 30, + string? egressProvider = null, + string? tags = null) => + new DiagController(context.RequestServices, logger).CaptureTraceCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + .WithName(nameof(CaptureTraceCustom)) + .RequireDiagControllerCommon() + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureLogs + builder.MapGet("logs", ( + HttpContext context, + ILogger logger, + int? pid, + Guid? uid, + string? name, + [Range(-1, int.MaxValue)] + int durationSeconds = 30, + LogLevel? level = null, + string? egressProvider = null, + string? tags = null) => + new DiagController(context.RequestServices, logger).CaptureLogs(pid, uid, name, durationSeconds, level, egressProvider, tags)) + .WithName(nameof(CaptureLogs)) + .RequireDiagControllerCommon() + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureLogsCustom + builder.MapPost("logs", ( + HttpContext context, + ILogger logger, + [FromBody] + LogsConfiguration configuration, + int? pid, + Guid? uid, + string? name, + [Range(-1, int.MaxValue)] + int durationSeconds = 30, + string? egressProvider = null, + string? tags = null) => + new DiagController(context.RequestServices, logger).CaptureLogsCustom(configuration, pid, uid, name, durationSeconds, egressProvider, tags)) + .WithName(nameof(CaptureLogs)) + .RequireDiagControllerCommon() + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // GetInfo + builder.MapGet("info", ( + HttpContext context, + ILogger logger) => + new DiagController(context.RequestServices, logger).GetInfo()) + .WithName(nameof(GetInfo)) + .RequireDiagControllerCommon() + .Produces(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // GetCollectionRulesDescription + builder.MapGet("collectionrules", ( + HttpContext context, + ILogger logger, + int pid, + Guid uid, + string name) => + new DiagController(context.RequestServices, logger).GetCollectionRulesDescription(pid, uid, name)) + .WithName(nameof(GetCollectionRulesDescription)) + .RequireDiagControllerCommon() + .Produces>(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // GetCollectionRuleDetailedDescription + builder.MapGet("collectionrules/{collectionRuleName}", ( + HttpContext context, + ILogger logger, + string collectionRuleName, + int pid, + Guid uid, + string name) => + new DiagController(context.RequestServices, logger).GetCollectionRuleDetailedDescription(collectionRuleName, pid, uid, name)) + .WithName(nameof(GetCollectionRuleDetailedDescription)) + .RequireDiagControllerCommon() + .Produces(StatusCodes.Status200OK) + .ProducesProblem(StatusCodes.Status400BadRequest); + + // CaptureParameters + builder.MapPost("parameters", ( + HttpContext context, + ILogger logger, + [FromBody][Required] + CaptureParametersConfiguration configuration, + [Range(-1, int.MaxValue)] + int durationSeconds = 30, + int? pid = null, + Guid? uid = null, + string? name = null, + string? egressProvider = null, + string? tags = null) => + new DiagController(context.RequestServices, logger).CaptureParameters(configuration, durationSeconds, pid, uid, name, egressProvider, tags)) + .WithName(nameof(CaptureParameters)) + .RequireDiagControllerCommon() + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + + // CaptureStacks + builder.MapGet("stacks", ( + HttpContext context, + ILogger logger, + int? pid, + Guid? uid, + string? name, + string? egressProvider, + string? tags) => + new DiagController(context.RequestServices, logger).CaptureStacks(pid, uid, name, egressProvider, tags)) + .WithName(nameof(CaptureStacks)) + .RequireDiagControllerCommon() + .Produces(StatusCodes.Status429TooManyRequests) + .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationJson, ContentTypes.TextPlain, ContentTypes.ApplicationSpeedscopeJson) + .Produces(StatusCodes.Status202Accepted) + .ProducesProblem(StatusCodes.Status400BadRequest) + .RequireEgressValidation(); + } + + /// + /// Get the list of accessible processes. + /// + public Task GetProcesses() + { + return this.InvokeService(async () => + { + IProcessInfo? defaultProcessInfo = null; + try + { + defaultProcessInfo = await DiagnosticServices.GetProcessAsync(null, HttpContext.RequestAborted); + } + catch (ArgumentException) + { + // Unable to locate a default process; no action required + } + catch (InvalidOperationException) + { + } + catch (Exception ex) when (!(ex is OperationCanceledException)) + { + Logger.DefaultProcessUnexpectedFailure(ex); + } + + IList processesIdentifiers = new List(); + foreach (IProcessInfo p in await DiagnosticServices.GetProcessesAsync(processFilter: null, HttpContext.RequestAborted)) + { + processesIdentifiers.Add(new ProcessIdentifier() + { + Pid = p.EndpointInfo.ProcessId, + Uid = p.EndpointInfo.RuntimeInstanceCookie, + Name = p.ProcessName, + IsDefault = (defaultProcessInfo != null && + p.EndpointInfo.ProcessId == defaultProcessInfo.EndpointInfo.ProcessId && + p.EndpointInfo.RuntimeInstanceCookie == defaultProcessInfo.EndpointInfo.RuntimeInstanceCookie) + }); + } + Logger.WrittenToHttpStream(); + return TypedResults.Ok(processesIdentifiers); + }, Logger); + } + + /// + /// Get information about the specified process. + /// + /// Process ID used to identify the target process. + /// The Runtime instance cookie used to identify the target process. + /// Process name used to identify the target process. + public Task GetProcessInfo( + int? pid, + Guid? uid, + string? name) + { + ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); + + return InvokeForProcess(processInfo => + { + Models.ProcessInfo processModel = new Models.ProcessInfo() + { + CommandLine = processInfo.CommandLine, + Name = processInfo.ProcessName, + OperatingSystem = processInfo.OperatingSystem, + ProcessArchitecture = processInfo.ProcessArchitecture, + Pid = processInfo.EndpointInfo.ProcessId, + Uid = processInfo.EndpointInfo.RuntimeInstanceCookie + }; + + Logger.WrittenToHttpStream(); + + return TypedResults.Ok(processModel); + }, + processKey); + } + + /// + /// Get the environment block of the specified process. + /// + /// Process ID used to identify the target process. + /// The Runtime instance cookie used to identify the target process. + /// Process name used to identify the target process. + public Task GetProcessEnvironment( + int? pid, + Guid? uid, + string? name) + { + ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); + + return InvokeForProcess>>(async processInfo => + { + var client = new DiagnosticsClient(processInfo.EndpointInfo.Endpoint); + + try + { + Dictionary environment = await client.GetProcessEnvironmentAsync(HttpContext.RequestAborted); + + Logger.WrittenToHttpStream(); + + return TypedResults.Ok(environment); + } + catch (ServerErrorException) + { + throw new InvalidOperationException(Strings.ErrorMessage_CanNotGetEnvironment); + } + }, + processKey); + } + + /// + /// Capture a dump of a process. + /// + /// Process ID used to identify the target process. + /// The Runtime instance cookie used to identify the target process. + /// Process name used to identify the target process. + /// The type of dump to capture. + /// The egress provider to which the dump is saved. + /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + /// + // FileResult is the closest representation of the output so that the OpenAPI document correctly + // describes the result as a binary file. + public Task CaptureDump( + int? pid, + Guid? uid, + string? name, + Models.DumpType type, + string? egressProvider, + string? tags) + { + ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); + + return InvokeForProcess( + processInfo => Result( + Utilities.ArtifactType_Dump, + egressProvider, + _dumpOperationFactory.Create(processInfo.EndpointInfo, type), + processInfo, + tags), + processKey, + Utilities.ArtifactType_Dump); + } + + /// + /// Capture a GC dump of a process. + /// + /// Process ID used to identify the target process. + /// The Runtime instance cookie used to identify the target process. + /// Process name used to identify the target process. + /// The egress provider to which the GC dump is saved. + /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + /// + // FileResult is the closest representation of the output so that the OpenAPI document correctly + // describes the result as a binary file. + public Task CaptureGcDump( + int? pid, + Guid? uid, + string? name, + string? egressProvider, + string? tags) + { + ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); + + return InvokeForProcess( + processInfo => Result( + Utilities.ArtifactType_GCDump, + egressProvider, + _gcdumpOperationFactory.Create(processInfo.EndpointInfo), + processInfo, + tags), + processKey, + Utilities.ArtifactType_GCDump); + } + + /// + /// Capture a trace of a process. + /// + /// Process ID used to identify the target process. + /// The Runtime instance cookie used to identify the target process. + /// Process name used to identify the target process. + /// The profiles enabled for the trace session. + /// The duration of the trace session (in seconds). + /// The egress provider to which the trace is saved. + /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + // FileResult is the closest representation of the output so that the OpenAPI document correctly + // describes the result as a binary file. + public Task CaptureTrace( + int? pid, + Guid? uid, + string? name, + TraceProfile profile, + int durationSeconds, + string? egressProvider, + string? tags) + { + ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); + + return InvokeForProcess(processInfo => + { + TimeSpan duration = Utilities.ConvertSecondsToTimeSpan(durationSeconds); + + var aggregateConfiguration = TraceUtilities.GetTraceConfiguration(profile, _counterOptions.CurrentValue); + + return StartTrace(processInfo, aggregateConfiguration, duration, egressProvider, tags); + }, processKey, Utilities.ArtifactType_Trace); + } + + /// + /// Capture a trace of a process. + /// + /// The trace configuration describing which events to capture. + /// Process ID used to identify the target process. + /// The Runtime instance cookie used to identify the target process. + /// Process name used to identify the target process. + /// The duration of the trace session (in seconds). + /// The egress provider to which the trace is saved. + /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + // FileResult is the closest representation of the output so that the OpenAPI document correctly + // describes the result as a binary file. + public Task CaptureTraceCustom( + EventPipeConfiguration configuration, + int? pid, + Guid? uid, + string? name, + int durationSeconds, + string? egressProvider, + string? tags) + { + ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); + + return InvokeForProcess(processInfo => + { + foreach (Models.EventPipeProvider provider in configuration.Providers) + { + if (!CounterValidator.ValidateProvider(_counterOptions.CurrentValue, + provider, out string? errorMessage)) + { + throw new ValidationException(errorMessage); + } + } + + TimeSpan duration = Utilities.ConvertSecondsToTimeSpan(durationSeconds); + + var traceConfiguration = TraceUtilities.GetTraceConfiguration(configuration.Providers, configuration.RequestRundown, configuration.BufferSizeInMB); + + return StartTrace(processInfo, traceConfiguration, duration, egressProvider, tags); + }, processKey, Utilities.ArtifactType_Trace); + } + + /// + /// Capture a stream of logs from a process. + /// + /// Process ID used to identify the target process. + /// The Runtime instance cookie used to identify the target process. + /// Process name used to identify the target process. + /// The duration of the logs session (in seconds). + /// The level of the logs to capture. + /// The egress provider to which the logs are saved. + /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + public Task CaptureLogs( + int? pid, + Guid? uid, + string? name, + int durationSeconds, + LogLevel? level, + string? egressProvider, + string? tags) + { + ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); + + return InvokeForProcess(processInfo => + { + TimeSpan duration = Utilities.ConvertSecondsToTimeSpan(durationSeconds); + + var settings = new EventLogsPipelineSettings() + { + Duration = duration + }; + + // Use log level query parameter if specified, otherwise use application-defined filters. + if (level.HasValue) + { + settings.LogLevel = level.Value; + settings.UseAppFilters = false; + } + else + { + settings.UseAppFilters = true; + } + + return StartLogs(processInfo, settings, egressProvider, tags); + }, processKey, Utilities.ArtifactType_Logs); + } + + /// + /// Capture a stream of logs from a process. + /// + /// The logs configuration describing which logs to capture. + /// Process ID used to identify the target process. + /// The Runtime instance cookie used to identify the target process. + /// Process name used to identify the target process. + /// The duration of the logs session (in seconds). + /// The egress provider to which the logs are saved. + /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + public Task CaptureLogsCustom( + LogsConfiguration configuration, + int? pid, + Guid? uid, + string? name, + int durationSeconds, + string? egressProvider, + string? tags) + { + ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); + + return InvokeForProcess(processInfo => + { + TimeSpan duration = Utilities.ConvertSecondsToTimeSpan(durationSeconds); + + var settings = new EventLogsPipelineSettings() + { + Duration = duration, + FilterSpecs = configuration.FilterSpecs, + LogLevel = configuration.LogLevel, + UseAppFilters = configuration.UseAppFilters + }; + + return StartLogs(processInfo, settings, egressProvider, tags); + }, processKey, Utilities.ArtifactType_Logs); + } + + /// + /// Gets versioning and listening mode information about Dotnet-Monitor + /// + public IResult GetInfo() + { + return this.InvokeService(() => + { + string? version = Assembly.GetExecutingAssembly().GetInformationalVersionString(); + string runtimeVersion = Environment.Version.ToString(); + DiagnosticPortConnectionMode diagnosticPortMode = _diagnosticPortOptions.Value.GetConnectionMode(); + string? diagnosticPortName = GetDiagnosticPortName(); + + DotnetMonitorInfo dotnetMonitorInfo = new() + { + Version = version, + RuntimeVersion = runtimeVersion, + DiagnosticPortMode = diagnosticPortMode, + DiagnosticPortName = diagnosticPortName + }; + + Logger.WrittenToHttpStream(); + return TypedResults.Ok(dotnetMonitorInfo); + }, Logger); + } + + /// + /// Gets a brief summary about the current state of the collection rules. + /// + /// Process ID used to identify the target process. + /// The Runtime instance cookie used to identify the target process. + /// Process name used to identify the target process. + public Task GetCollectionRulesDescription( + int? pid, + Guid? uid, + string? name) + { + return InvokeForProcess>>(processInfo => + { + return TypedResults.Ok(_collectionRuleService.GetCollectionRulesDescriptions(processInfo.EndpointInfo)); + }, + Utilities.GetProcessKey(pid, uid, name)); + } + + /// + /// Gets detailed information about the current state of the specified collection rule. + /// + /// The name of the collection rule for which a detailed description should be provided. + /// Process ID used to identify the target process. + /// The Runtime instance cookie used to identify the target process. + /// Process name used to identify the target process. + public Task GetCollectionRuleDetailedDescription( + string collectionRuleName, + int? pid, + Guid? uid, + string? name) + { + return InvokeForProcess>(processInfo => + { + return TypedResults.Ok(_collectionRuleService.GetCollectionRuleDetailedDescription(collectionRuleName, processInfo.EndpointInfo)); + }, + Utilities.GetProcessKey(pid, uid, name)); + } + + public async Task CaptureParameters( + CaptureParametersConfiguration configuration, + int durationSeconds, + int? pid, + Guid? uid, + string? name, + string? egressProvider, + string? tags) + { + if (!_parameterCapturingOptions.Value.GetEnabled()) + { + return this.FeatureNotEnabled(Strings.FeatureName_ParameterCapturing); + } + + ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); + TimeSpan duration = Utilities.ConvertSecondsToTimeSpan(durationSeconds); + + return await InvokeForProcess(processInfo => + { + CapturedParameterFormat format = ContentTypeUtilities.ComputeCapturedParameterFormat(Request.GetTypedHeaders().Accept) ?? CapturedParameterFormat.JsonSequence; + + IArtifactOperation operation = _captureParametersFactory.Create(processInfo.EndpointInfo, configuration, duration, format); + + return Result( + Utilities.ArtifactType_Parameters, + egressProvider, + operation, + processInfo, + tags, + format != CapturedParameterFormat.PlainText); + }, processKey, Utilities.ArtifactType_Parameters); + } + + public Task CaptureStacks( + int? pid, + Guid? uid, + string? name, + string? egressProvider, + string? tags) + { + if (!_callStacksOptions.Value.GetEnabled()) + { + return Task.FromResult(this.FeatureNotEnabled(Strings.FeatureName_CallStacks)); + } + + ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); + + return InvokeForProcess(processInfo => + { + //Stack format based on Content-Type + + StackFormat stackFormat = ContentTypeUtilities.ComputeStackFormat(Request.GetTypedHeaders().Accept) ?? StackFormat.PlainText; + + IArtifactOperation operation = _stacksOperationFactory.Create(processInfo.EndpointInfo, stackFormat); + + return Result( + Utilities.ArtifactType_Stacks, + egressProvider, + operation, + processInfo, + tags); + }, processKey, Utilities.ArtifactType_Stacks); + } + + private string? GetDiagnosticPortName() + { + return _diagnosticPortOptions.Value.EndpointName; + } + + private Task StartTrace( + IProcessInfo processInfo, + MonitoringSourceConfiguration configuration, + TimeSpan duration, + string? egressProvider, + string? tags) + { + IArtifactOperation traceOperation = _traceOperationFactory.Create( + processInfo.EndpointInfo, + configuration, + duration); + + return Result( + Utilities.ArtifactType_Trace, + egressProvider, + traceOperation, + processInfo, + tags); + } + + private Task StartLogs( + IProcessInfo processInfo, + EventLogsPipelineSettings settings, + string? egressProvider, + string? tags) + { + LogFormat? format = ComputeLogFormat(Request.GetTypedHeaders().Accept); + if (null == format) + { + return Task.FromResult(this.NotAcceptable()); + } + + // Allow sync I/O on logging routes due to StreamLogger's usage. + HttpContext.AllowSynchronousIO(); + + IArtifactOperation logsOperation = _logsOperationFactory.Create( + processInfo.EndpointInfo, + settings, + format.Value); + + return Result( + Utilities.ArtifactType_Logs, + egressProvider, + logsOperation, + processInfo, + tags, + format != LogFormat.PlainText); + } + + private static LogFormat? ComputeLogFormat(IList acceptedHeaders) + { + if (acceptedHeaders == null || acceptedHeaders.Count == 0) + { + return null; + } + + if (acceptedHeaders.Contains(ContentTypeUtilities.TextPlainHeader)) + { + return LogFormat.PlainText; + } + if (acceptedHeaders.Contains(ContentTypeUtilities.NdJsonHeader)) + { + return LogFormat.NewlineDelimitedJson; + } + if (acceptedHeaders.Contains(ContentTypeUtilities.JsonSequenceHeader)) + { + return LogFormat.JsonSequence; + } + if (acceptedHeaders.Any(ContentTypeUtilities.TextPlainHeader.IsSubsetOf)) + { + return LogFormat.PlainText; + } + if (acceptedHeaders.Any(ContentTypeUtilities.NdJsonHeader.IsSubsetOf)) + { + return LogFormat.NewlineDelimitedJson; + } + if (acceptedHeaders.Any(ContentTypeUtilities.JsonSequenceHeader.IsSubsetOf)) + { + return LogFormat.JsonSequence; + } + return null; + } + } +} diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs index ba72770f418..8c0df2971fa 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs @@ -13,6 +13,7 @@ using Microsoft.Net.Http.Headers; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Threading.Tasks; @@ -25,7 +26,8 @@ public static RouteHandlerBuilder RequireExceptionsControllerCommon(this RouteHa return builder .RequireHostRestriction() .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson); + .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) + .WithTags("Exceptions"); } } @@ -45,15 +47,16 @@ public ExceptionsController( public static void MapActionMethods(IEndpointRouteBuilder builder) { // GetExceptions - builder.MapGet("exceptions", ( - IServiceProvider serviceProvider, + builder.MapGet("exceptions", + [EndpointSummary("Gets the exceptions from the target process.")] ( + HttpContext context, ILogger logger, - int? pid, - Guid? uid, - string? name, - string? egressProvider = null, - string? tags = null) => - new ExceptionsController(serviceProvider, logger).GetExceptions(pid, uid, name, egressProvider, tags)) + [Description("Process ID used to identify the target process.")] int? pid, + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [Description("Process name used to identify the target process.")] string? name, + [Description("The egress provider to which the exceptions are saved.")] string? egressProvider = null, + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) => + new ExceptionsController(context.RequestServices, logger).GetExceptions(pid, uid, name, egressProvider, tags)) .WithName(nameof(GetExceptions)) .RequireExceptionsControllerCommon() .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) @@ -62,21 +65,23 @@ public static void MapActionMethods(IEndpointRouteBuilder builder) .RequireEgressValidation(); // CaptureExceptionsCustom - builder.MapPost("exceptions", ( - IServiceProvider serviceProvider, + builder.MapPost("exceptions", + [EndpointSummary("Gets the exceptions from the target process.")] ( + HttpContext context, ILogger logger, - [FromBody] + [FromBody, Description("The exceptions configuration describing which exceptions to include in the response.")] ExceptionsConfiguration configuration, - int? pid, - Guid? uid, - string? name, - string? egressProvider = null, - string? tags = null) => - new ExceptionsController(serviceProvider, logger).CaptureExceptionsCustom(configuration, pid, uid, name, egressProvider, tags)) + [Description("Process ID used to identify the target process.")] int? pid, + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [Description("Process name used to identify the target process.")] string? name, + [Description("The egress provider to which the exceptions are saved.")] string? egressProvider = null, + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) => + new ExceptionsController(context.RequestServices, logger).CaptureExceptionsCustom(configuration, pid, uid, name, egressProvider, tags)) .WithName(nameof(CaptureExceptionsCustom)) .RequireExceptionsControllerCommon() .Produces(StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain) .ProducesProblem(StatusCodes.Status400BadRequest) + .Accepts(ContentTypes.ApplicationJson, ContentTypes.TextJson, ContentTypes.ApplicationAnyJson) .RequireEgressValidation(); } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs index 16fe6185330..277bd8fc5d6 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs @@ -32,15 +32,17 @@ public MetricsController(ILogger logger, public static void MapActionMethods(IEndpointRouteBuilder builder) { // GetMetrics - builder.MapGet("metrics", ( + builder.MapGet("metrics", + [EndpointSummary("Get a list of the current backlog of metrics for a process in the Prometheus exposition format.")] ( ILogger logger, - IServiceProvider serviceProvider, + HttpContext context, IOptions metricsOptions) => - new MetricsController(logger, serviceProvider, metricsOptions).GetMetrics()) + new MetricsController(logger, context.RequestServices, metricsOptions).GetMetrics()) .WithName(nameof(GetMetrics)) .Produces(StatusCodes.Status400BadRequest, ContentTypes.ApplicationProblemJson) .Produces(StatusCodes.Status200OK, ContentTypes.TextPlain_v0_0_4) - .ProducesProblem(StatusCodes.Status400BadRequest); + .ProducesProblem(StatusCodes.Status400BadRequest) + .WithTags("Metrics"); } /// diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs index cdbdc9a3b8c..bc3459d6eeb 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; +using System.ComponentModel; namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { @@ -21,7 +22,8 @@ public static RouteHandlerBuilder RequireOperationsControllerCommon(this RouteHa return builder .RequireHostRestriction() .RequireAuthorization(AuthConstants.PolicyName) - .Produces(StatusCodes.Status401Unauthorized); + .Produces(StatusCodes.Status401Unauthorized) + .WithTags("Operations"); } } @@ -38,39 +40,41 @@ public OperationsController(ILogger logger, IServiceProvid _operationsStore = serviceProvider.GetRequiredService(); } + // Todo: use MapGroup! + // Factor out. public static void MapActionMethods(IEndpointRouteBuilder builder) { // GetOperations - builder.MapGet($"{ControllerName}/{nameof(GetOperations)}", ( + builder.MapGet($"{ControllerName}", [EndpointSummary("Gets the operations list for the specified process (or all processes if left unspecified).")] ( + HttpContext context, ILogger logger, - IServiceProvider serviceProvider, - int? pid, - Guid? uid, - string? name, - string? tags) => - new OperationsController(logger, serviceProvider).GetOperations(pid, uid, name, tags)) + [Description("Process ID used to identify the target process.")] int? pid, + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid, + [Description("Process name used to identify the target process.")] string? name, + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags) => + new OperationsController(logger, context.RequestServices).GetOperations(pid, uid, name, tags)) .WithName(nameof(GetOperations)) .RequireOperationsControllerCommon() .Produces>(StatusCodes.Status200OK); // GetOperationStatus - builder.MapGet($"{ControllerName}/{nameof(GetOperationStatus)}/{{operationId}}", ( + builder.MapGet($"{ControllerName}/{{operationId}}", ( + HttpContext context, ILogger logger, - IServiceProvider serviceProvider, Guid operationId) => - new OperationsController(logger, serviceProvider).GetOperationStatus(operationId)) + new OperationsController(logger, context.RequestServices).GetOperationStatus(operationId)) .WithName(nameof(GetOperationStatus)) .RequireOperationsControllerCommon() .Produces(StatusCodes.Status200OK) .Produces(StatusCodes.Status201Created); // CancelOperation - builder.MapDelete($"{ControllerName}/{nameof(CancelOperation)}/{{operationId}}", ( + builder.MapDelete($"{ControllerName}/{{operationId}}", ( + HttpContext context, ILogger logger, - IServiceProvider serviceProvider, Guid operationId, bool stop = false) => - new OperationsController(logger, serviceProvider).CancelOperation(operationId, stop)) + new OperationsController(logger, context.RequestServices).CancelOperation(operationId, stop)) .WithName(nameof(CancelOperation)) .RequireOperationsControllerCommon() .Produces(StatusCodes.Status200OK) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Metrics/JsonCounterLogger.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Metrics/JsonCounterLogger.cs index c3cc4da5b2d..0b721433aa2 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Metrics/JsonCounterLogger.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Metrics/JsonCounterLogger.cs @@ -109,7 +109,7 @@ protected override async Task SerializeAsync(ICounterPayload counter) private void SerializeCounterValues( DateTime timestamp, - string provider, + string provider, // or here? string name, string displayName, string unit, diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Metrics/MetricsStore.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Metrics/MetricsStore.cs index 57f37690e4d..b70ecc53210 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Metrics/MetricsStore.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Metrics/MetricsStore.cs @@ -50,7 +50,7 @@ public override bool Equals(object? obj) private ILogger _logger; private HashSet _observedErrorMessages = new(); - private HashSet<(string provider, string counter)> _observedEndedCounters = new(); + private HashSet<(string provider, string counter)> _observedEndedCounters = new(); // maybe? public MetricsStore(ILogger logger, int maxMetricCount) { diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDescription.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDescription.cs index 141163004d5..f3990b2f757 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDescription.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDescription.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Text.Json.Serialization; +using System.ComponentModel; namespace Microsoft.Diagnostics.Monitoring.WebApi.Models { @@ -17,6 +18,7 @@ public record class CollectionRuleDescription /// Human-readable explanation for the current state of the collection rule. /// [JsonPropertyName("stateReason")] + [Description("Human-readable explanation for the current state of the collection rule.")] public string? StateReason { get; set; } } } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDetailedDescription.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDetailedDescription.cs index 744314e1f53..2e7f6dbc171 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDetailedDescription.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDetailedDescription.cs @@ -3,6 +3,7 @@ using System; using System.Text.Json.Serialization; +using System.ComponentModel; namespace Microsoft.Diagnostics.Monitoring.WebApi.Models { @@ -12,36 +13,42 @@ public record class CollectionRuleDetailedDescription : CollectionRuleDescriptio /// The number of times the trigger has executed for a process in its lifetime. /// [JsonPropertyName("lifetimeOccurrences")] + [Description("The number of times the trigger has executed for a process in its lifetime.")] public int LifetimeOccurrences { get; set; } /// /// The number of times the trigger has executed for a process in the current sliding window duration (as defined by Limits). /// [JsonPropertyName("slidingWindowOccurrences")] + [Description("The number of times the trigger has executed for a process in the current sliding window duration (as defined by Limits).")] public int SlidingWindowOccurrences { get; set; } /// /// The number of times the trigger can execute for a process before being limited (as defined by Limits). /// [JsonPropertyName("actionCountLimit")] + [Description("The number of times the trigger can execute for a process before being limited (as defined by Limits).")] public int ActionCountLimit { get; set; } /// /// The sliding window duration in which the actionCountLimit is the maximum number of occurrences (as defined by Limits). /// [JsonPropertyName("actionCountSlidingWindowDurationLimit")] + [Description("The sliding window duration in which the actionCountLimit is the maximum number of occurrences (as defined by Limits).")] public TimeSpan? ActionCountSlidingWindowDurationLimit { get; set; } /// /// The amount of time that needs to pass before the slidingWindowOccurrences drops below the actionCountLimit /// [JsonPropertyName("slidingWindowDurationCountdown")] + [Description("The amount of time that needs to pass before the slidingWindowOccurrences drops below the actionCountLimit")] public TimeSpan? SlidingWindowDurationCountdown { get; set; } /// /// The amount of time that needs to pass before the rule is finished /// [JsonPropertyName("ruleFinishedCountdown")] + [Description("The amount of time that needs to pass before the rule is finished")] public TimeSpan? RuleFinishedCountdown { get; set; } } } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Validation/CounterValidator.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Validation/CounterValidator.cs index 74d747c3c02..99bb4456404 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Validation/CounterValidator.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Validation/CounterValidator.cs @@ -10,7 +10,7 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Validation internal static class CounterValidator { public static bool ValidateProvider(GlobalCounterOptions counterOptions, - EventPipeProvider provider, + EventPipeProvider provider, // or here? [NotNullWhen(false)] out string? errorMessage) { errorMessage = null; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj index 5668a50b1c6..06fea193981 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj @@ -3,10 +3,17 @@ Exe $(ToolTargetFrameworks) + ../../../documentation + --file-name openapi + + + + + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Program.cs index 41ee7d2f2cd..84cab8fb2e9 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Program.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Program.cs @@ -1,15 +1,20 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.Auth; -using Microsoft.Diagnostics.Tools.Monitor.Swagger; +using Microsoft.Diagnostics.Tools.Monitor.OpenApi; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Swashbuckle.AspNetCore.Swagger; -using System; -using System.Globalization; -using System.IO; +using Microsoft.Extensions.Options; +using Microsoft.Diagnostics.Monitoring.WebApi; +// using Swashbuckle.AspNetCore.Swagger; +// using System; +// using System.Globalization; +// using System.IO; namespace Microsoft.Diagnostics.Monitoring.OpenApiGen { @@ -17,14 +22,14 @@ internal sealed class Program { public static void Main(string[] args) { - if (args.Length != 1) - { - throw new InvalidOperationException("Expected single argument for the output path."); - } - string outputPath = args[0]; + // if (args.Length != 1) + // { + // throw new InvalidOperationException("Expected single argument for the output path."); + // } + // string outputPath = args[0]; // Create directory if it does not exist - Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); + // Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); HostBuilderSettings settings = HostBuilderSettings.CreateMonitor( urls: null, @@ -41,18 +46,30 @@ public static void Main(string[] args) .CreateHostBuilder(settings) .ConfigureServices(services => { - services.AddSwaggerGen(options => options.ConfigureMonitorSwaggerGen()); + // services.AddSwaggerGen(options => options.ConfigureMonitorSwaggerGen()); + services.AddOpenApi(options => options.ConfigureMonitorOpenApiGen()); }) .Build(); + var config = host.Services.GetRequiredService(); + var startup = new Startup(config); + var appBuilder = new ApplicationBuilder(host.Services); + var env = host.Services.GetRequiredService(); + var corsOptions = host.Services.GetRequiredService>(); + Startup.Configure(appBuilder, env, corsOptions); + + // Necessary to call Configure, which does MapOpenApi. + // Run the app! + // host.Run(); + // Serialize the OpenApi document - using StringWriter outputWriter = new(CultureInfo.InvariantCulture); - ISwaggerProvider provider = host.Services.GetRequiredService(); - provider.WriteTo(outputWriter); - outputWriter.Flush(); + // using StringWriter outputWriter = new(CultureInfo.InvariantCulture); + // ISwaggerProvider provider = host.Services.GetRequiredService(); + // provider.WriteTo(outputWriter); + // outputWriter.Flush(); - // Normalize line endings before writing - File.WriteAllText(outputPath, outputWriter.ToString().Replace("\r\n", "\n")); + // Normalize line endings before writinge + // File.WriteAllText(outputPath, outputWriter.ToString().Replace("\r\n", "\n")); } } } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/getvsdbgsh b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/getvsdbgsh new file mode 100644 index 00000000000..ece5d6a159d --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/getvsdbgsh @@ -0,0 +1,570 @@ +#!/bin/sh + +# Copyright (c) Microsoft. All rights reserved. + +# Working dirctory to return to +__InitialCWD=$(pwd) + +# Location of the script +__ScriptDirectory= + +# VsDbg Meta Version. It could be something like 'latest', 'vs2022', 'vs2019', 'vsfm-8', 'vs2017u5', or a fully specified version. +__VsDbgMetaVersion= + +# Install directory of the vsdbg relative to the script. +__InstallLocation= + +# When SkipDownloads is set to true, no access to internet is made. +__SkipDownloads=false + +# Launches VsDbg after downloading/upgrading. +__LaunchVsDbg=false + +# Mode used to launch vsdbg. +__VsDbgMode= + +# Removes existing installation of VsDbg in the Install Location. +__RemoveExistingOnUpgrade=false + +# Internal, fully specified version of the VsDbg. Computed when the meta version is used. +__VsDbgVersion= + +__ExactVsDbgVersionUsed=false + +# RuntimeID of dotnet +__RuntimeID= + +# Alternative location of installed debugger +__AltInstallLocation= + +# Whether to use the alternate location version of the debugger. This is set after verifying the version is up-to-date. +__UseAltDebuggerLocation=false + +# Flag to indicate that we will have to download the zip version and extract it as a zip. +__UseZip=false + +# Flag to indicate that we support offline installation and will report with a structured error message. +__OfflineMode=false + +GetVsDbgShDataPrefix="GetVsDbgShData:" + +__VsdbgCompressedFile= + +# Echo a message and exit with a failure +fail() +{ + echo + echo "$1" + exit 1 +} + +# Gets the script directory +get_script_directory() +{ + scriptDirectory=$(dirname "$0") + cd "$scriptDirectory" || fail "Command failed: 'cd \"$scriptDirectory\"'" + __ScriptDirectory=$(pwd) + cd "$__InitialCWD" || fail "Command failed: 'cd \"$__InitialCWD\"'" +} + +print_help() +{ + echo 'GetVsDbg.sh [-usho] -v V [-l L] [-r R] [-d M] [-e E]' + echo '' + echo 'This script downloads and configures vsdbg, the Cross Platform .NET Debugger' + echo '-u Deletes the existing installation directory of the debugger before installing the current version.' + echo '-s Skips any steps which requires downloading from the internet.' + echo '-d M Launches debugger after the script completion. Where M is the mode, "mi" or "vscode"' + echo '-h Prints usage information.' + echo '-v V Version V can be "latest" or a version number such as 15.0.25930.0' + echo '-l L Location L where the debugger should be installed. Can be absolute or relative' + echo '-r R Debugger for the RuntimeID will be installed' + echo '-a A Specify a different alternate location that the debugger might already be installed.' + echo '-o Enables "Offline Mode" This enables structured output to use if the current machine does not have access to internet.' + echo '-e E E is the full path to the compressed package obtained from outside of the script.' + echo '' + echo 'For more information about using this script with Visual Studio Code see:' + echo 'https://github.com/OmniSharp/omnisharp-vscode/wiki/Attaching-to-remote-processes' + echo '' + echo 'For more information about using this script with Visual Studio see:' + echo 'https://github.com/Microsoft/MIEngine/wiki/Offroad-Debugging-of-.NET-Core-on-Linux---OSX-from-Visual-Studio' + echo '' + echo 'To report issues, see:' + echo 'https://github.com/omnisharp/omnisharp-vscode/issues' +} + +get_dotnet_runtime_id() +{ + if [ "$(uname)" = "Darwin" ]; then + if [ "$(uname -m)" = "arm64" ]; then + __RuntimeID=osx-arm64 + else + __RuntimeID=osx-x64 + fi + elif [ "$(uname -m)" = "x86_64" ]; then + __RuntimeID=linux-x64 + if [ -e /etc/os-release ]; then + # '.' is the same as 'source' but is POSIX compliant + . /etc/os-release + if [ "$ID" = "alpine" ]; then + __RuntimeID=linux-musl-x64 + fi + fi + elif [ "$(uname -m)" = "armv7l" ]; then + __RuntimeID=linux-arm + elif [ "$(uname -m)" = "aarch64" ]; then + __RuntimeID=linux-arm64 + if [ -e /etc/os-release ]; then + # '.' is the same as 'source' but is POSIX compliant + . /etc/os-release + if [ "$ID" = "alpine" ]; then + __RuntimeID=linux-musl-arm64 + # Check to see if we have dpkg to get the real architecture on debian based linux OS. + elif hash dpkg 2>/dev/null; then + # Raspbian 32-bit will return aarch64 in 'uname -m', but it can only use the linux-arm debugger + if [ "$(dpkg --print-architecture)" = "armhf" ]; then + echo 'Info: Overriding Runtime ID from linux-arm64 to linux-arm' + __RuntimeID=linux-arm + fi + fi + fi + fi +} + +remap_runtime_id() +{ + case "$__RuntimeID" in + "debian.8-x64"|"rhel.7.2-x64"|"centos.7-x64"|"fedora.23-x64"|"opensuse.13.2-x64"|"ubuntu.14.04-x64"|"ubuntu.16.04-x64"|"ubuntu.16.10-x64"|"fedora.24-x64"|"opensuse.42.1-x64") + __RuntimeID=linux-x64 + ;; + *) + ;; + esac +} + +# Parses and populates the arguments +parse_and_get_arguments() +{ + while getopts "v:l:r:d:a:suhoe:" opt; do + case $opt in + v) + __VsDbgMetaVersion=$OPTARG; + ;; + l) + __InstallLocation=$OPTARG + # Subdirectories under '~/.vs-debugger' should always be safe to remove + case $__InstallLocation in + "$HOME/.vs-debugger/"*) + __RemoveExistingOnUpgrade=true + ;; + esac + ;; + u) + __RemoveExistingOnUpgrade=true + ;; + s) + __SkipDownloads=true + ;; + d) + __LaunchVsDbg=true + __VsDbgMode=$OPTARG + ;; + r) + __RuntimeID=$OPTARG + ;; + a) + __AltInstallLocation=$OPTARG + ;; + h) + print_help + exit 1 + ;; + o) + __OfflineMode=true + ;; + e) + __VsdbgCompressedFile=$OPTARG + + # Convert to absolute path. If `cd` fails, `pwd` will not run and the subshell will exit with 1. + __VsDbgCompressedFullPath=$(cd "$(dirname "$__VsdbgCompressedFile")" || fail "Command Failed: 'cd \"\$(dirname \"$__VsdbgCompressedFile\")\"'" ; pwd) 2>/dev/null + + # `cd` will fail within the subshell and exit with 1. + if [ $? -eq 0 ]; then + __VsdbgCompressedFile="$__VsDbgCompressedFullPath/$(basename "$__VsdbgCompressedFile")" + else + fail "ERROR: Failed to get the absolute path to $__VsdbgCompressedFile." + fi + + # Test to see we got an existing file. + if [ ! -f "$__VsdbgCompressedFile" ]; then + fail "ERROR: The compressed file path $__VsdbgCompressedFile does not exist." + fi + ;; + \?) + echo "ERROR: Invalid Option: -$OPTARG" + print_help + exit 1; + ;; + :) + echo "ERROR: Option expected for -$OPTARG" + print_help + exit 1 + ;; + esac + done + + if [ -z "$__VsDbgMetaVersion" ]; then + fail "ERROR: Version is not an optional parameter" + fi + + case "$__VsDbgMetaVersion" in + -*) + fail "ERROR: Version should not start with hyphen" + ;; + esac + + case "$__AltInstallLocation" in + -*) + fail "ERROR: Alternate install location should not start with hyphen" + ;; + esac + + if [ -z "$__InstallLocation" ]; then + fail "ERROR: Install location is not an optional parameter" + fi + + case "$__InstallLocation" in + -*) + fail "ERROR: Install location should not start with hyphen" + ;; + esac + + if [ "$__RemoveExistingOnUpgrade" = true ]; then + if [ "$__InstallLocation" = "$__ScriptDirectory" ]; then + fail "ERROR: Cannot remove the directory which has the running script. InstallLocation: $__InstallLocation, ScriptDirectory: $__ScriptDirectory" + fi + + if [ "$__InstallLocation" = "$HOME" ]; then + fail "ERROR: Cannot remove home ( $HOME ) directory." + fi + fi +} + +# Prints the arguments to stdout for the benefit of the user and does a quick sanity check. +print_arguments() +{ + echo "Using arguments" + echo " Version : '$__VsDbgMetaVersion'" + echo " Location : '$__InstallLocation'" + echo " SkipDownloads : '$__SkipDownloads'" + echo " LaunchVsDbgAfter : '$__LaunchVsDbg'" + if [ "$__LaunchVsDbg" = true ]; then + echo " VsDbgMode : '$__VsDbgMode'" + fi + echo " RemoveExistingOnUpgrade : '$__RemoveExistingOnUpgrade'" + if [ "$__OfflineMode" = true ]; then + echo " OfflineMode : '$__OfflineMode'" + fi + if [ -n "$__VsdbgCompressedFile" ]; then + echo " CompressedFileToExtract : '$__VsdbgCompressedFile'" + fi +} + +# Prepares installation directory. +prepare_install_location() +{ + if [ -f "$__InstallLocation" ]; then + fail "ERROR: Path '$__InstallLocation' points to a regular file and not a directory" + elif [ ! -d "$__InstallLocation" ]; then + echo 'Info: Creating install directory' + if ! mkdir -p "$__InstallLocation"; then + fail "ERROR: Unable to create install directory: '$__InstallLocation'" + fi + fi +} + +# Checks if the debugger is already installed in the alternate location. If so, verify the version and if it matches, use it. +verify_and_use_alt_install_location() +{ + if [ -n "$__AltInstallLocation" ] && [ -d "$__AltInstallLocation" ]; then + __AltSuccessFile="$__AltInstallLocation/success_version.txt" + if [ -f "$__AltSuccessFile" ]; then + __AltVersion=$(tr -cd '0-9.' < "$__AltSuccessFile") + echo "Info: Existing debugger install found at $__AltInstallLocation'" + echo " Version : '$__AltVersion'" + if [ "$__VsDbgVersion" = "$__AltVersion" ]; then + __InstallLocation=$__AltInstallLocation + __UseAltDebuggerLocation=true + __SkipDownloads=true + echo "Info: Using debugger found at '$__InstallLocation'" + fi + fi + fi +} + +# Converts relative location of the installation directory to absolute location. +convert_install_path_to_absolute() +{ + if [ -z "$__InstallLocation" ]; then + __InstallLocation=$(pwd) + else + if [ ! -d "$__InstallLocation" ]; then + prepare_install_location + fi + + cd "$__InstallLocation" || fail "Command Failed: 'cd \"$__InstallLocation\"" + __InstallLocation=$(pwd) + cd "$__InitialCWD" || fail "Command Failed: 'cd \"$__InitialCWD\"'" + fi +} + +# Computes the VSDBG version +set_vsdbg_version() +{ + # This case statement is done on the lower case version of version_string + # Add new version constants here + # 'latest' version may be updated + # all other version contstants i.e. 'vs2017u1' or 'vs2017u5' may not be updated after they are finalized + version_string="$(echo "$1" | awk '{print tolower($0)}')" + case "$version_string" in + latest) + __VsDbgVersion=17.13.20213.2 + ;; + vs2022) + __VsDbgVersion=17.13.20213.2 + ;; + vs2019) + __VsDbgVersion=17.13.20213.2 + ;; + vsfm-8) + __VsDbgVersion=17.13.20213.2 + ;; + vs2017u5) + __VsDbgVersion=17.13.20213.2 + ;; + vs2017u1) + __VsDbgVersion="15.1.10630.1" + __UseZip=true + ;; + [0-9]*) + __VsDbgVersion=$1 + __ExactVsDbgVersionUsed=true + + # .tar.gz format is only avaliabe on versions higher than 16.5.20117 + __UseZip=$(echo "$__VsDbgVersion" | tr '-' '.' | awk '{split($0,a,"."); if (a[1] > 16 || (a[1] == 16 && a[2] > 5) || (a[1] == 16 && a[2] == 5 && a[3] > 20117)) {print "false"} else {print "true"};}') + ;; + *) + fail "ERROR: '$1' does not look like a valid version number." + esac +} + +# Removes installation directory if remove option is specified. +process_removal() +{ + if [ "$__RemoveExistingOnUpgrade" = true ]; then + + echo "Info: Attempting to remove '$__InstallLocation'" + + if [ -d "$__InstallLocation" ]; then + wcOutput=$(lsof "$__InstallLocation/vsdbg" | wc -l) + + if [ "$wcOutput" -gt 0 ]; then + fail "ERROR: vsdbg is being used in location '$__InstallLocation'" + fi + + if ! rm -rf "$__InstallLocation"; then + fail "ERROR: files could not be removed from '$__InstallLocation'" + fi + fi + echo "Info: Removed directory '$__InstallLocation'" + else + echo "Info: Cleaning up old files from '$__InstallLocation'." + + # Delete the old success.txt. This should always exist since we just read it. + rm "$__InstallLocation/success.txt" + + # Old files can cause problems if the new vsdbg doesn't contain them. Remove + # the files which may not exist in the new version. + for i in "$__InstallLocation"/*.dll; do + [ -f "$i" ] && rm "$i" + done + for i in "$__InstallLocation"/*.vsdconfig; do + [ -f "$i" ] && rm "$i" + done + for i in "$__InstallLocation"/libSystem.*Native*.so; do + [ -f "$i" ] && rm "$i" + done + for i in "$__InstallLocation"/libSystem.*Native*.dylib; do + [ -f "$i" ] && rm "$i" + done + fi +} + +# Checks if the existing copy is the latest version. +check_latest() +{ + __SuccessFile="$__InstallLocation/success.txt" + if [ -f "$__SuccessFile" ]; then + __LastInstalled=$(cat "$__SuccessFile") + echo "Info: Last installed version of vsdbg is '$__LastInstalled'" + if [ "$__VsDbgVersion" = "$__LastInstalled" ]; then + __SkipDownloads=true + echo "Info: VsDbg is up-to-date" + else + process_removal + fi + else + echo "Info: Previous installation at '$__InstallLocation' not found" + fi +} + +check_internet_connection() +{ + if hash wget 2>/dev/null; then + wget -q --spider "$1" + elif hash curl 2>/dev/null; then + curl -Is "$1" | head -1 | grep 200 + else + if [ "$__OfflineMode" = true ]; then + echo "${GetVsDbgShDataPrefix}URL=$url" + fi + fail "ERROR: Unable to find 'wget' or 'curl'. Install 'curl' or 'wget'. It is needed to download the vsdbg package." + fi + + if [ $? -ne 0 ]; then + if [ "$__OfflineMode" = true ]; then + echo "${GetVsDbgShDataPrefix}URL=$url" + fi + fail "ERROR: No internet connection." + fi +} + +download() +{ + if [ "$__UseZip" = false ]; then + vsdbgFileExtension=".tar.gz" + else + echo "Warning: Version '${__VsDbgMetaVersion}' is only avaliable in zip." + vsdbgFileExtension=".zip" + fi + vsdbgCompressedFile="vsdbg-${__RuntimeID}${vsdbgFileExtension}" + target="$(echo "${__VsDbgVersion}" | tr '.' '-')" + url="https://vsdebugger-cyg0dxb6czfafzaz.b01.azurefd.net/vsdbg-${target}/${vsdbgCompressedFile}" + + check_internet_connection "$url" + + echo "Downloading ${url}" + if hash wget 2>/dev/null; then + wget -q "$url" -O "$vsdbgCompressedFile" + elif hash curl 2>/dev/null; then + curl -s "$url" -o "$vsdbgCompressedFile" + fi + + if [ $? -ne 0 ]; then + echo + echo "ERROR: Could not download ${url}" + exit 1; + fi + + __VsdbgCompressedFile=$vsdbgCompressedFile +} + +extract() +{ + errorMessage= + if [ "$__UseZip" = false ]; then + if ! hash tar 2>/dev/null; then + errorMessage="ERROR: Failed to find 'tar'." + elif ! tar -xzf "$__VsdbgCompressedFile"; then + errorMessage="ERROR: Failed to extract vsdbg." + fi + else + if ! hash unzip 2>/dev/null; then + errorMessage="ERROR: Failed to find 'zip'." + elif ! unzip -o -q "$__VsdbgCompressedFile"; then + errorMessage="ERROR: Failed to unzip vsdbg." + fi + fi + + # If no errors, continue + if [ -z "$errorMessage" ]; then + chmod +x ./vsdbg + # Check to see if vsdbg has execute permissions. + if [ ! -x ./vsdbg ]; then + errorMessage="ERROR: Failed to set executable permissions on vsdbg." + fi + fi + + rm "$__VsdbgCompressedFile" + + # Error occured, cleanup the compressed binary and exit with error. + if [ -n "$errorMessage" ]; then + fail "$errorMessage" + fi +} + +get_script_directory + +if [ -z "$1" ]; then + echo "ERROR: Missing arguments for GetVsDbg.sh" + print_help + exit 1 +else + parse_and_get_arguments "$@" +fi + +set_vsdbg_version "$__VsDbgMetaVersion" + +check_latest +# only try and use the alternate debugger location if the one in the default location is not adequate +if [ "$__SkipDownloads" = false ]; then + verify_and_use_alt_install_location +fi + +echo "Info: Using vsdbg version '$__VsDbgVersion'" +convert_install_path_to_absolute +print_arguments + +# Shortcut if we are using Alternate Debugger Location +if [ "$__UseAltDebuggerLocation" = false ]; then + if [ "$__SkipDownloads" = true ]; then + echo "Info: Skipping downloads" + else + prepare_install_location + cd "$__InstallLocation" || fail "Command failed: 'cd \"$__InstallLocation\"'" + + # For the rest of this script we can assume the working directory is the install path + + # Check to see if we already have a compressed file to extract, if not, we need to download it. + if [ -z "$__VsdbgCompressedFile" ]; then + if [ -z "$__RuntimeID" ]; then + get_dotnet_runtime_id + elif [ "$__ExactVsDbgVersionUsed" = "false" ]; then + # Remap the old distro-specific runtime ids unless the caller specified an exact build number. + # We don't do this in the exact build number case so that old builds can be used. + remap_runtime_id + fi + + echo "Info: Using Runtime ID '$__RuntimeID'" + download + fi + + extract + + echo "$__VsDbgVersion" > success.txt + # per greggm, this 'cd' can fail sometimes and is to be expected. + # shellcheck disable=SC2164 + cd "$__InitialCWD" + echo "Info: Successfully installed vsdbg at '$__InstallLocation'" + fi +fi + +if [ "$__LaunchVsDbg" = true ]; then + # Note: The following echo is a token to indicate the vsdbg is getting launched. + # If you were to change or remove this echo make the necessary changes in the MIEngine + echo "Info: Launching vsdbg" + "$__InstallLocation/vsdbg" "--interpreter=$__VsDbgMode" + exit $? +fi + +exit 0 diff --git a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyAuthConfigurator.cs b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyAuthConfigurator.cs index 8abb9236591..69d309c5b99 100644 --- a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyAuthConfigurator.cs +++ b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyAuthConfigurator.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.Diagnostics.Monitoring.WebApi; -using Microsoft.Diagnostics.Tools.Monitor.Swagger; +using Microsoft.Diagnostics.Tools.Monitor.OpenApi; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; diff --git a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs index cdae1908e94..ec54db4e70a 100644 --- a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs +++ b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs @@ -6,7 +6,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.Auth; using Microsoft.Diagnostics.Tools.Monitor.Stacks; -using Microsoft.Diagnostics.Tools.Monitor.Swagger; +using Microsoft.Diagnostics.Tools.Monitor.OpenApi; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -95,10 +95,14 @@ private static IHostBuilder Configure(this IHostBuilder builder, StartupAuthenti authConfigurator.ConfigureApiAuth(services, context); - services.AddSwaggerGen(options => - { - options.ConfigureMonitorSwaggerGen(); - authConfigurator.ConfigureSwaggerGenAuth(options); + // services.AddSwaggerGen(options => + // { + // options.ConfigureMonitorSwaggerGen(); + // authConfigurator.ConfigureSwaggerGenAuth(options); + // }); + services.AddOpenApi(options => { + options.ConfigureMonitorOpenApiGen(); + // TODO: ConfigureOpenApiGenAuth(options); }); services.ConfigureDiagnosticPort(context.Configuration); diff --git a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs new file mode 100644 index 00000000000..31c51de15e4 --- /dev/null +++ b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs @@ -0,0 +1,133 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.Diagnostics.Monitoring.WebApi.Controllers; +using Microsoft.AspNetCore.OpenApi; +using Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Net.Http.Headers; +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading.Tasks; +using System.Xml.XPath; + +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi +{ + internal static class OpenApiOptionsExtensions + { + public static void ConfigureMonitorOpenApiGen(this OpenApiOptions options) + { + options.AddDocumentTransformer(); + options.AddDocumentTransformer(); + options.AddDocumentTransformer(); + + options.AddOperationTransformer(); +// options.OperationFilter(); + options.AddOperationTransformer(); + options.AddOperationTransformer(); + + options.AddSchemaTransformer((schema, context, cancellationToken) => { + // FileResult should be represented as type: string, format: binary, not a ref. + // if (schema.Reference != null && schema.Reference.Id == nameof(FileResult)) + if (context.JsonTypeInfo.Type == typeof(FileResult)) + { + // if (string.Empty.Length == 0) { + // throw new System.Exception("FileResuiLT!"); + // } + schema.Reference = null; + schema.Type = "string"; + schema.Format = "binary"; + schema.Properties = new Dictionary(); + } + return Task.CompletedTask; + }); + + options.CreateSchemaReferenceId = (type) => { + if (type.Type == typeof(FileResult)) { + // always inline. + return null; + } + return OpenApiOptions.CreateDefaultSchemaReferenceId(type); + }; + + // options.CreateSchemaReferenceId = (type) => { + // Console.WriteLine("Create schema ref id for type " + type.ToString()); + // return type.Type.IsEnum ? null : OpenApiOptions.CreateDefaultSchemaReferenceId(type); + // }; + + // options.AddDocumentTransformer((document, context, cancellationToken) => { + // // Get rid of any 400 Bad Request section, replacing it with a reference + // // to components/responses/BadRequestResponse. + // if (document.Paths != null) + // { + // foreach (var path in document.Paths) + // { + // foreach (var operation in path.Value.Operations) + // { + // if (operation.Value.Responses.ContainsKey("400")) + // { + // operation.Value.Responses["400"] = new OpenApiResponse + // { + // Reference = new OpenApiReference + // { + // Type = ReferenceType.Response, + // Id = "BadRequestResponse" + // } + // }; + // } + // } + // } + // } + // // Add the common response + // document.Components.Responses.Add("BadRequestResponse", new OpenApiResponse + // { + // Description = "Bad Request", + // Content = new Dictionary + // { + // { ContentTypes.ApplicationProblemJson, new OpenApiMediaType() } + // } + // }); + // }); + + + + +// string documentationFile = $"{typeof(DiagController).Assembly.GetName().Name}.xml"; +// #nullable disable +// options.IncludeXmlComments(() => new XPathDocument(Assembly.GetExecutingAssembly().GetManifestResourceStream(documentationFile))); +// #nullable restore +// // Make sure TimeSpan is represented as a string instead of a full object type +// options.MapType(() => new OpenApiSchema() { Type = "string", Format = "time-span", Example = new OpenApiString("00:00:30") }); + } + + public static void AddBearerTokenAuthOption(this SwaggerGenOptions options, string securityDefinitionName) + { + options.AddSecurityDefinition(securityDefinitionName, new OpenApiSecurityScheme + { + Name = HeaderNames.Authorization, + Type = SecuritySchemeType.ApiKey, + Scheme = JwtBearerDefaults.AuthenticationScheme, + BearerFormat = "JWT", + In = ParameterLocation.Header, + Description = Strings.HelpDescription_SecurityDefinitionDescription_ApiKey + }); + + options.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = securityDefinitionName } + }, + Array.Empty() + } + }); + } + } +} diff --git a/src/Tools/dotnet-monitor/Swagger/ResponseNames.cs b/src/Tools/dotnet-monitor/OpenApi/ResponseNames.cs similarity index 89% rename from src/Tools/dotnet-monitor/Swagger/ResponseNames.cs rename to src/Tools/dotnet-monitor/OpenApi/ResponseNames.cs index 8dfa5710382..8d8fc465e18 100644 --- a/src/Tools/dotnet-monitor/Swagger/ResponseNames.cs +++ b/src/Tools/dotnet-monitor/OpenApi/ResponseNames.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi { internal static class ResponseNames { diff --git a/src/Tools/dotnet-monitor/Swagger/StatusCodeStrings.cs b/src/Tools/dotnet-monitor/OpenApi/StatusCodeStrings.cs similarity index 92% rename from src/Tools/dotnet-monitor/Swagger/StatusCodeStrings.cs rename to src/Tools/dotnet-monitor/OpenApi/StatusCodeStrings.cs index 3ccc27573d5..ea06d3a2253 100644 --- a/src/Tools/dotnet-monitor/Swagger/StatusCodeStrings.cs +++ b/src/Tools/dotnet-monitor/OpenApi/StatusCodeStrings.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Http; using System.Globalization; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi { internal static class StatusCodeStrings { diff --git a/src/Tools/dotnet-monitor/Swagger/SwaggerProviderExtensions.cs b/src/Tools/dotnet-monitor/OpenApi/SwaggerProviderExtensions.cs similarity index 93% rename from src/Tools/dotnet-monitor/Swagger/SwaggerProviderExtensions.cs rename to src/Tools/dotnet-monitor/OpenApi/SwaggerProviderExtensions.cs index b99b5c60cc7..062f3fb7ebc 100644 --- a/src/Tools/dotnet-monitor/Swagger/SwaggerProviderExtensions.cs +++ b/src/Tools/dotnet-monitor/OpenApi/SwaggerProviderExtensions.cs @@ -6,7 +6,7 @@ using Swashbuckle.AspNetCore.Swagger; using System.IO; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi { internal static class SwaggerProviderExtensions { diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/BadRequestResponseDocumentFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/BadRequestResponseDocumentTransformer.cs similarity index 69% rename from src/Tools/dotnet-monitor/Swagger/Filters/BadRequestResponseDocumentFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/BadRequestResponseDocumentTransformer.cs index a30ad0e38cc..52c2e1c2888 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/BadRequestResponseDocumentFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/BadRequestResponseDocumentTransformer.cs @@ -2,18 +2,20 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.OpenApi; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { /// /// Adds an BadRequestResponse response component to the document. /// - internal sealed class BadRequestResponseDocumentFilter : IDocumentFilter + internal sealed class BadRequestResponseDocumentTransformer : IOpenApiDocumentTransformer { - public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) + public async Task TransformAsync(OpenApiDocument openApiDoc, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken) { OpenApiResponse unauthorizedResponse = new(); unauthorizedResponse.Description = "Bad Request"; @@ -31,7 +33,7 @@ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) } }); - swaggerDoc.Components.Responses.Add( + (openApiDoc.Components ??= new OpenApiComponents()).Responses.Add( ResponseNames.BadRequestResponse, unauthorizedResponse); } diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/BadRequestResponseOperationFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/BadRequestResponseOperationTransformer.cs similarity index 70% rename from src/Tools/dotnet-monitor/Swagger/Filters/BadRequestResponseOperationFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/BadRequestResponseOperationTransformer.cs index 1c21b56e58c..32d3c0a2a20 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/BadRequestResponseOperationFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/BadRequestResponseOperationTransformer.cs @@ -1,18 +1,20 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.OpenApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { /// /// Clears all content of the 400 response and adds a reference to the /// BadRequestResponse response component . /// - internal sealed class BadRequestResponseOperationFilter : IOperationFilter + internal sealed class BadRequestResponseOperationTransformer : IOpenApiOperationTransformer { - public void Apply(OpenApiOperation operation, OperationFilterContext context) + public async Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransformerContext context, CancellationToken cancellationToken) { if (operation.Responses.Remove(StatusCodeStrings.Status400BadRequest)) { diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/RemoveFailureContentTypesOperationFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/RemoveFailureContentTypesOperationFilter.cs similarity index 93% rename from src/Tools/dotnet-monitor/Swagger/Filters/RemoveFailureContentTypesOperationFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/RemoveFailureContentTypesOperationFilter.cs index ff8a00784e8..9a0b454bf49 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/RemoveFailureContentTypesOperationFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/RemoveFailureContentTypesOperationFilter.cs @@ -6,7 +6,7 @@ using Swashbuckle.AspNetCore.SwaggerGen; using System.Collections.Generic; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { /// /// Removes failure content types (e.g. application/problem+json) from success operations. diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/TooManyRequestsResponseDocumentFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/TooManyRequestsResponseDocumentTransformer.cs similarity index 72% rename from src/Tools/dotnet-monitor/Swagger/Filters/TooManyRequestsResponseDocumentFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/TooManyRequestsResponseDocumentTransformer.cs index db978cbe210..b56891e034f 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/TooManyRequestsResponseDocumentFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/TooManyRequestsResponseDocumentTransformer.cs @@ -2,15 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.OpenApi; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { - internal sealed class TooManyRequestsResponseDocumentFilter : IDocumentFilter + internal sealed class TooManyRequestsResponseDocumentTransformer : IOpenApiDocumentTransformer { - public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) + public async Task TransformAsync(OpenApiDocument swaggerDoc, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken) { OpenApiResponse tooManyRequests = new(); tooManyRequests.Description = "TooManyRequests"; diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/TooManyRequestsResponseOperationFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/TooManyRequestsResponseOperationTransformer.cs similarity index 65% rename from src/Tools/dotnet-monitor/Swagger/Filters/TooManyRequestsResponseOperationFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/TooManyRequestsResponseOperationTransformer.cs index eb57e961d6d..ec300785aaa 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/TooManyRequestsResponseOperationFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/TooManyRequestsResponseOperationTransformer.cs @@ -1,14 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.OpenApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { - internal sealed class TooManyRequestsResponseOperationFilter : IOperationFilter + internal sealed class TooManyRequestsResponseOperationTransformer : IOpenApiOperationTransformer { - public void Apply(OpenApiOperation operation, OperationFilterContext context) + public async Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransformerContext context, CancellationToken cancellationToken) { if (operation.Responses.Remove(StatusCodeStrings.Status429TooManyRequests)) { diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/UnauthorizedResponseDocumentFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/UnauthorizedResponseDocumentTransformer.cs similarity index 62% rename from src/Tools/dotnet-monitor/Swagger/Filters/UnauthorizedResponseDocumentFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/UnauthorizedResponseDocumentTransformer.cs index 58267696f22..8aedcea6d08 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/UnauthorizedResponseDocumentFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/UnauthorizedResponseDocumentTransformer.cs @@ -1,17 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.OpenApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { /// /// Adds an UnauthorizedResponse response component to the document. /// - internal sealed class UnauthorizedResponseDocumentFilter : IDocumentFilter + internal sealed class UnauthorizedResponseDocumentTransformer : IOpenApiDocumentTransformer { - public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) + public async Task TransformAsync(OpenApiDocument openApiDoc, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken) { OpenApiHeader authenticateHeader = new(); authenticateHeader.Schema = new OpenApiSchema() { Type = "string" }; @@ -20,7 +22,7 @@ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) unauthorizedResponse.Description = "Unauthorized"; unauthorizedResponse.Headers.Add("WWW_Authenticate", authenticateHeader); - swaggerDoc.Components.Responses.Add( + openApiDoc.Components.Responses.Add( ResponseNames.UnauthorizedResponse, unauthorizedResponse); } diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/UnauthorizedResponseOperationFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/UnauthorizedResponseOperationTransformer.cs similarity index 67% rename from src/Tools/dotnet-monitor/Swagger/Filters/UnauthorizedResponseOperationFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/UnauthorizedResponseOperationTransformer.cs index 7a491fe7f3f..57a6da8fec7 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/UnauthorizedResponseOperationFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/UnauthorizedResponseOperationTransformer.cs @@ -1,18 +1,20 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.OpenApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { /// /// Clears all content of the 401 response and adds a reference to the /// UnauthorizedResponse response component . /// - internal sealed class UnauthorizedResponseOperationFilter : IOperationFilter + internal sealed class UnauthorizedResponseOperationTransformer : IOpenApiOperationTransformer { - public void Apply(OpenApiOperation operation, OperationFilterContext context) + public async Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransformerContext context, CancellationToken cancellationToken) { if (operation.Responses.TryGetValue(StatusCodeStrings.Status401Unauthorized, out OpenApiResponse? unauthorizedResponse)) { diff --git a/src/Tools/dotnet-monitor/Startup.cs b/src/Tools/dotnet-monitor/Startup.cs index 4a19a0276dc..d66eb8f79ee 100644 --- a/src/Tools/dotnet-monitor/Startup.cs +++ b/src/Tools/dotnet-monitor/Startup.cs @@ -8,7 +8,7 @@ using Microsoft.AspNetCore.ResponseCompression; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Controllers; -using Microsoft.Diagnostics.Tools.Monitor.Swagger; +using Microsoft.Diagnostics.Tools.Monitor.OpenApi; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -18,6 +18,7 @@ using System.IO; using System.IO.Compression; using System.Text.Json.Serialization; +using System.Reflection; namespace Microsoft.Diagnostics.Tools.Monitor { @@ -33,7 +34,6 @@ public Startup(IConfiguration configuration) // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - // AddControllers is sufficient because the tool does not use Razor nor Views. services.ConfigureHttpJsonOptions(options => { options.SerializerOptions.Converters.Add(new JsonStringEnumConverter()); }); @@ -80,7 +80,10 @@ public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, I app.UseRouting(); app.UseAuthentication(); - app.UseAuthorization(); + if (Assembly.GetEntryAssembly()?.GetName().Name != "GetDocument.Insider") + { + app.UseAuthorization(); + } if (!string.IsNullOrEmpty(corsOptions.Value.AllowedOrigins)) { @@ -95,8 +98,6 @@ public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, I { var serviceProvider = builder.ServiceProvider; - OperationsController.MapActionMethods(builder); - DiagController.MapActionMethods(builder); DiagController.MapMetricsActionMethods(builder); @@ -104,14 +105,19 @@ public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, I MetricsController.MapActionMethods(builder); - builder.MapGet("/", (HttpResponse response, ISwaggerProvider provider) => - { - using Stream stream = response.BodyWriter.AsStream(true); + OperationsController.MapActionMethods(builder); + + // AH! Here!!! + // builder.MapGet("/", (HttpResponse response, ISwaggerProvider provider) => + // { + // using Stream stream = response.BodyWriter.AsStream(true); - provider.WriteTo(stream); - }); + // provider.WriteTo(stream); + // }); + builder.MapOpenApi("/"); app.UseMiddleware(); + System.Console.WriteLine("MapOpenApi"); }); } } diff --git a/src/Tools/dotnet-monitor/Swagger/SwaggerGenOptionsExtensions.cs b/src/Tools/dotnet-monitor/Swagger/SwaggerGenOptionsExtensions.cs deleted file mode 100644 index 82943dccd6c..00000000000 --- a/src/Tools/dotnet-monitor/Swagger/SwaggerGenOptionsExtensions.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.Diagnostics.Monitoring.WebApi.Controllers; -using Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Net.Http.Headers; -using Microsoft.OpenApi.Any; -using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; -using System; -using System.Reflection; -using System.Xml.XPath; - -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger -{ - internal static class SwaggerGenOptionsExtensions - { - public static void ConfigureMonitorSwaggerGen(this SwaggerGenOptions options) - { - options.DocumentFilter(); - options.DocumentFilter(); - options.DocumentFilter(); - - options.OperationFilter(); - options.OperationFilter(); - options.OperationFilter(); - options.OperationFilter(); - - string documentationFile = $"{typeof(DiagController).Assembly.GetName().Name}.xml"; -#nullable disable - options.IncludeXmlComments(() => new XPathDocument(Assembly.GetExecutingAssembly().GetManifestResourceStream(documentationFile))); -#nullable restore - // Make sure TimeSpan is represented as a string instead of a full object type - options.MapType(() => new OpenApiSchema() { Type = "string", Format = "time-span", Example = new OpenApiString("00:00:30") }); - } - - public static void AddBearerTokenAuthOption(this SwaggerGenOptions options, string securityDefinitionName) - { - options.AddSecurityDefinition(securityDefinitionName, new OpenApiSecurityScheme - { - Name = HeaderNames.Authorization, - Type = SecuritySchemeType.ApiKey, - Scheme = JwtBearerDefaults.AuthenticationScheme, - BearerFormat = "JWT", - In = ParameterLocation.Header, - Description = Strings.HelpDescription_SecurityDefinitionDescription_ApiKey - }); - - options.AddSecurityRequirement(new OpenApiSecurityRequirement - { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = securityDefinitionName } - }, - Array.Empty() - } - }); - } - } -} diff --git a/src/Tools/dotnet-monitor/dotnet-monitor.csproj b/src/Tools/dotnet-monitor/dotnet-monitor.csproj index 3b881f6617a..d1199c122b3 100644 --- a/src/Tools/dotnet-monitor/dotnet-monitor.csproj +++ b/src/Tools/dotnet-monitor/dotnet-monitor.csproj @@ -9,6 +9,7 @@ false false enable + false @@ -17,6 +18,7 @@ + From bb7582f3227afa0de838483aff4fe1508d060910 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 14 Mar 2025 19:11:56 +0000 Subject: [PATCH 071/174] Use openapi generator --- Directory.Packages.props | 3 +- documentation/openapi.json | 341 +++++++++++------- eng/Versions.props | 2 + .../CollectionRuleState.cs | 3 + .../DiagnosticPortConnectionMode.cs | 3 + .../MonitorCapability.cs | 8 +- .../Controllers/DiagController.Metrics.cs | 43 +-- .../Controllers/DiagController.cs | 215 +++++------ .../Controllers/ExceptionsController.cs | 39 +- .../Controllers/MetricsController.cs | 8 +- .../Controllers/OperationsController.cs | 25 +- .../Models/CollectionRuleDescription.cs | 5 +- .../CollectionRuleDetailedDescription.cs | 7 + .../Models/DotnetMonitorInfo.cs | 17 +- .../Models/DumpType.cs | 3 + .../Models/EventMetricsConfiguration.cs | 2 + .../Models/EventPipeProvider.cs | 2 + .../Models/LogsConfiguration.cs | 10 +- .../Models/MethodDescription.cs | 3 + .../Models/TraceProfile.cs | 2 + .../ProducesWithProblemDetailsAttribute.cs | 24 +- ...t.Diagnostics.Monitoring.OpenApiGen.csproj | 7 + .../Program.cs | 25 +- .../ApiKey/MonitorApiKeyAuthConfigurator.cs | 6 +- .../Auth/AzureAd/AzureAdAuthConfigurator.cs | 42 ++- .../Auth/IAuthenticationConfigurator.cs | 4 +- .../Auth/NoAuth/NoAuthConfigurator.cs | 4 +- .../Commands/CollectCommandHandler.cs | 9 +- .../OpenApi/OpenApiOptionsExtensions.cs | 184 ++++++++++ .../{Swagger => OpenApi}/ResponseNames.cs | 2 +- .../{Swagger => OpenApi}/StatusCodeStrings.cs | 3 +- .../BadRequestResponseDocumentTransformer.cs} | 14 +- ...BadRequestResponseOperationTransformer.cs} | 14 +- ...ailureContentTypesOperationTransformer.cs} | 12 +- ...anyRequestsResponseDocumentTransformer.cs} | 14 +- ...nyRequestsResponseOperationTransformer.cs} | 12 +- ...nauthorizedResponseDocumentTransformer.cs} | 14 +- ...authorizedResponseOperationTransformer.cs} | 14 +- src/Tools/dotnet-monitor/Startup.cs | 13 +- .../Swagger/SwaggerGenOptionsExtensions.cs | 63 ---- .../Swagger/SwaggerProviderExtensions.cs | 27 -- .../dotnet-monitor/dotnet-monitor.csproj | 4 +- 42 files changed, 704 insertions(+), 548 deletions(-) create mode 100644 src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs rename src/Tools/dotnet-monitor/{Swagger => OpenApi}/ResponseNames.cs (89%) rename src/Tools/dotnet-monitor/{Swagger => OpenApi}/StatusCodeStrings.cs (78%) rename src/Tools/dotnet-monitor/{Swagger/Filters/BadRequestResponseDocumentFilter.cs => OpenApi/Transformers/BadRequestResponseDocumentTransformer.cs} (68%) rename src/Tools/dotnet-monitor/{Swagger/Filters/BadRequestResponseOperationFilter.cs => OpenApi/Transformers/BadRequestResponseOperationTransformer.cs} (67%) rename src/Tools/dotnet-monitor/{Swagger/Filters/RemoveFailureContentTypesOperationFilter.cs => OpenApi/Transformers/RemoveFailureContentTypesOperationTransformer.cs} (63%) rename src/Tools/dotnet-monitor/{Swagger/Filters/TooManyRequestsResponseDocumentFilter.cs => OpenApi/Transformers/TooManyRequestsResponseDocumentTransformer.cs} (66%) rename src/Tools/dotnet-monitor/{Swagger/Filters/TooManyRequestsResponseOperationFilter.cs => OpenApi/Transformers/TooManyRequestsResponseOperationTransformer.cs} (64%) rename src/Tools/dotnet-monitor/{Swagger/Filters/UnauthorizedResponseDocumentFilter.cs => OpenApi/Transformers/UnauthorizedResponseDocumentTransformer.cs} (60%) rename src/Tools/dotnet-monitor/{Swagger/Filters/UnauthorizedResponseOperationFilter.cs => OpenApi/Transformers/UnauthorizedResponseOperationTransformer.cs} (64%) delete mode 100644 src/Tools/dotnet-monitor/Swagger/SwaggerGenOptionsExtensions.cs delete mode 100644 src/Tools/dotnet-monitor/Swagger/SwaggerProviderExtensions.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 2998d1aa653..76c3f67438b 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,6 +7,7 @@ + @@ -14,6 +15,7 @@ + @@ -25,7 +27,6 @@ - diff --git a/documentation/openapi.json b/documentation/openapi.json index 03cab7afadb..a6535e2a37e 100644 --- a/documentation/openapi.json +++ b/documentation/openapi.json @@ -49,7 +49,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -58,7 +59,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -66,7 +68,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -104,7 +107,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -113,7 +117,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -121,7 +126,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -162,7 +168,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -171,7 +178,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -179,7 +187,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -187,7 +196,13 @@ "in": "query", "description": "The type of dump to capture.", "schema": { - "$ref": "#/components/schemas/DumpType" + "enum": [ + "Full", + "Mini", + "WithHeap", + "Triage" + ], + "default": "WithHeap" } }, { @@ -195,7 +210,8 @@ "in": "query", "description": "The egress provider to which the dump is saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -203,7 +219,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -248,7 +265,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -257,7 +275,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -265,7 +284,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -273,7 +293,8 @@ "in": "query", "description": "The egress provider to which the GC dump is saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -281,7 +302,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -326,7 +348,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -335,7 +358,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -343,7 +367,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -351,7 +376,8 @@ "in": "query", "description": "The profiles enabled for the trace session.", "schema": { - "$ref": "#/components/schemas/TraceProfile" + "type": "string", + "default": "Cpu, Http, Metrics, GcCollect" } }, { @@ -371,7 +397,8 @@ "in": "query", "description": "The egress provider to which the trace is saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -379,7 +406,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -422,7 +450,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -431,7 +460,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -439,7 +469,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -459,7 +490,8 @@ "in": "query", "description": "The egress provider to which the trace is saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -467,7 +499,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -533,7 +566,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -542,7 +576,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -550,7 +585,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -570,7 +606,8 @@ "in": "query", "description": "The level of the logs to capture.", "schema": { - "$ref": "#/components/schemas/LogLevel" + "type": "string", + "default": null } }, { @@ -578,7 +615,8 @@ "in": "query", "description": "The egress provider to which the logs are saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -586,7 +624,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -638,7 +677,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -647,7 +687,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -655,7 +696,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -675,7 +717,8 @@ "in": "query", "description": "The egress provider to which the logs are saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -683,7 +726,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -705,7 +749,8 @@ "$ref": "#/components/schemas/LogsConfiguration" } } - } + }, + "required": true }, "responses": { "400": { @@ -784,7 +829,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -793,7 +839,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -801,7 +848,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -851,7 +899,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -860,7 +909,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -868,7 +918,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -915,7 +966,8 @@ "in": "query", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -923,28 +975,32 @@ "in": "query", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { "name": "name", "in": "query", "schema": { - "type": "string" + "type": "string", + "default": null } }, { "name": "egressProvider", "in": "query", "schema": { - "type": "string" + "type": "string", + "default": null } }, { "name": "tags", "in": "query", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -1016,7 +1072,8 @@ "in": "query", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -1024,28 +1081,32 @@ "in": "query", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { "name": "name", "in": "query", "schema": { - "type": "string" + "type": "string", + "default": null } }, { "name": "egressProvider", "in": "query", "schema": { - "type": "string" + "type": "string", + "default": null } }, { "name": "tags", "in": "query", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -1099,7 +1160,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -1108,7 +1170,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -1116,7 +1179,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1136,7 +1200,8 @@ "in": "query", "description": "The egress provider to which the metrics are saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1144,7 +1209,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -1186,7 +1252,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -1195,7 +1262,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -1203,7 +1271,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1223,7 +1292,8 @@ "in": "query", "description": "The egress provider to which the metrics are saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1231,7 +1301,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -1296,7 +1367,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -1305,7 +1377,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -1313,7 +1386,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1321,7 +1395,8 @@ "in": "query", "description": "The egress provider to which the exceptions are saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1329,7 +1404,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -1375,7 +1451,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -1384,7 +1461,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -1392,7 +1470,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1400,7 +1479,8 @@ "in": "query", "description": "The egress provider to which the exceptions are saved.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1408,7 +1488,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -1430,7 +1511,8 @@ "$ref": "#/components/schemas/ExceptionsConfiguration" } } - } + }, + "required": true }, "responses": { "400": { @@ -1497,7 +1579,8 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32" + "format": "int32", + "default": null } }, { @@ -1506,7 +1589,8 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid" + "format": "uuid", + "default": null } }, { @@ -1514,7 +1598,8 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string" + "type": "string", + "default": null } }, { @@ -1522,7 +1607,8 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string" + "type": "string", + "default": null } } ], @@ -1666,20 +1752,11 @@ "description": "Human-readable explanation for the current state of the collection rule.", "nullable": true } - }, - "additionalProperties": false + } }, "CollectionRuleDetailedDescription": { "type": "object", "properties": { - "state": { - "$ref": "#/components/schemas/CollectionRuleState" - }, - "stateReason": { - "type": "string", - "description": "Human-readable explanation for the current state of the collection rule.", - "nullable": true - }, "lifetimeOccurrences": { "type": "integer", "description": "The number of times the trigger has executed for a process in its lifetime.", @@ -1715,6 +1792,14 @@ "format": "time-span", "nullable": true, "example": "00:00:30" + }, + "state": { + "$ref": "#/components/schemas/CollectionRuleState" + }, + "stateReason": { + "type": "string", + "description": "Human-readable explanation for the current state of the collection rule.", + "nullable": true } }, "additionalProperties": false @@ -1725,15 +1810,13 @@ "ActionExecuting", "Throttled", "Finished" - ], - "type": "string" + ] }, "DiagnosticPortConnectionMode": { "enum": [ "Connect", "Listen" - ], - "type": "string" + ] }, "DotnetMonitorInfo": { "required": [ @@ -1770,15 +1853,6 @@ }, "additionalProperties": false }, - "DumpType": { - "enum": [ - "Full", - "Mini", - "WithHeap", - "Triage" - ], - "type": "string" - }, "EventLevel": { "enum": [ "LogAlways", @@ -1787,8 +1861,7 @@ "Warning", "Informational", "Verbose" - ], - "type": "string" + ] }, "EventMetricsConfiguration": { "type": "object", @@ -1956,8 +2029,7 @@ "Error", "Critical", "None" - ], - "type": "string" + ] }, "LogsConfiguration": { "required": [ @@ -1985,9 +2057,9 @@ }, "MethodDescription": { "required": [ - "methodName", "moduleName", - "typeName" + "typeName", + "methodName" ], "type": "object", "properties": { @@ -2034,7 +2106,8 @@ "nullable": true } }, - "additionalProperties": false + "additionalProperties": false, + "nullable": true }, "OperationProcessInfo": { "type": "object", @@ -2053,7 +2126,8 @@ } }, "additionalProperties": false, - "description": "Represents the details of a given process used in an operation." + "description": "Represents the details of a given process used in an operation.", + "nullable": true }, "OperationState": { "enum": [ @@ -2063,12 +2137,18 @@ "Failed", "Cancelled", "Stopping" - ], - "type": "string" + ] }, "OperationStatus": { "type": "object", "properties": { + "resourceLocation": { + "type": "string", + "nullable": true + }, + "error": { + "$ref": "#/components/schemas/OperationError" + }, "operationId": { "type": "string", "format": "uuid" @@ -2097,13 +2177,6 @@ "type": "string" }, "nullable": true - }, - "resourceLocation": { - "type": "string", - "nullable": true - }, - "error": { - "$ref": "#/components/schemas/OperationError" } }, "additionalProperties": false, @@ -2223,16 +2296,6 @@ }, "additionalProperties": false }, - "TraceProfile": { - "enum": [ - "Cpu", - "Http", - "Logs", - "Metrics", - "GcCollect" - ], - "type": "string" - }, "ValidationProblemDetails": { "type": "object", "properties": { @@ -2303,5 +2366,19 @@ } } } - } + }, + "tags": [ + { + "name": "Diag" + }, + { + "name": "Exceptions" + }, + { + "name": "Metrics" + }, + { + "name": "Operations" + } + ] } \ No newline at end of file diff --git a/eng/Versions.props b/eng/Versions.props index 0780b298d1e..3d560d20cf7 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -122,6 +122,8 @@ $(MicrosoftExtensionsLoggingAbstractions90Version) $(MicrosoftExtensionsLoggingConsole90Version) $(SystemTextJson90Version) + $(MicrosoftAspNetCoreApp90Version) + $(MicrosoftAspNetCoreApp90Version) $(MicrosoftDiagnosticsMonitoringShippedVersion) diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/CollectionRuleState.cs b/src/Microsoft.Diagnostics.Monitoring.Options/CollectionRuleState.cs index 2ec3a672557..1f4562765b7 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/CollectionRuleState.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/CollectionRuleState.cs @@ -1,8 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Text.Json.Serialization; + namespace Microsoft.Diagnostics.Monitoring.WebApi { + [JsonConverter(typeof(JsonStringEnumConverter))] public enum CollectionRuleState { Running, diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortConnectionMode.cs b/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortConnectionMode.cs index 19a96d1c31c..56799fd2ceb 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortConnectionMode.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortConnectionMode.cs @@ -1,8 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Text.Json.Serialization; + namespace Microsoft.Diagnostics.Monitoring.WebApi { + [JsonConverter(typeof(JsonStringEnumConverter))] public enum DiagnosticPortConnectionMode { Connect, diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/MonitorCapability.cs b/src/Microsoft.Diagnostics.Monitoring.Options/MonitorCapability.cs index e480e727c48..22c0c244130 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/MonitorCapability.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/MonitorCapability.cs @@ -10,15 +10,15 @@ public class MonitorCapability : IMonitorCapability { [JsonPropertyName("name")] [Required] - public string Name { get; } + [MinLength(1)] + public string Name { get; set; } [JsonPropertyName("enabled")] - public bool Enabled { get; } + public bool Enabled { get; init; } - public MonitorCapability(string name, bool enabled) + public MonitorCapability(string name) { Name = name; - Enabled = enabled; } } } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs index 0c99f193dc8..ca6eb339538 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.Metrics.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Diagnostics.Monitoring.EventPipe; using System; +using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; @@ -12,33 +13,31 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { partial class DiagController { - /// - /// Capture metrics for a process. - /// - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. - /// The duration of the metrics session (in seconds). - /// The egress provider to which the metrics are saved. - /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + [EndpointSummary("Capture metrics for a process.")] [HttpGet("livemetrics", Name = nameof(CaptureMetrics))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJsonSequence)] + [ProducesWithProblemDetails] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, ContentTypes.ApplicationJsonSequence)] [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] [EgressValidation] public Task CaptureMetrics( [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null, [FromQuery][Range(-1, int.MaxValue)] + [Description("The duration of the metrics session (in seconds).")] int durationSeconds = 30, [FromQuery] + [Description("The egress provider to which the metrics are saved.")] string? egressProvider = null, [FromQuery] + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -59,36 +58,34 @@ public Task CaptureMetrics( Utilities.ArtifactType_Metrics); } - /// - /// Capture metrics for a process. - /// - /// The metrics configuration describing which metrics to capture. - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. - /// The duration of the metrics session (in seconds). - /// The egress provider to which the metrics are saved. - /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + [EndpointSummary("Capture metrics for a process.")] [HttpPost("livemetrics", Name = nameof(CaptureMetricsCustom))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJsonSequence)] + [ProducesWithProblemDetails] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, ContentTypes.ApplicationJsonSequence)] [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] [EgressValidation] public Task CaptureMetricsCustom( [FromBody][Required] + [Description("The metrics configuration describing which metrics to capture.")] Models.EventMetricsConfiguration configuration, [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null, [FromQuery][Range(-1, int.MaxValue)] + [Description("The duration of the metrics session (in seconds).")] int durationSeconds = 30, [FromQuery] + [Description("The egress provider to which the metrics are saved.")] string? egressProvider = null, [FromQuery] + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs index e986323f930..12a3877ad14 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/DiagController.cs @@ -15,6 +15,7 @@ using Microsoft.Net.Http.Headers; using System; using System.Collections.Generic; +using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; @@ -68,12 +69,10 @@ public DiagController(IServiceProvider serviceProvider, ILogger _monitorCapabilities = serviceProvider.GetRequiredService>(); } - /// - /// Get the list of accessible processes. - /// + [EndpointSummary("Get the list of accessible processes.")] [HttpGet("processes", Name = nameof(GetProcesses))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesWithProblemDetails] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK, ContentTypes.ApplicationJson)] public Task>> GetProcesses() { return this.InvokeService(async () => @@ -113,21 +112,19 @@ public Task>> GetProcesses() }, Logger); } - /// - /// Get information about the specified process. - /// - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. + [EndpointSummary("Get information about the specified process.")] [HttpGet("process", Name = nameof(GetProcessInfo))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(Models.ProcessInfo), StatusCodes.Status200OK)] + [ProducesWithProblemDetails] + [ProducesResponseType(typeof(Models.ProcessInfo), StatusCodes.Status200OK, ContentTypes.ApplicationJson)] public Task> GetProcessInfo( [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -151,21 +148,19 @@ public Task>> GetProcesses() processKey); } - /// - /// Get the environment block of the specified process. - /// - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. + [EndpointSummary("Get the environment block of the specified process.")] [HttpGet("env", Name = nameof(GetProcessEnvironment))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(Dictionary), StatusCodes.Status200OK)] + [ProducesWithProblemDetails] + [ProducesResponseType(typeof(Dictionary), StatusCodes.Status200OK, ContentTypes.ApplicationJson)] public Task>> GetProcessEnvironment( [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -190,36 +185,33 @@ public Task>> GetProcessEnvironment( processKey); } - /// - /// Capture a dump of a process. - /// - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. - /// The type of dump to capture. - /// The egress provider to which the dump is saved. - /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. - /// + [EndpointSummary("Capture a dump of a process.")] [HttpGet("dump", Name = nameof(CaptureDump))] - [ProducesWithProblemDetails(ContentTypes.ApplicationOctetStream)] + [ProducesWithProblemDetails] // FileResult is the closest representation of the output so that the OpenAPI document correctly // describes the result as a binary file. [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream)] [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] [EgressValidation] public Task CaptureDump( [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null, [FromQuery] + [Description("The type of dump to capture.")] Models.DumpType type = Models.DumpType.WithHeap, [FromQuery] + [Description("The egress provider to which the dump is saved.")] string? egressProvider = null, [FromQuery] + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -235,33 +227,30 @@ public Task CaptureDump( Utilities.ArtifactType_Dump); } - /// - /// Capture a GC dump of a process. - /// - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. - /// The egress provider to which the GC dump is saved. - /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. - /// + [EndpointSummary("Capture a GC dump of a process.")] [HttpGet("gcdump", Name = nameof(CaptureGcDump))] - [ProducesWithProblemDetails(ContentTypes.ApplicationOctetStream)] + [ProducesWithProblemDetails] // FileResult is the closest representation of the output so that the OpenAPI document correctly // describes the result as a binary file. [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream)] [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] [EgressValidation] public Task CaptureGcDump( [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null, [FromQuery] + [Description("The egress provider to which the GC dump is saved.")] string? egressProvider = null, [FromQuery] + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -277,38 +266,36 @@ public Task CaptureGcDump( Utilities.ArtifactType_GCDump); } - /// - /// Capture a trace of a process. - /// - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. - /// The profiles enabled for the trace session. - /// The duration of the trace session (in seconds). - /// The egress provider to which the trace is saved. - /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + [EndpointSummary("Capture a trace of a process.")] [HttpGet("trace", Name = nameof(CaptureTrace))] - [ProducesWithProblemDetails(ContentTypes.ApplicationOctetStream)] + [ProducesWithProblemDetails] // FileResult is the closest representation of the output so that the OpenAPI document correctly // describes the result as a binary file. [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream)] [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] [EgressValidation] public Task CaptureTrace( [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null, [FromQuery] + [Description("The profiles enabled for the trace session.")] TraceProfile profile = DefaultTraceProfiles, [FromQuery][Range(-1, int.MaxValue)] + [Description("The duration of the trace session (in seconds).")] int durationSeconds = 30, [FromQuery] + [Description("The egress provider to which the trace is saved.")] string? egressProvider = null, [FromQuery] + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -323,38 +310,36 @@ public Task CaptureTrace( }, processKey, Utilities.ArtifactType_Trace); } - /// - /// Capture a trace of a process. - /// - /// The trace configuration describing which events to capture. - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. - /// The duration of the trace session (in seconds). - /// The egress provider to which the trace is saved. - /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + [EndpointSummary("Capture a trace of a process.")] [HttpPost("trace", Name = nameof(CaptureTraceCustom))] - [ProducesWithProblemDetails(ContentTypes.ApplicationOctetStream)] + [ProducesWithProblemDetails] // FileResult is the closest representation of the output so that the OpenAPI document correctly // describes the result as a binary file. [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK, ContentTypes.ApplicationOctetStream)] [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] [EgressValidation] public Task CaptureTraceCustom( [FromBody][Required] + [Description("The trace configuration describing which events to capture.")] EventPipeConfiguration configuration, [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null, [FromQuery][Range(-1, int.MaxValue)] + [Description("The duration of the trace session (in seconds).")] int durationSeconds = 30, [FromQuery] + [Description("The egress provider to which the trace is saved.")] string? egressProvider = null, [FromQuery] + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -378,36 +363,34 @@ public Task CaptureTraceCustom( }, processKey, Utilities.ArtifactType_Trace); } - /// - /// Capture a stream of logs from a process. - /// - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. - /// The duration of the logs session (in seconds). - /// The level of the logs to capture. - /// The egress provider to which the logs are saved. - /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + [EndpointSummary("Capture a stream of logs from a process.")] [HttpGet("logs", Name = nameof(CaptureLogs))] - [ProducesWithProblemDetails(ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] + [ProducesWithProblemDetails] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] [EgressValidation] public Task CaptureLogs( [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null, [FromQuery][Range(-1, int.MaxValue)] + [Description("The duration of the logs session (in seconds).")] int durationSeconds = 30, [FromQuery] + [Description("The level of the logs to capture.")] LogLevel? level = null, [FromQuery] + [Description("The egress provider to which the logs are saved.")] string? egressProvider = null, [FromQuery] + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -436,36 +419,34 @@ public Task CaptureLogs( }, processKey, Utilities.ArtifactType_Logs); } - /// - /// Capture a stream of logs from a process. - /// - /// The logs configuration describing which logs to capture. - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. - /// The duration of the logs session (in seconds). - /// The egress provider to which the logs are saved. - /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + [EndpointSummary("Capture a stream of logs from a process.")] [HttpPost("logs", Name = nameof(CaptureLogsCustom))] - [ProducesWithProblemDetails(ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] + [ProducesWithProblemDetails] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] [EgressValidation] public Task CaptureLogsCustom( [FromBody] + [Description("The logs configuration describing which logs to capture.")] LogsConfiguration configuration, [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null, [FromQuery][Range(-1, int.MaxValue)] + [Description("The duration of the logs session (in seconds).")] int durationSeconds = 30, [FromQuery] + [Description("The egress provider to which the logs are saved.")] string? egressProvider = null, [FromQuery] + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -486,12 +467,10 @@ public Task CaptureLogsCustom( }, processKey, Utilities.ArtifactType_Logs); } - /// - /// Gets versioning and listening mode information about Dotnet-Monitor - /// + [EndpointSummary("Gets versioning and listening mode information about Dotnet-Monitor")] [HttpGet("info", Name = nameof(GetInfo))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(DotnetMonitorInfo), StatusCodes.Status200OK)] + [ProducesWithProblemDetails] + [ProducesResponseType(typeof(DotnetMonitorInfo), StatusCodes.Status200OK, ContentTypes.ApplicationJson)] public ActionResult GetInfo() { return this.InvokeService(() => @@ -507,7 +486,9 @@ public ActionResult GetInfo() RuntimeVersion = runtimeVersion, DiagnosticPortMode = diagnosticPortMode, DiagnosticPortName = diagnosticPortName, - Capabilities = _monitorCapabilities.Select(c => new MonitorCapability(c.Name, c.Enabled)).ToArray() + Capabilities = _monitorCapabilities.Select(c => new MonitorCapability(c.Name) { + Enabled = c.Enabled + }).ToArray() }; Logger.WrittenToHttpStream(); @@ -515,21 +496,19 @@ public ActionResult GetInfo() }, Logger); } - /// - /// Gets a brief summary about the current state of the collection rules. - /// - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. + [EndpointSummary("Gets a brief summary about the current state of the collection rules.")] [HttpGet("collectionrules", Name = nameof(GetCollectionRulesDescription))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(Dictionary), StatusCodes.Status200OK)] + [ProducesWithProblemDetails] + [ProducesResponseType(typeof(Dictionary), StatusCodes.Status200OK, ContentTypes.ApplicationJson)] public Task>> GetCollectionRulesDescription( [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null) { return InvokeForProcess>(processInfo => @@ -539,23 +518,21 @@ public Task>> GetColl Utilities.GetProcessKey(pid, uid, name)); } - /// - /// Gets detailed information about the current state of the specified collection rule. - /// - /// The name of the collection rule for which a detailed description should be provided. - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. + [EndpointSummary("Gets detailed information about the current state of the specified collection rule.")] [HttpGet("collectionrules/{collectionRuleName}", Name = nameof(GetCollectionRuleDetailedDescription))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(CollectionRuleDetailedDescription), StatusCodes.Status200OK)] + [ProducesWithProblemDetails] + [ProducesResponseType(typeof(CollectionRuleDetailedDescription), StatusCodes.Status200OK, ContentTypes.ApplicationJson)] public Task> GetCollectionRuleDetailedDescription( + [Description("The name of the collection rule for which a detailed description should be provided.")] string collectionRuleName, [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null) { return InvokeForProcess(processInfo => @@ -566,9 +543,9 @@ public Task>> GetColl } [HttpPost("parameters", Name = nameof(CaptureParameters))] - [ProducesWithProblemDetails(ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] + [ProducesWithProblemDetails] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] [EgressValidation] public async Task CaptureParameters( @@ -612,9 +589,9 @@ public async Task CaptureParameters( } [HttpGet("stacks", Name = nameof(CaptureStacks))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson, ContentTypes.TextPlain, ContentTypes.ApplicationSpeedscopeJson)] + [ProducesWithProblemDetails] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status429TooManyRequests)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, ContentTypes.ApplicationJson, ContentTypes.TextPlain, ContentTypes.ApplicationSpeedscopeJson)] [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] [EgressValidation] public Task CaptureStacks( diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs index 84023a6960a..04da03907a8 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/ExceptionsController.cs @@ -12,6 +12,7 @@ using Microsoft.Net.Http.Headers; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Threading.Tasks; @@ -36,29 +37,27 @@ public ExceptionsController( _options = serviceProvider.GetRequiredService>(); } - /// - /// Gets the exceptions from the target process. - /// - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. - /// The egress provider to which the exceptions are saved. - /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. + [EndpointSummary("Gets the exceptions from the target process.")] [HttpGet("exceptions", Name = nameof(GetExceptions))] - [ProducesWithProblemDetails(ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] + [ProducesWithProblemDetails] + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] [EgressValidation] public Task GetExceptions( [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null, [FromQuery] + [Description("The egress provider to which the exceptions are saved.")] string? egressProvider = null, [FromQuery] + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) { if (!_options.Value.GetEnabled()) @@ -86,31 +85,29 @@ public Task GetExceptions( }, processKey, Utilities.ArtifactType_Exceptions); } - /// - /// Gets the exceptions from the target process. - /// - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. - /// The egress provider to which the exceptions are saved. - /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. - /// The exceptions configuration describing which exceptions to include in the response. + [EndpointSummary("Gets the exceptions from the target process.")] [HttpPost("exceptions", Name = nameof(CaptureExceptionsCustom))] - [ProducesWithProblemDetails(ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] + [ProducesWithProblemDetails] + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, ContentTypes.ApplicationNdJson, ContentTypes.ApplicationJsonSequence, ContentTypes.TextPlain)] [EgressValidation] public Task CaptureExceptionsCustom( [FromBody] + [Description("The exceptions configuration describing which exceptions to include in the response.")] ExceptionsConfiguration configuration, [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null, [FromQuery] + [Description("The egress provider to which the exceptions are saved.")] string? egressProvider = null, [FromQuery] + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) { if (!_options.Value.GetEnabled()) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs index 1b14cb49b6c..005485530b5 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/MetricsController.cs @@ -33,12 +33,10 @@ public MetricsController(ILogger logger, _metricsOptions = metricsOptions.Value; } - /// - /// Get a list of the current backlog of metrics for a process in the Prometheus exposition format. - /// + [EndpointSummary("Get a list of the current backlog of metrics for a process in the Prometheus exposition format.")] [HttpGet("metrics", Name = nameof(GetMetrics))] - [ProducesWithProblemDetails(ContentTypes.TextPlain_v0_0_4)] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] + [ProducesWithProblemDetails] + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, ContentTypes.TextPlain_v0_0_4)] public ActionResult GetMetrics() { return this.InvokeService(() => diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs index 9d6c9a3c570..bacd6849c70 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Controllers/OperationsController.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; +using System.ComponentModel; namespace Microsoft.Diagnostics.Monitoring.WebApi.Controllers { @@ -29,24 +30,22 @@ public OperationsController(ILogger logger, IServiceProvid _operationsStore = serviceProvider.GetRequiredService(); } - /// - /// Gets the operations list for the specified process (or all processes if left unspecified). - /// - /// Process ID used to identify the target process. - /// The Runtime instance cookie used to identify the target process. - /// Process name used to identify the target process. - /// An optional set of comma-separated identifiers users can include to make an operation easier to identify. [HttpGet(Name = nameof(GetOperations))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesWithProblemDetails] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK, ContentTypes.ApplicationJson)] + [EndpointSummary("Gets the operations list for the specified process (or all processes if left unspecified).")] public ActionResult> GetOperations( [FromQuery] + [Description("Process ID used to identify the target process.")] int? pid = null, [FromQuery] + [Description("The Runtime instance cookie used to identify the target process.")] Guid? uid = null, [FromQuery] + [Description("Process name used to identify the target process.")] string? name = null, [FromQuery] + [Description("An optional set of comma-separated identifiers users can include to make an operation easier to identify.")] string? tags = null) { ProcessKey? processKey = Utilities.GetProcessKey(pid, uid, name); @@ -58,9 +57,9 @@ public OperationsController(ILogger logger, IServiceProvid } [HttpGet("{operationId}", Name = nameof(GetOperationStatus))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] - [ProducesResponseType(typeof(Models.OperationStatus), StatusCodes.Status201Created)] - [ProducesResponseType(typeof(Models.OperationStatus), StatusCodes.Status200OK)] + [ProducesWithProblemDetails] + [ProducesResponseType(typeof(Models.OperationStatus), StatusCodes.Status201Created, ContentTypes.ApplicationJson)] + [ProducesResponseType(typeof(Models.OperationStatus), StatusCodes.Status200OK, ContentTypes.ApplicationJson)] public IActionResult GetOperationStatus(Guid operationId) { return this.InvokeService(() => @@ -72,7 +71,7 @@ public IActionResult GetOperationStatus(Guid operationId) } [HttpDelete("{operationId}", Name = nameof(CancelOperation))] - [ProducesWithProblemDetails(ContentTypes.ApplicationJson)] + [ProducesWithProblemDetails] [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] [ProducesResponseType(typeof(void), StatusCodes.Status202Accepted)] public IActionResult CancelOperation( diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDescription.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDescription.cs index 141163004d5..4c35c6ecb56 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDescription.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDescription.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Text.Json.Serialization; +using System.ComponentModel; namespace Microsoft.Diagnostics.Monitoring.WebApi.Models { @@ -13,9 +14,7 @@ public record class CollectionRuleDescription [JsonPropertyName("state")] public CollectionRuleState State { get; set; } - /// - /// Human-readable explanation for the current state of the collection rule. - /// + [Description("Human-readable explanation for the current state of the collection rule.")] [JsonPropertyName("stateReason")] public string? StateReason { get; set; } } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDetailedDescription.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDetailedDescription.cs index 744314e1f53..2e7f6dbc171 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDetailedDescription.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/CollectionRuleDetailedDescription.cs @@ -3,6 +3,7 @@ using System; using System.Text.Json.Serialization; +using System.ComponentModel; namespace Microsoft.Diagnostics.Monitoring.WebApi.Models { @@ -12,36 +13,42 @@ public record class CollectionRuleDetailedDescription : CollectionRuleDescriptio /// The number of times the trigger has executed for a process in its lifetime. /// [JsonPropertyName("lifetimeOccurrences")] + [Description("The number of times the trigger has executed for a process in its lifetime.")] public int LifetimeOccurrences { get; set; } /// /// The number of times the trigger has executed for a process in the current sliding window duration (as defined by Limits). /// [JsonPropertyName("slidingWindowOccurrences")] + [Description("The number of times the trigger has executed for a process in the current sliding window duration (as defined by Limits).")] public int SlidingWindowOccurrences { get; set; } /// /// The number of times the trigger can execute for a process before being limited (as defined by Limits). /// [JsonPropertyName("actionCountLimit")] + [Description("The number of times the trigger can execute for a process before being limited (as defined by Limits).")] public int ActionCountLimit { get; set; } /// /// The sliding window duration in which the actionCountLimit is the maximum number of occurrences (as defined by Limits). /// [JsonPropertyName("actionCountSlidingWindowDurationLimit")] + [Description("The sliding window duration in which the actionCountLimit is the maximum number of occurrences (as defined by Limits).")] public TimeSpan? ActionCountSlidingWindowDurationLimit { get; set; } /// /// The amount of time that needs to pass before the slidingWindowOccurrences drops below the actionCountLimit /// [JsonPropertyName("slidingWindowDurationCountdown")] + [Description("The amount of time that needs to pass before the slidingWindowOccurrences drops below the actionCountLimit")] public TimeSpan? SlidingWindowDurationCountdown { get; set; } /// /// The amount of time that needs to pass before the rule is finished /// [JsonPropertyName("ruleFinishedCountdown")] + [Description("The amount of time that needs to pass before the rule is finished")] public TimeSpan? RuleFinishedCountdown { get; set; } } } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/DotnetMonitorInfo.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/DotnetMonitorInfo.cs index 114a78ac13d..42db01d3fd7 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/DotnetMonitorInfo.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/DotnetMonitorInfo.cs @@ -2,21 +2,18 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Diagnostics.Monitoring.Options; +using System.ComponentModel; using System.Text.Json.Serialization; namespace Microsoft.Diagnostics.Monitoring.WebApi.Models { public class DotnetMonitorInfo { - /// - /// The dotnet monitor version. - /// + [Description("The dotnet monitor version.")] [JsonPropertyName("version")] public string? Version { get; set; } - /// - /// The dotnet runtime version. - /// + [Description("The dotnet runtime version.")] [JsonPropertyName("runtimeVersion")] public string? RuntimeVersion { get; set; } @@ -26,15 +23,11 @@ public class DotnetMonitorInfo [JsonPropertyName("diagnosticPortMode")] public DiagnosticPortConnectionMode DiagnosticPortMode { get; set; } - /// - /// The name of the named pipe or unix domain socket to use for connecting to the diagnostic server. - /// + [Description("The name of the named pipe or unix domain socket to use for connecting to the diagnostic server.")] [JsonPropertyName("diagnosticPortName")] public string? DiagnosticPortName { get; set; } - /// - /// The capabilities provided by dotnet-monitor. - /// + [Description("The capabilities provided by dotnet-monitor.")] [JsonPropertyName("capabilities")] public required MonitorCapability[] Capabilities { get; set; } } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/DumpType.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/DumpType.cs index ec06f9451a2..bd85a78b9cf 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/DumpType.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/DumpType.cs @@ -1,8 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Text.Json.Serialization; + namespace Microsoft.Diagnostics.Monitoring.WebApi.Models { + [JsonConverter(typeof(JsonStringEnumConverter))] public enum DumpType { Full = 1, diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EventMetricsConfiguration.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EventMetricsConfiguration.cs index fad168e9380..b966a07d664 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EventMetricsConfiguration.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EventMetricsConfiguration.cs @@ -25,6 +25,7 @@ public class EventMetricsConfiguration public class EventMetricsProvider { [Required] + [MinLength(1)] [JsonPropertyName("providerName")] public string ProviderName { get; set; } = string.Empty; @@ -35,6 +36,7 @@ public class EventMetricsProvider public class EventMetricsMeter { [Required] + [MinLength(1)] [JsonPropertyName("meterName")] public string MeterName { get; set; } = string.Empty; diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EventPipeProvider.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EventPipeProvider.cs index c631eca410b..3250a6a02de 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EventPipeProvider.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EventPipeProvider.cs @@ -18,6 +18,7 @@ public class EventPipeProvider { [JsonPropertyName("name")] [Required] + [MinLength(1)] public string Name { get; set; } = string.Empty; [JsonPropertyName("keywords")] @@ -28,6 +29,7 @@ public class EventPipeProvider [JsonPropertyName("eventLevel")] [EnumDataType(typeof(EventLevel))] + [JsonConverter(typeof(JsonStringEnumConverter))] public EventLevel EventLevel { get; set; } = EventLevel.Verbose; [JsonPropertyName("arguments")] diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/LogsConfiguration.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/LogsConfiguration.cs index 523378abd76..108f2bc435c 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/LogsConfiguration.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/LogsConfiguration.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging; using System.Collections.Generic; +using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Text.Json.Serialization; @@ -14,19 +15,16 @@ public class LogsConfiguration /// The default level at which logs are collected. /// [JsonPropertyName("logLevel")] + [JsonConverter(typeof(JsonStringEnumConverter))] [EnumDataType(typeof(LogLevel))] [Required] public LogLevel LogLevel { get; set; } = LogLevel.Warning; - /// - /// The logger categories and levels at which logs are collected. Setting the log level to null will have logs collected from the corresponding category at the level set in the LogLevel property. - /// + [Description("The logger categories and levels at which logs are collected. Setting the log level to null will have logs collected from the corresponding category at the level set in the LogLevel property.")] [JsonPropertyName("filterSpecs")] public Dictionary? FilterSpecs { get; set; } - /// - /// Set to true to collect logs at the application-defined categories and levels. - /// + [Description("Set to true to collect logs at the application-defined categories and levels.")] [JsonPropertyName("useAppFilters")] public bool UseAppFilters { get; set; } = true; } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/MethodDescription.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/MethodDescription.cs index 8a7b18afca0..0723dc5967d 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/MethodDescription.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/MethodDescription.cs @@ -14,12 +14,15 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi.Models public class MethodDescription : IMethodDescription { [Required] + [MinLength(1)] public string ModuleName { get; set; } = string.Empty; [Required] + [MinLength(1)] public string TypeName { get; set; } = string.Empty; [Required] + [MinLength(1)] public string MethodName { get; set; } = string.Empty; public override string ToString() => FormattableString.Invariant($"{ModuleName}!{TypeName}.{MethodName}"); diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/TraceProfile.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/TraceProfile.cs index ab76908e028..ba44e08aa86 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/TraceProfile.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/TraceProfile.cs @@ -2,9 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Text.Json.Serialization; namespace Microsoft.Diagnostics.Monitoring.WebApi.Models { + [JsonConverter(typeof(JsonStringEnumConverter))] [Flags] public enum TraceProfile { diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/ProducesWithProblemDetailsAttribute.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/ProducesWithProblemDetailsAttribute.cs index a039a4ab0cf..575e515d74f 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/ProducesWithProblemDetailsAttribute.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/ProducesWithProblemDetailsAttribute.cs @@ -8,38 +8,28 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi { /// - /// Overrides the behavior of the Produces attribute, which clears all content types from the result and - /// sets the content types from the attribute to the result. This attribute does the same except that if - /// the result is a Bad Request, then only add the application/problem+json content type to the result. + /// Filter that adds the application/problem+json content type to Bad Request results. /// /// /// This alleviates an issue where application/problem+json would never be returned if some other content - /// type, such as application/json, was also specified. The DefaultOutputFormatterSelector will format the - /// content using any acceptable content type, which both application/json and application/problem+json are - /// acceptable to the SystemTextJsonOutputFormatter, thus it chooses the first one: application/json. This - /// selection is incorrect for error results, which typically want application/problem+json. + /// type, such as application/json, was specified via ProducesAttribute. The DefaultOutputFormatterSelector + /// will format the content using any acceptable content type, which both application/json and + /// application/problem+json are acceptable to the SystemTextJsonOutputFormatter, thus it chooses the first + /// one: application/json. This selection is incorrect for error results, which typically want + /// application/problem+json. /// /// The intent of this attribute is to make sure that the output is unconditionally reported with a content /// type of application/problem+json if the result is a Bad Request. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] - public class ProducesWithProblemDetailsAttribute : ProducesAttribute + public class ProducesWithProblemDetailsAttribute : ResultFilterAttribute { - public ProducesWithProblemDetailsAttribute(string contentType, params string[] additionalContentTypes) - : base(contentType, additionalContentTypes) - { - } - public override void OnResultExecuting(ResultExecutingContext context) { if (context.Result is BadRequestObjectResult badRequestResult && badRequestResult.Value is ProblemDetails) { badRequestResult.ContentTypes.Add(WebApi.ContentTypes.ApplicationProblemJson); } - else - { - base.OnResultExecuting(context); - } } } } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj index 5668a50b1c6..06fea193981 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj @@ -3,10 +3,17 @@ Exe $(ToolTargetFrameworks) + ../../../documentation + --file-name openapi + + + + + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Program.cs index 41ee7d2f2cd..f110a75d751 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Program.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Program.cs @@ -3,13 +3,9 @@ using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.Auth; -using Microsoft.Diagnostics.Tools.Monitor.Swagger; +using Microsoft.Diagnostics.Tools.Monitor.OpenApi; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Swashbuckle.AspNetCore.Swagger; -using System; -using System.Globalization; -using System.IO; namespace Microsoft.Diagnostics.Monitoring.OpenApiGen { @@ -17,14 +13,6 @@ internal sealed class Program { public static void Main(string[] args) { - if (args.Length != 1) - { - throw new InvalidOperationException("Expected single argument for the output path."); - } - string outputPath = args[0]; - - // Create directory if it does not exist - Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); HostBuilderSettings settings = HostBuilderSettings.CreateMonitor( urls: null, @@ -41,18 +29,9 @@ public static void Main(string[] args) .CreateHostBuilder(settings) .ConfigureServices(services => { - services.AddSwaggerGen(options => options.ConfigureMonitorSwaggerGen()); + services.AddOpenApi(options => options.ConfigureMonitorOpenApiGen()); }) .Build(); - - // Serialize the OpenApi document - using StringWriter outputWriter = new(CultureInfo.InvariantCulture); - ISwaggerProvider provider = host.Services.GetRequiredService(); - provider.WriteTo(outputWriter); - outputWriter.Flush(); - - // Normalize line endings before writing - File.WriteAllText(outputPath, outputWriter.ToString().Replace("\r\n", "\n")); } } } diff --git a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyAuthConfigurator.cs b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyAuthConfigurator.cs index 8abb9236591..78763727c91 100644 --- a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyAuthConfigurator.cs +++ b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyAuthConfigurator.cs @@ -4,12 +4,12 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.OpenApi; using Microsoft.Diagnostics.Monitoring.WebApi; -using Microsoft.Diagnostics.Tools.Monitor.Swagger; +using Microsoft.Diagnostics.Tools.Monitor.OpenApi; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Swashbuckle.AspNetCore.SwaggerGen; using System; using System.Collections.Generic; @@ -60,7 +60,7 @@ public void ConfigureApiAuth(IServiceCollection services, HostBuilderContext con services.AddSingleton(); } - public void ConfigureSwaggerGenAuth(SwaggerGenOptions options) + public void ConfigureOpenApiGenAuth(OpenApiOptions options) { const string ApiKeySecurityDefinitionName = "ApiKeyAuth"; options.AddBearerTokenAuthOption(ApiKeySecurityDefinitionName); diff --git a/src/Tools/dotnet-monitor/Auth/AzureAd/AzureAdAuthConfigurator.cs b/src/Tools/dotnet-monitor/Auth/AzureAd/AzureAdAuthConfigurator.cs index 45d42d7ab09..deb89c182af 100644 --- a/src/Tools/dotnet-monitor/Auth/AzureAd/AzureAdAuthConfigurator.cs +++ b/src/Tools/dotnet-monitor/Auth/AzureAd/AzureAdAuthConfigurator.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.OpenApi; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Extensions.DependencyInjection; @@ -8,8 +9,8 @@ using Microsoft.Extensions.Logging; using Microsoft.Identity.Web; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; using System; +using System.Threading.Tasks; namespace Microsoft.Diagnostics.Tools.Monitor.Auth.AzureAd { @@ -47,34 +48,39 @@ public void ConfigureApiAuth(IServiceCollection services, HostBuilderContext con }); } - public void ConfigureSwaggerGenAuth(SwaggerGenOptions options) + public void ConfigureOpenApiGenAuth(OpenApiOptions options) { const string OAuth2SecurityDefinitionName = "OAuth2"; - + Uri baseEndpoint = new Uri(_azureAdOptions.GetInstance(), FormattableString.Invariant($"{_azureAdOptions.TenantId}/oauth2/v2.0/")); - options.AddSecurityDefinition(OAuth2SecurityDefinitionName, new OpenApiSecurityScheme + options.AddDocumentTransformer((document, context, cancellationToken) => { - Type = SecuritySchemeType.OAuth2, - Flows = new OpenApiOAuthFlows + document.Components.SecuritySchemes.Add(OAuth2SecurityDefinitionName, new OpenApiSecurityScheme { - AuthorizationCode = new OpenApiOAuthFlow + Type = SecuritySchemeType.OAuth2, + Flows = new OpenApiOAuthFlows { - AuthorizationUrl = new Uri(baseEndpoint, "authorize"), - TokenUrl = new Uri(baseEndpoint, "token") + AuthorizationCode = new OpenApiOAuthFlow + { + AuthorizationUrl = new Uri(baseEndpoint, "authorize"), + TokenUrl = new Uri(baseEndpoint, "token") + } } - } - }); + }); - options.AddSecurityRequirement(new OpenApiSecurityRequirement - { + document.SecurityRequirements.Add(new OpenApiSecurityRequirement { - new OpenApiSecurityScheme { - Reference = new OpenApiReference { Type= ReferenceType.SecurityScheme, Id = OAuth2SecurityDefinitionName } - }, - Array.Empty() - } + new OpenApiSecurityScheme + { + Reference = new OpenApiReference { Type= ReferenceType.SecurityScheme, Id = OAuth2SecurityDefinitionName } + }, + Array.Empty() + } + }); + + return Task.CompletedTask; }); } diff --git a/src/Tools/dotnet-monitor/Auth/IAuthenticationConfigurator.cs b/src/Tools/dotnet-monitor/Auth/IAuthenticationConfigurator.cs index 72a7e8e6994..81df6db62c6 100644 --- a/src/Tools/dotnet-monitor/Auth/IAuthenticationConfigurator.cs +++ b/src/Tools/dotnet-monitor/Auth/IAuthenticationConfigurator.cs @@ -1,10 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.OpenApi; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Swashbuckle.AspNetCore.SwaggerGen; using System; namespace Microsoft.Diagnostics.Tools.Monitor.Auth @@ -12,7 +12,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.Auth internal interface IAuthenticationConfigurator { void ConfigureApiAuth(IServiceCollection services, HostBuilderContext context); - void ConfigureSwaggerGenAuth(SwaggerGenOptions options); + void ConfigureOpenApiGenAuth(OpenApiOptions options); IStartupLogger CreateStartupLogger(ILogger logger, IServiceProvider serviceProvider); } } diff --git a/src/Tools/dotnet-monitor/Auth/NoAuth/NoAuthConfigurator.cs b/src/Tools/dotnet-monitor/Auth/NoAuth/NoAuthConfigurator.cs index c2d2f0dee89..9cf219d575a 100644 --- a/src/Tools/dotnet-monitor/Auth/NoAuth/NoAuthConfigurator.cs +++ b/src/Tools/dotnet-monitor/Auth/NoAuth/NoAuthConfigurator.cs @@ -2,10 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.AspNetCore.OpenApi; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Swashbuckle.AspNetCore.SwaggerGen; using System; namespace Microsoft.Diagnostics.Tools.Monitor.Auth.NoAuth @@ -23,7 +23,7 @@ public void ConfigureApiAuth(IServiceCollection services, HostBuilderContext con }); } - public void ConfigureSwaggerGenAuth(SwaggerGenOptions options) + public void ConfigureOpenApiGenAuth(OpenApiOptions options) { } diff --git a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs index 6676b37de8b..c16dcb791d5 100644 --- a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs +++ b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs @@ -6,7 +6,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.Auth; using Microsoft.Diagnostics.Tools.Monitor.Stacks; -using Microsoft.Diagnostics.Tools.Monitor.Swagger; +using Microsoft.Diagnostics.Tools.Monitor.OpenApi; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -95,10 +95,9 @@ private static IHostBuilder Configure(this IHostBuilder builder, StartupAuthenti authConfigurator.ConfigureApiAuth(services, context); - services.AddSwaggerGen(options => - { - options.ConfigureMonitorSwaggerGen(); - authConfigurator.ConfigureSwaggerGenAuth(options); + services.AddOpenApi(options => { + options.ConfigureMonitorOpenApiGen(); + authConfigurator.ConfigureOpenApiGenAuth(options); }); services.ConfigureDiagnosticPort(context.Configuration); diff --git a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs new file mode 100644 index 00000000000..6c9951cc10a --- /dev/null +++ b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs @@ -0,0 +1,184 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.OpenApi; +using Microsoft.Diagnostics.Monitoring.Options; +using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers; +using Microsoft.Extensions.Logging; +using Microsoft.Net.Http.Headers; +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi +{ + internal static class OpenApiOptionsExtensions + { + public static void ConfigureMonitorOpenApiGen(this OpenApiOptions options) + { + options.AddDocumentTransformer(); + options.AddDocumentTransformer(); + options.AddDocumentTransformer(); + + options.AddOperationTransformer(); + options.AddOperationTransformer(); + options.AddOperationTransformer(); + options.AddOperationTransformer(); + + // Make sure TimeSpan is represented as a string instead of a full object type + options.AddSchemaTransformer((schema, context, cancellationToken) => { + if (context.JsonTypeInfo.Type == typeof(TimeSpan?)) + { + schema.Type = "string"; + schema.Format = "time-span"; + schema.Example = new OpenApiString("00:00:30"); + schema.Pattern = null; + } + return Task.CompletedTask; + }); + + // Make sure FileResult is represented as a string with binary format + options.AddSchemaTransformer((schema, context, cancellationToken) => { + if (context.JsonTypeInfo.Type == typeof(FileResult)) + { + schema.Reference = null; + schema.Type = "string"; + schema.Format = "binary"; + schema.Properties = new Dictionary(); + } + return Task.CompletedTask; + }); + + // Make sure FileResult schema is inlined + options.CreateSchemaReferenceId = (type) => + type.Type == typeof(FileResult) ? null : OpenApiOptions.CreateDefaultSchemaReferenceId(type); + + // Fix up nullable and uniqueItems + options.AddSchemaTransformer((schema, context, cancellationToken) => { + var type = context.JsonTypeInfo.Type; + if (type == typeof(DotnetMonitorInfo)) + { + schema.Properties["capabilities"].Nullable = true; + } + else if (type == typeof(ExceptionsConfiguration)) + { + schema.Properties["include"].Nullable = true; + schema.Properties["exclude"].Nullable = true; + } + else if (type == typeof(ValidationProblemDetails)) + { + schema.Properties["errors"].Nullable = true; + } + else if (type == typeof(OperationStatus) || + type == typeof(OperationSummary)) + { + schema.Properties["tags"].UniqueItems = true; + } + return Task.CompletedTask; + }); + + // Fix up "additionalProperties" + options.AddSchemaTransformer((schema, context, cancellationToken) => { + var type = context.JsonTypeInfo.Type; + if (type == typeof(CaptureParametersConfiguration) || + type == typeof(CollectionRuleDescription) || + type == typeof(CollectionRuleDetailedDescription) || + type == typeof(DotnetMonitorInfo) || + type == typeof(EventMetricsConfiguration) || + type == typeof(EventMetricsMeter) || + type == typeof(EventMetricsProvider) || + type == typeof(EventPipeConfiguration) || + type == typeof(EventPipeProvider) || + type == typeof(ExceptionFilter) || + type == typeof(ExceptionsConfiguration) || + type == typeof(MethodDescription) || + type == typeof(MonitorCapability) || + type == typeof(OperationError) || + type == typeof(OperationProcessInfo) || + type == typeof(OperationStatus) || + type == typeof(OperationSummary) || + type == typeof(ProcessIdentifier) || + type == typeof(ProcessInfo)) + { + schema.AdditionalPropertiesAllowed = false; + } + else if (type == typeof(ProblemDetails) || + type == typeof(ValidationProblemDetails)) + { + schema.AdditionalProperties = new OpenApiSchema(); + } + else if (type == typeof(LogsConfiguration)) + { + schema.AdditionalPropertiesAllowed = false; + schema.Properties["filterSpecs"].AdditionalProperties = new OpenApiSchema + { + Reference = new OpenApiReference + { + Type = ReferenceType.Schema, + Id = nameof(LogLevel) + } + }; + } + return Task.CompletedTask; + }); + + // Add missing descriptions on types + options.AddSchemaTransformer((schema, context, cancellationToken) => { + var type = context.JsonTypeInfo.Type; + if (type == typeof(OperationProcessInfo)) + { + schema.Description = "Represents the details of a given process used in an operation."; + } + else if (type == typeof(OperationStatus)) + { + schema.Description = "Represents the state of a long running operation. Used for all types of results, including successes and failures."; + } + else if (type == typeof(OperationSummary)) + { + schema.Description = "Represents a partial model when enumerating all operations."; + } + return Task.CompletedTask; + }); + + options.AddDocumentTransformer((document, context, cancellationToken) => { + document.Info.Title = "dotnet-monitor"; + document.Info.Version = "1.0"; + return Task.CompletedTask; + }); + } + + public static void AddBearerTokenAuthOption(this OpenApiOptions options, string securityDefinitionName) + { + options.AddDocumentTransformer((document, context, cancellationToken) => + { + document.Components.SecuritySchemes.Add(securityDefinitionName, new OpenApiSecurityScheme + { + Name = HeaderNames.Authorization, + Type = SecuritySchemeType.ApiKey, + Scheme = JwtBearerDefaults.AuthenticationScheme, + BearerFormat = "JWT", + In = ParameterLocation.Header, + Description = Strings.HelpDescription_SecurityDefinitionDescription_ApiKey + }); + + document.SecurityRequirements.Add(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = securityDefinitionName } + }, + Array.Empty() + } + }); + + return Task.CompletedTask; + }); + } + } +} diff --git a/src/Tools/dotnet-monitor/Swagger/ResponseNames.cs b/src/Tools/dotnet-monitor/OpenApi/ResponseNames.cs similarity index 89% rename from src/Tools/dotnet-monitor/Swagger/ResponseNames.cs rename to src/Tools/dotnet-monitor/OpenApi/ResponseNames.cs index 8dfa5710382..8d8fc465e18 100644 --- a/src/Tools/dotnet-monitor/Swagger/ResponseNames.cs +++ b/src/Tools/dotnet-monitor/OpenApi/ResponseNames.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi { internal static class ResponseNames { diff --git a/src/Tools/dotnet-monitor/Swagger/StatusCodeStrings.cs b/src/Tools/dotnet-monitor/OpenApi/StatusCodeStrings.cs similarity index 78% rename from src/Tools/dotnet-monitor/Swagger/StatusCodeStrings.cs rename to src/Tools/dotnet-monitor/OpenApi/StatusCodeStrings.cs index 3ccc27573d5..2d5f72ac49d 100644 --- a/src/Tools/dotnet-monitor/Swagger/StatusCodeStrings.cs +++ b/src/Tools/dotnet-monitor/OpenApi/StatusCodeStrings.cs @@ -4,10 +4,11 @@ using Microsoft.AspNetCore.Http; using System.Globalization; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi { internal static class StatusCodeStrings { + public static readonly string Status202Accepted = StatusCodes.Status202Accepted.ToString(CultureInfo.InvariantCulture); public static readonly string Status400BadRequest = StatusCodes.Status400BadRequest.ToString(CultureInfo.InvariantCulture); public static readonly string Status401Unauthorized = StatusCodes.Status401Unauthorized.ToString(CultureInfo.InvariantCulture); public static readonly string Status429TooManyRequests = StatusCodes.Status429TooManyRequests.ToString(CultureInfo.InvariantCulture); diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/BadRequestResponseDocumentFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/BadRequestResponseDocumentTransformer.cs similarity index 68% rename from src/Tools/dotnet-monitor/Swagger/Filters/BadRequestResponseDocumentFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/BadRequestResponseDocumentTransformer.cs index a30ad0e38cc..95c88a1633e 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/BadRequestResponseDocumentFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/BadRequestResponseDocumentTransformer.cs @@ -2,18 +2,20 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.OpenApi; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { /// /// Adds an BadRequestResponse response component to the document. /// - internal sealed class BadRequestResponseDocumentFilter : IDocumentFilter + internal sealed class BadRequestResponseDocumentTransformer : IOpenApiDocumentTransformer { - public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) + public Task TransformAsync(OpenApiDocument openApiDoc, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken) { OpenApiResponse unauthorizedResponse = new(); unauthorizedResponse.Description = "Bad Request"; @@ -31,9 +33,11 @@ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) } }); - swaggerDoc.Components.Responses.Add( + (openApiDoc.Components ??= new OpenApiComponents()).Responses.Add( ResponseNames.BadRequestResponse, unauthorizedResponse); + + return Task.CompletedTask; } } } diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/BadRequestResponseOperationFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/BadRequestResponseOperationTransformer.cs similarity index 67% rename from src/Tools/dotnet-monitor/Swagger/Filters/BadRequestResponseOperationFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/BadRequestResponseOperationTransformer.cs index 1c21b56e58c..a4058efbb79 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/BadRequestResponseOperationFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/BadRequestResponseOperationTransformer.cs @@ -1,18 +1,20 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.OpenApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { /// /// Clears all content of the 400 response and adds a reference to the - /// BadRequestResponse response component . + /// BadRequestResponse response component . /// - internal sealed class BadRequestResponseOperationFilter : IOperationFilter + internal sealed class BadRequestResponseOperationTransformer : IOpenApiOperationTransformer { - public void Apply(OpenApiOperation operation, OperationFilterContext context) + public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransformerContext context, CancellationToken cancellationToken) { if (operation.Responses.Remove(StatusCodeStrings.Status400BadRequest)) { @@ -27,6 +29,8 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) } }); } + + return Task.CompletedTask; } } } diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/RemoveFailureContentTypesOperationFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/RemoveFailureContentTypesOperationTransformer.cs similarity index 63% rename from src/Tools/dotnet-monitor/Swagger/Filters/RemoveFailureContentTypesOperationFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/RemoveFailureContentTypesOperationTransformer.cs index ff8a00784e8..b31accec19b 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/RemoveFailureContentTypesOperationFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/RemoveFailureContentTypesOperationTransformer.cs @@ -1,19 +1,21 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.OpenApi; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { /// /// Removes failure content types (e.g. application/problem+json) from success operations. /// - internal sealed class RemoveFailureContentTypesOperationFilter : IOperationFilter + internal sealed class RemoveFailureContentTypesOperationTransformer : IOpenApiOperationTransformer { - public void Apply(OpenApiOperation operation, OperationFilterContext context) + public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransformerContext context, CancellationToken cancellationToken) { foreach (KeyValuePair response in operation.Responses) { @@ -22,6 +24,8 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) response.Value.Content.Remove(ContentTypes.ApplicationProblemJson); } } + + return Task.CompletedTask; } } } diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/TooManyRequestsResponseDocumentFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/TooManyRequestsResponseDocumentTransformer.cs similarity index 66% rename from src/Tools/dotnet-monitor/Swagger/Filters/TooManyRequestsResponseDocumentFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/TooManyRequestsResponseDocumentTransformer.cs index db978cbe210..94128b2257b 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/TooManyRequestsResponseDocumentFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/TooManyRequestsResponseDocumentTransformer.cs @@ -2,15 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.OpenApi; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { - internal sealed class TooManyRequestsResponseDocumentFilter : IDocumentFilter + internal sealed class TooManyRequestsResponseDocumentTransformer : IOpenApiDocumentTransformer { - public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) + public Task TransformAsync(OpenApiDocument openApiDoc, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken) { OpenApiResponse tooManyRequests = new(); tooManyRequests.Description = "TooManyRequests"; @@ -29,9 +31,11 @@ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) } }); - swaggerDoc.Components.Responses.Add( + openApiDoc.Components.Responses.Add( ResponseNames.TooManyRequestsResponse, tooManyRequests); + + return Task.CompletedTask; } } } diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/TooManyRequestsResponseOperationFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/TooManyRequestsResponseOperationTransformer.cs similarity index 64% rename from src/Tools/dotnet-monitor/Swagger/Filters/TooManyRequestsResponseOperationFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/TooManyRequestsResponseOperationTransformer.cs index eb57e961d6d..ddb3c00f0ee 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/TooManyRequestsResponseOperationFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/TooManyRequestsResponseOperationTransformer.cs @@ -1,14 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.OpenApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { - internal sealed class TooManyRequestsResponseOperationFilter : IOperationFilter + internal sealed class TooManyRequestsResponseOperationTransformer : IOpenApiOperationTransformer { - public void Apply(OpenApiOperation operation, OperationFilterContext context) + public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransformerContext context, CancellationToken cancellationToken) { if (operation.Responses.Remove(StatusCodeStrings.Status429TooManyRequests)) { @@ -23,6 +25,8 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) } }); } + + return Task.CompletedTask; } } } diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/UnauthorizedResponseDocumentFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/UnauthorizedResponseDocumentTransformer.cs similarity index 60% rename from src/Tools/dotnet-monitor/Swagger/Filters/UnauthorizedResponseDocumentFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/UnauthorizedResponseDocumentTransformer.cs index 58267696f22..b901b86f924 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/UnauthorizedResponseDocumentFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/UnauthorizedResponseDocumentTransformer.cs @@ -1,17 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.OpenApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { /// /// Adds an UnauthorizedResponse response component to the document. /// - internal sealed class UnauthorizedResponseDocumentFilter : IDocumentFilter + internal sealed class UnauthorizedResponseDocumentTransformer : IOpenApiDocumentTransformer { - public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) + public Task TransformAsync(OpenApiDocument openApiDoc, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken) { OpenApiHeader authenticateHeader = new(); authenticateHeader.Schema = new OpenApiSchema() { Type = "string" }; @@ -20,9 +22,11 @@ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) unauthorizedResponse.Description = "Unauthorized"; unauthorizedResponse.Headers.Add("WWW_Authenticate", authenticateHeader); - swaggerDoc.Components.Responses.Add( + openApiDoc.Components.Responses.Add( ResponseNames.UnauthorizedResponse, unauthorizedResponse); + + return Task.CompletedTask; } } } diff --git a/src/Tools/dotnet-monitor/Swagger/Filters/UnauthorizedResponseOperationFilter.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/UnauthorizedResponseOperationTransformer.cs similarity index 64% rename from src/Tools/dotnet-monitor/Swagger/Filters/UnauthorizedResponseOperationFilter.cs rename to src/Tools/dotnet-monitor/OpenApi/Transformers/UnauthorizedResponseOperationTransformer.cs index 7a491fe7f3f..e6aae23e9f1 100644 --- a/src/Tools/dotnet-monitor/Swagger/Filters/UnauthorizedResponseOperationFilter.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/UnauthorizedResponseOperationTransformer.cs @@ -1,18 +1,20 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.OpenApi; using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; +using System.Threading; +using System.Threading.Tasks; -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters +namespace Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers { /// /// Clears all content of the 401 response and adds a reference to the - /// UnauthorizedResponse response component . + /// UnauthorizedResponse response component . /// - internal sealed class UnauthorizedResponseOperationFilter : IOperationFilter + internal sealed class UnauthorizedResponseOperationTransformer : IOpenApiOperationTransformer { - public void Apply(OpenApiOperation operation, OperationFilterContext context) + public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransformerContext context, CancellationToken cancellationToken) { if (operation.Responses.TryGetValue(StatusCodeStrings.Status401Unauthorized, out OpenApiResponse? unauthorizedResponse)) { @@ -23,6 +25,8 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) Type = ReferenceType.Response }; } + + return Task.CompletedTask; } } } diff --git a/src/Tools/dotnet-monitor/Startup.cs b/src/Tools/dotnet-monitor/Startup.cs index 9253658b750..cd86312a1f8 100644 --- a/src/Tools/dotnet-monitor/Startup.cs +++ b/src/Tools/dotnet-monitor/Startup.cs @@ -3,19 +3,15 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.ResponseCompression; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Controllers; -using Microsoft.Diagnostics.Tools.Monitor.Swagger; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; -using Swashbuckle.AspNetCore.Swagger; using System.Collections.Generic; -using System.IO; using System.IO.Compression; using System.Text.Json.Serialization; @@ -84,8 +80,6 @@ public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, I app.UseHsts(); } - app.UseSwagger(); - app.UseRouting(); app.UseAuthentication(); @@ -104,12 +98,7 @@ public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, I { builder.MapControllers(); - builder.MapGet("/", (HttpResponse response, ISwaggerProvider provider) => - { - using Stream stream = response.BodyWriter.AsStream(true); - - provider.WriteTo(stream); - }); + builder.MapOpenApi("/"); }); } } diff --git a/src/Tools/dotnet-monitor/Swagger/SwaggerGenOptionsExtensions.cs b/src/Tools/dotnet-monitor/Swagger/SwaggerGenOptionsExtensions.cs deleted file mode 100644 index 82943dccd6c..00000000000 --- a/src/Tools/dotnet-monitor/Swagger/SwaggerGenOptionsExtensions.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.Diagnostics.Monitoring.WebApi.Controllers; -using Microsoft.Diagnostics.Tools.Monitor.Swagger.Filters; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Net.Http.Headers; -using Microsoft.OpenApi.Any; -using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; -using System; -using System.Reflection; -using System.Xml.XPath; - -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger -{ - internal static class SwaggerGenOptionsExtensions - { - public static void ConfigureMonitorSwaggerGen(this SwaggerGenOptions options) - { - options.DocumentFilter(); - options.DocumentFilter(); - options.DocumentFilter(); - - options.OperationFilter(); - options.OperationFilter(); - options.OperationFilter(); - options.OperationFilter(); - - string documentationFile = $"{typeof(DiagController).Assembly.GetName().Name}.xml"; -#nullable disable - options.IncludeXmlComments(() => new XPathDocument(Assembly.GetExecutingAssembly().GetManifestResourceStream(documentationFile))); -#nullable restore - // Make sure TimeSpan is represented as a string instead of a full object type - options.MapType(() => new OpenApiSchema() { Type = "string", Format = "time-span", Example = new OpenApiString("00:00:30") }); - } - - public static void AddBearerTokenAuthOption(this SwaggerGenOptions options, string securityDefinitionName) - { - options.AddSecurityDefinition(securityDefinitionName, new OpenApiSecurityScheme - { - Name = HeaderNames.Authorization, - Type = SecuritySchemeType.ApiKey, - Scheme = JwtBearerDefaults.AuthenticationScheme, - BearerFormat = "JWT", - In = ParameterLocation.Header, - Description = Strings.HelpDescription_SecurityDefinitionDescription_ApiKey - }); - - options.AddSecurityRequirement(new OpenApiSecurityRequirement - { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = securityDefinitionName } - }, - Array.Empty() - } - }); - } - } -} diff --git a/src/Tools/dotnet-monitor/Swagger/SwaggerProviderExtensions.cs b/src/Tools/dotnet-monitor/Swagger/SwaggerProviderExtensions.cs deleted file mode 100644 index b99b5c60cc7..00000000000 --- a/src/Tools/dotnet-monitor/Swagger/SwaggerProviderExtensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.OpenApi.Models; -using Microsoft.OpenApi.Writers; -using Swashbuckle.AspNetCore.Swagger; -using System.IO; - -namespace Microsoft.Diagnostics.Tools.Monitor.Swagger -{ - internal static class SwaggerProviderExtensions - { - public static void WriteTo(this ISwaggerProvider provider, Stream stream) - { - using StreamWriter writer = new(stream); - - provider.WriteTo(writer); - } - - public static void WriteTo(this ISwaggerProvider provider, TextWriter writer) - { - OpenApiDocument document = provider.GetSwagger("v1"); - - document.SerializeAsV3(new OpenApiJsonWriter(writer)); - } - } -} diff --git a/src/Tools/dotnet-monitor/dotnet-monitor.csproj b/src/Tools/dotnet-monitor/dotnet-monitor.csproj index 3b881f6617a..7318574cb26 100644 --- a/src/Tools/dotnet-monitor/dotnet-monitor.csproj +++ b/src/Tools/dotnet-monitor/dotnet-monitor.csproj @@ -1,4 +1,4 @@ - + $(ToolTargetFrameworks) Microsoft.Diagnostics.Tools.Monitor @@ -16,7 +16,7 @@ - + From 65e7f3e3043a36191560194a0f4f99e886cd2c29 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 14 Mar 2025 20:31:18 +0000 Subject: [PATCH 072/174] Fix Microsoft.Diagnostics.Monitoring.Options build for net6/7 --- .../CollectionRuleState.cs | 4 ++++ .../DiagnosticPortConnectionMode.cs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/CollectionRuleState.cs b/src/Microsoft.Diagnostics.Monitoring.Options/CollectionRuleState.cs index 1f4562765b7..72c7fb0139c 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/CollectionRuleState.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/CollectionRuleState.cs @@ -1,11 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#if NET8_0_OR_GREATER using System.Text.Json.Serialization; +#endif namespace Microsoft.Diagnostics.Monitoring.WebApi { +#if NET8_0_OR_GREATER [JsonConverter(typeof(JsonStringEnumConverter))] +#endif public enum CollectionRuleState { Running, diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortConnectionMode.cs b/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortConnectionMode.cs index 56799fd2ceb..871c062ff16 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortConnectionMode.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortConnectionMode.cs @@ -1,11 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#if NET8_0_OR_GREATER using System.Text.Json.Serialization; +#endif namespace Microsoft.Diagnostics.Monitoring.WebApi { +#if NET8_0_OR_GREATER [JsonConverter(typeof(JsonStringEnumConverter))] +#endif public enum DiagnosticPortConnectionMode { Connect, From 236b8d09a59a55342b5aff82be6d92b52a48d567 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 14 Mar 2025 20:51:29 +0000 Subject: [PATCH 073/174] Polyfill EndpointSummaryAttribute --- .../EndpointSummaryAttribute.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/Microsoft.Diagnostics.Monitoring.WebApi/Microsoft.AspNetCore.Http/EndpointSummaryAttribute.cs diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Microsoft.AspNetCore.Http/EndpointSummaryAttribute.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Microsoft.AspNetCore.Http/EndpointSummaryAttribute.cs new file mode 100644 index 00000000000..6a9695811f5 --- /dev/null +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Microsoft.AspNetCore.Http/EndpointSummaryAttribute.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#if !NET7_0_OR_GREATER + +using System; +using System.Diagnostics; + +namespace Microsoft.AspNetCore.Http; + +/// +/// Specifies a summary in . +/// +[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] +[DebuggerDisplay("{ToString(),nq}")] +public sealed class EndpointSummaryAttribute : Attribute +{ + /// + /// Initializes an instance of the . + /// + /// The summary associated with the endpoint or parameter. + public EndpointSummaryAttribute(string summary) + { + Summary = summary; + } + + /// + public string Summary { get; } +} + +#endif From a45bfc13acb0d5f490d43064168755825aaba669 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 14 Mar 2025 22:31:12 +0000 Subject: [PATCH 074/174] Fix incorrect ref for ExceptionFilter --- .../dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs index 6c9951cc10a..fa314b66ce8 100644 --- a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs @@ -69,6 +69,14 @@ public static void ConfigureMonitorOpenApiGen(this OpenApiOptions options) { schema.Properties["include"].Nullable = true; schema.Properties["exclude"].Nullable = true; + + // Work around an issue where the OpenApi generator outputs an incorrect ref for the + // "exclude" ExceptionFilter when running on .NET 9.0. + schema.Properties["exclude"].Items.Reference = new OpenApiReference + { + Type = ReferenceType.Schema, + Id = nameof(ExceptionFilter) + }; } else if (type == typeof(ValidationProblemDetails)) { From 31a68e6d1b5a8e59f169c2ab90748ec16d2d2e7a Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 14 Mar 2025 22:31:31 +0000 Subject: [PATCH 075/174] Avoid default value of null for non-nullable parameters --- .../OpenApi/OpenApiOptionsExtensions.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs index fa314b66ce8..9acb95cc832 100644 --- a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs @@ -90,6 +90,17 @@ public static void ConfigureMonitorOpenApiGen(this OpenApiOptions options) return Task.CompletedTask; }); + // The OpenApi generator doesn't make nullable properties nullable in the schema, + // but it does set the default value to null when the parameter had a default value of null. + // This produces an invalid schema. To fix this, avoid setting a default value of null for non-nullable schemas. + options.AddSchemaTransformer((schema, context, cancellationToken) => { + if (!schema.Nullable && schema.Default is OpenApiNull) + { + schema.Default = null; + } + return Task.CompletedTask; + }); + // Fix up "additionalProperties" options.AddSchemaTransformer((schema, context, cancellationToken) => { var type = context.JsonTypeInfo.Type; From e36ed42cd7d1be95186d1150f1bad2d21871b536 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Sat, 15 Mar 2025 00:13:27 +0000 Subject: [PATCH 076/174] Update openapi.json --- documentation/openapi.json | 231 +++++++++++++------------------------ 1 file changed, 77 insertions(+), 154 deletions(-) diff --git a/documentation/openapi.json b/documentation/openapi.json index a6535e2a37e..14cd4c1247c 100644 --- a/documentation/openapi.json +++ b/documentation/openapi.json @@ -49,8 +49,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -59,8 +58,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -68,8 +66,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -107,8 +104,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -117,8 +113,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -126,8 +121,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -168,8 +162,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -178,8 +171,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -187,8 +179,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -210,8 +201,7 @@ "in": "query", "description": "The egress provider to which the dump is saved.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -219,8 +209,7 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -265,8 +254,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -275,8 +263,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -284,8 +271,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -293,8 +279,7 @@ "in": "query", "description": "The egress provider to which the GC dump is saved.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -302,8 +287,7 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -348,8 +332,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -358,8 +341,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -367,8 +349,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -397,8 +378,7 @@ "in": "query", "description": "The egress provider to which the trace is saved.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -406,8 +386,7 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -450,8 +429,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -460,8 +438,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -469,8 +446,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -490,8 +466,7 @@ "in": "query", "description": "The egress provider to which the trace is saved.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -499,8 +474,7 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -566,8 +540,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -576,8 +549,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -585,8 +557,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -606,8 +577,7 @@ "in": "query", "description": "The level of the logs to capture.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -615,8 +585,7 @@ "in": "query", "description": "The egress provider to which the logs are saved.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -624,8 +593,7 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -677,8 +645,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -687,8 +654,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -696,8 +662,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -717,8 +682,7 @@ "in": "query", "description": "The egress provider to which the logs are saved.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -726,8 +690,7 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -829,8 +792,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -839,8 +801,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -848,8 +809,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -899,8 +859,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -909,8 +868,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -918,8 +876,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -966,8 +923,7 @@ "in": "query", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -975,32 +931,28 @@ "in": "query", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { "name": "name", "in": "query", "schema": { - "type": "string", - "default": null + "type": "string" } }, { "name": "egressProvider", "in": "query", "schema": { - "type": "string", - "default": null + "type": "string" } }, { "name": "tags", "in": "query", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -1072,8 +1024,7 @@ "in": "query", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -1081,32 +1032,28 @@ "in": "query", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { "name": "name", "in": "query", "schema": { - "type": "string", - "default": null + "type": "string" } }, { "name": "egressProvider", "in": "query", "schema": { - "type": "string", - "default": null + "type": "string" } }, { "name": "tags", "in": "query", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -1160,8 +1107,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -1170,8 +1116,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -1179,8 +1124,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -1200,8 +1144,7 @@ "in": "query", "description": "The egress provider to which the metrics are saved.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -1209,8 +1152,7 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -1252,8 +1194,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -1262,8 +1203,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -1271,8 +1211,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -1292,8 +1231,7 @@ "in": "query", "description": "The egress provider to which the metrics are saved.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -1301,8 +1239,7 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -1367,8 +1304,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -1377,8 +1313,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -1386,8 +1321,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -1395,8 +1329,7 @@ "in": "query", "description": "The egress provider to which the exceptions are saved.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -1404,8 +1337,7 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -1451,8 +1383,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -1461,8 +1392,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -1470,8 +1400,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -1479,8 +1408,7 @@ "in": "query", "description": "The egress provider to which the exceptions are saved.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -1488,8 +1416,7 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], @@ -1579,8 +1506,7 @@ "description": "Process ID used to identify the target process.", "schema": { "type": "integer", - "format": "int32", - "default": null + "format": "int32" } }, { @@ -1589,8 +1515,7 @@ "description": "The Runtime instance cookie used to identify the target process.", "schema": { "type": "string", - "format": "uuid", - "default": null + "format": "uuid" } }, { @@ -1598,8 +1523,7 @@ "in": "query", "description": "Process name used to identify the target process.", "schema": { - "type": "string", - "default": null + "type": "string" } }, { @@ -1607,8 +1531,7 @@ "in": "query", "description": "An optional set of comma-separated identifiers users can include to make an operation easier to identify.", "schema": { - "type": "string", - "default": null + "type": "string" } } ], From 8b138b795a6031d5a1dbe1ab08986c8e64cf53f5 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Sat, 15 Mar 2025 00:13:54 +0000 Subject: [PATCH 077/174] Remove swagger FileSignInfo --- eng/Signing.props | 2 -- 1 file changed, 2 deletions(-) diff --git a/eng/Signing.props b/eng/Signing.props index 7f295f84768..6b1ca519403 100644 --- a/eng/Signing.props +++ b/eng/Signing.props @@ -5,8 +5,6 @@ - - diff --git a/eng/dependabot/net10.0/Versions.props b/eng/dependabot/net10.0/Versions.props index a230538cfbd..8d1f67cd5df 100644 --- a/eng/dependabot/net10.0/Versions.props +++ b/eng/dependabot/net10.0/Versions.props @@ -2,7 +2,7 @@ - 10.0.0-alpha.1.25070.4 + 10.0.0-preview.4.25174.9 $(MicrosoftNETCoreApp100Version) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Program.cs index 12f6cb1984a..bcea4ebd754 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Program.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Program.cs @@ -82,7 +82,7 @@ private static async Task GetOpenApiDocument(IHost host) var documentService = GetDocumentService(host.Services); var methodInfo = documentService.GetType().GetMethod("GetOpenApiDocumentAsync", BindingFlags.Public | BindingFlags.Instance)!; - object result = methodInfo.Invoke(documentService, new object?[] { host.Services, default(CancellationToken) })!; + object result = methodInfo.Invoke(documentService, [host.Services, null, default(CancellationToken)])!; return await (Task)result; } diff --git a/src/Tools/dotnet-monitor/Auth/AzureAd/AzureAdAuthConfigurator.cs b/src/Tools/dotnet-monitor/Auth/AzureAd/AzureAdAuthConfigurator.cs index 34d5c2d3480..d2a9c9c27cb 100644 --- a/src/Tools/dotnet-monitor/Auth/AzureAd/AzureAdAuthConfigurator.cs +++ b/src/Tools/dotnet-monitor/Auth/AzureAd/AzureAdAuthConfigurator.cs @@ -74,7 +74,7 @@ public void ConfigureOpenApiGenAuth(OpenApiOptions options) } }); - var securityRequirements = document.SecurityRequirements ??= new List(); + var securityRequirements = document.Security ??= new List(); securityRequirements.Add(new OpenApiSecurityRequirement { { diff --git a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs index 50d3c0988ee..5dac332cff1 100644 --- a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs @@ -41,8 +41,6 @@ public static void ConfigureMonitorOpenApiGen(this OpenApiOptions options) if (context.JsonTypeInfo.Type == typeof(TimeSpan?)) { schema.Format = "time-span"; - // Updating to Microsoft.OpenApi 2.0.0-preview11 should fix the serialized Example: - // https://github.com/microsoft/OpenAPI.NET/issues/2137 schema.Example = JsonValue.Create("00:00:30"); schema.Pattern = null; } @@ -254,7 +252,7 @@ public static void AddBearerTokenAuthOption(this OpenApiOptions options, string Description = Strings.HelpDescription_SecurityDefinitionDescription_ApiKey }); - var securityRequirements = document.SecurityRequirements ??= new List(); + var securityRequirements = document.Security ??= new List(); securityRequirements.Add(new OpenApiSecurityRequirement { { From b837fa14935dee38c4f0564b1021674738e972c4 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Thu, 27 Mar 2025 23:01:22 +0000 Subject: [PATCH 103/174] Fix ExceptionFilter schema Works around https://github.com/dotnet/aspnetcore/issues/61194. --- documentation/openapi.json | 15 +++++++++++++ .../OpenApi/OpenApiOptionsExtensions.cs | 22 +++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/documentation/openapi.json b/documentation/openapi.json index 653229e52ef..d93f298a835 100644 --- a/documentation/openapi.json +++ b/documentation/openapi.json @@ -1909,6 +1909,21 @@ "additionalProperties": false }, "ExceptionFilter": { + "type": "object", + "properties": { + "exceptionType": { + "type": "string" + }, + "moduleName": { + "type": "string" + }, + "typeName": { + "type": "string" + }, + "methodName": { + "type": "string" + } + }, "additionalProperties": false }, "ExceptionsConfiguration": { diff --git a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs index 5dac332cff1..96dcad87f5c 100644 --- a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs @@ -73,9 +73,28 @@ public static void ConfigureMonitorOpenApiGen(this OpenApiOptions options) }); // Make sure FileResult schema is inlined - options.CreateSchemaReferenceId = (type) => + options.CreateSchemaReferenceId = (type) => type.Type == typeof(FileResult) ? null : OpenApiOptions.CreateDefaultSchemaReferenceId(type); + // Fix ExceptionFilter schema to work around https://github.com/dotnet/aspnetcore/issues/61194 + options.AddDocumentTransformer((document, context, cancellationToken) => { + var components = document.Components ??= new OpenApiComponents(); + var schemas = components.Schemas ??= new Dictionary(); + schemas[nameof(ExceptionFilter)] = new OpenApiSchema + { + Type = JsonSchemaType.Object, + Properties = new Dictionary + { + { "exceptionType", new OpenApiSchema { Type = JsonSchemaType.String } }, + { "moduleName", new OpenApiSchema { Type = JsonSchemaType.String } }, + { "typeName", new OpenApiSchema { Type = JsonSchemaType.String } }, + { "methodName", new OpenApiSchema { Type = JsonSchemaType.String } } + }, + AdditionalPropertiesAllowed = false + }; + return Task.CompletedTask; + }); + // Fix up nullable and uniqueItems options.AddSchemaTransformer((schema, context, cancellationToken) => { var type = context.JsonTypeInfo.Type; @@ -144,7 +163,6 @@ public static void ConfigureMonitorOpenApiGen(this OpenApiOptions options) type == typeof(EventMetricsProvider) || type == typeof(EventPipeConfiguration) || type == typeof(EventPipeProvider) || - type == typeof(ExceptionFilter) || type == typeof(ExceptionsConfiguration) || type == typeof(MethodDescription) || type == typeof(MonitorCapability) || From 6e7d1edd2f79745fca8c44c5c0a436979321a70a Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 28 Mar 2025 15:59:27 +0000 Subject: [PATCH 104/174] Remove filterSpecs transform logic NullableOfLogLevel seems more accurate in the schema, and I didn't find a way to change this back to LogLevel with a transformer. --- .../OpenApi/OpenApiOptionsExtensions.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs index 96dcad87f5c..7e035ef5c30 100644 --- a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs @@ -163,7 +163,8 @@ public static void ConfigureMonitorOpenApiGen(this OpenApiOptions options) type == typeof(EventMetricsProvider) || type == typeof(EventPipeConfiguration) || type == typeof(EventPipeProvider) || - type == typeof(ExceptionsConfiguration) || + type == typeof(ExceptionsConfiguration) || + type == typeof(LogsConfiguration) || type == typeof(MethodDescription) || type == typeof(MonitorCapability) || type == typeof(OperationError) || @@ -180,14 +181,6 @@ public static void ConfigureMonitorOpenApiGen(this OpenApiOptions options) { schema.AdditionalProperties = new OpenApiSchema(); } - else if (type == typeof(LogsConfiguration)) - { - schema.AdditionalPropertiesAllowed = false; - // if (schema.Properties["filterSpecs"] is OpenApiSchema filterSpecsSchema) - // { - // filterSpecsSchema.AdditionalProperties = new OpenApiSchemaReference(nameof(LogLevel)); - // } - } else if (type == typeof(Dictionary)) { if (schema.AdditionalProperties is OpenApiSchema additionalProperties) From 976e770f044273221624903fecdba3616a6955d1 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Thu, 3 Apr 2025 18:01:19 +0000 Subject: [PATCH 105/174] Some cleanup --- eng/Versions.props | 2 +- .../CollectionRuleActions.UnitTests.csproj | 9 --------- .../Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj | 9 +-------- ...oft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj | 8 -------- ...icrosoft.Diagnostics.Monitoring.Tool.UnitTests.csproj | 8 -------- .../Auth/AzureAd/AzureAdAuthConfigurator.cs | 1 - src/Tools/dotnet-monitor/dotnet-monitor.csproj | 7 ------- 7 files changed, 2 insertions(+), 42 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index c2895f9fc9c..f6831659761 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -104,7 +104,7 @@ $(MicrosoftExtensionsConfigurationAbstractions70Version) $(MicrosoftExtensionsLogging70Version) $(MicrosoftExtensionsLoggingAbstractions70Version) - $(MicrosoftExte nsionsLoggingConsole70Version) + $(MicrosoftExtensionsLoggingConsole70Version) $(SystemTextJson80Version) diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj b/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj index 8c803190982..be245a94f1e 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj @@ -17,13 +17,4 @@ - - - - - - - - diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj index 6895135fb5a..d2c42a45a5f 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.OpenApiGen/Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj @@ -5,6 +5,7 @@ $(ToolTargetFrameworks) enable $(InterceptorsNamespaces);Microsoft.AspNetCore.OpenApi.Generated + true @@ -12,12 +13,4 @@ - - - - - - - diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj index 361247fd7a2..2fabab936f6 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj @@ -29,12 +29,4 @@ - - - - - - - diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj index e5653092eb8..a5b1c431be5 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj @@ -183,12 +183,4 @@ - - - - - - - diff --git a/src/Tools/dotnet-monitor/Auth/AzureAd/AzureAdAuthConfigurator.cs b/src/Tools/dotnet-monitor/Auth/AzureAd/AzureAdAuthConfigurator.cs index d8b7aa5a2d4..83a79029eb3 100644 --- a/src/Tools/dotnet-monitor/Auth/AzureAd/AzureAdAuthConfigurator.cs +++ b/src/Tools/dotnet-monitor/Auth/AzureAd/AzureAdAuthConfigurator.cs @@ -14,7 +14,6 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using System.Collections.Generic; namespace Microsoft.Diagnostics.Tools.Monitor.Auth.AzureAd { diff --git a/src/Tools/dotnet-monitor/dotnet-monitor.csproj b/src/Tools/dotnet-monitor/dotnet-monitor.csproj index 2253c13a6d8..fdaa8a04563 100644 --- a/src/Tools/dotnet-monitor/dotnet-monitor.csproj +++ b/src/Tools/dotnet-monitor/dotnet-monitor.csproj @@ -14,13 +14,6 @@ true - - - - - - From 042c0fbc541cc0550cda8248ad180dd7012348a7 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 4 Apr 2025 23:19:34 +0000 Subject: [PATCH 106/174] WIP validation source generator --- eng/Version.Details.xml | 8 +- eng/Versions.props | 10 +- eng/dependabot/net10.0/Versions.props | 3 +- global.json | 2 +- src/Directory.Build.targets | 18 ++ .../S3StorageEgressProviderOptions.cs | 2 + ...soft.Diagnostics.Monitoring.Options.csproj | 22 ++- .../HostRestrictionMiddleware.cs | 2 - .../Models/Activity.cs | 2 +- .../MonitorJsonSerializerContext.cs | 20 ++ .../CollectionRuleActions.UnitTests.csproj | 1 - .../GenerateDotNetHost.targets | 18 -- ...ics.Monitoring.Tool.FunctionalTests.csproj | 4 +- ...tics.Monitoring.Tool.UnitTestCommon.csproj | 1 - ...agnostics.Monitoring.Tool.UnitTests.csproj | 1 - ....Diagnostics.Monitoring.UnitTestApp.csproj | 20 +- src/Tools/Directory.Build.props | 2 +- .../Auth/ApiKey/GeneratedJwtKey.cs | 7 +- .../Auth/ApiKey/MonitorApiKeyPostConfigure.cs | 18 +- .../Auth/AuthConfiguratorFactory.cs | 12 +- .../Actions/CollectDumpAction.cs | 9 +- .../Actions/CollectExceptionsAction.cs | 19 +- .../Actions/CollectGCDumpAction.cs | 10 +- .../Actions/CollectLiveMetricsAction.cs | 8 +- .../Actions/CollectLogsAction.cs | 9 +- .../Actions/CollectStacksAction.cs | 9 +- .../Actions/CollectTraceAction.cs | 8 +- .../Actions/CollectionRuleActionOperations.cs | 13 -- .../CollectionRules/Actions/ExecuteAction.cs | 14 +- .../Actions/GetEnvironmentVariableAction.cs | 10 +- .../ICollectionRuleActionOperations.cs | 8 - .../Actions/LoadProfilerAction.cs | 10 +- .../Actions/SetEnvironmentVariableAction.cs | 10 +- .../CollectionRuleBindingHelper.cs | 172 ++++++++++++++++-- ...CollectionRulePostConfigureNamedOptions.cs | 7 +- .../TemplatesConfigureNamedOptions.cs | 7 +- .../Actions/CollectLiveMetricsOptions.cs | 2 + .../Actions/CollectLogsOptions.Validate.cs | 49 ----- .../Options/Actions/CollectLogsOptions.cs | 2 + .../Actions/CollectTraceOptions.Validate.cs | 17 -- .../Options/Actions/CollectTraceOptions.cs | 2 + .../CollectionRuleLimitsDefaultsOptions.cs | 3 + .../Options/CollectionRuleLimitsOptions.cs | 3 + .../Options/CollectionRuleOptions.Validate.cs | 56 ------ .../Options/CollectionRuleOptions.cs | 2 +- .../CollectionRuleTriggerDefaultsOptions.cs | 2 + .../Triggers/AspNetRequestCountOptions.cs | 9 +- .../Triggers/AspNetRequestDurationOptions.cs | 10 +- .../Triggers/AspNetResponseStatusOptions.cs | 10 +- .../Options/Triggers/EventCounterOptions.cs | 6 +- .../EventCounterShortcuts/CPUUsageOptions.cs | 6 +- .../GCHeapSizeOptions.cs | 6 +- .../ThreadpoolQueueLengthOptions.cs | 6 +- .../Options/Triggers/EventMeterOptions.cs | 6 +- .../Options/ValidationHelper.cs | 70 +++++-- .../CollectionRuleTriggerOperations.cs | 17 -- .../ICollectionRuleTriggerOperations.cs | 7 - .../Commands/CollectCommandHandler.cs | 4 +- .../Commands/GenerateApiKeyCommandHandler.cs | 9 +- .../DataAnnotationValidateOptions.cs | 31 ++-- .../Extension/EgressExtension.OutputParser.cs | 7 +- .../Egress/Extension/EgressExtension.cs | 25 ++- .../Extension/EgressExtensionFactory.cs | 10 +- .../Extension/ExtensionEgressPayload.cs | 2 +- .../EndpointInfo/ServerEndpointInfoSource.cs | 1 - .../Exceptions/ExceptionsOperation.cs | 7 +- .../Extensibility/ExtensionManifest.cs | 19 +- .../Extensibility/ExtensionMode.cs | 3 + .../OpenApi/OpenApiOptionsExtensions.cs | 1 + .../ServiceCollectionExtensions.cs | 9 +- src/Tools/dotnet-monitor/Startup.cs | 3 + src/Tools/dotnet-monitor/ValidatableTypes.cs | 20 ++ .../dotnet-monitor/dotnet-monitor.csproj | 34 +++- 73 files changed, 633 insertions(+), 339 deletions(-) create mode 100644 src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs delete mode 100644 src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs delete mode 100644 src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs create mode 100644 src/Tools/dotnet-monitor/ValidatableTypes.cs diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c0b10c278ce..793843b0778 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,6 +1,6 @@ - + https://github.com/dotnet/aspnetcore de35e2b0a0d8d5d1e307907983a6838da1092898 @@ -46,11 +46,11 @@ https://github.com/dotnet/diagnostics b1037b7cc1ef0b00a9032f19a83b074a00c9a4b8 - + https://github.com/dotnet/runtime 0a33e18a0bccc10a0c4646dbf5b0fc70cbb3aa44 - + https://github.com/dotnet/aspnetcore de35e2b0a0d8d5d1e307907983a6838da1092898 @@ -58,7 +58,7 @@ https://github.com/dotnet/sdk 9dee3cf508254bc3859d9cd2fe96aeb2ad1b9751 - + https://github.com/dotnet/runtime 0a33e18a0bccc10a0c4646dbf5b0fc70cbb3aa44 diff --git a/eng/Versions.props b/eng/Versions.props index f6831659761..8609f02a9ab 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -52,8 +52,8 @@ 10.0.0-beta.25202.1 10.0.0-beta.25202.1 - 10.0.0-preview.3.25172.1 - 10.0.0-preview.3.25172.1 + 10.0.0-preview.4.25181.4 + 10.0.0-preview.4.25181.4 2.0.0-beta5.25170.1 @@ -62,8 +62,8 @@ 10.0.0-preview.25076.4 - 10.0.0-preview.3.25171.5 - 10.0.0-preview.3.25171.5 + 10.0.0-preview.4.25174.9 + 10.0.0-preview.3.25174.9 10.0.100-preview.3.25201.16 @@ -131,7 +131,7 @@ $(MicrosoftAspNetCoreApp100Version) $(MicrosoftNETCoreApp100Version) $(MicrosoftNETCoreApp100Version) - $(MicrosoftNETCoreApp100Version) + $(MicrosoftExtensionsLoggingAbstractions100Version) $(MicrosoftNETCoreApp100Version) $(MicrosoftNETCoreApp100Version) $(MicrosoftAspNetCoreApp100Version) diff --git a/eng/dependabot/net10.0/Versions.props b/eng/dependabot/net10.0/Versions.props index 8d1f67cd5df..7f4fd2f3a7b 100644 --- a/eng/dependabot/net10.0/Versions.props +++ b/eng/dependabot/net10.0/Versions.props @@ -2,7 +2,6 @@ - 10.0.0-preview.4.25174.9 $(MicrosoftNETCoreApp100Version) @@ -13,5 +12,7 @@ $(MicrosoftNETCoreApp100Version) $(MicrosoftNETCoreApp100Version) + + 10.0.0-preview.4.25180.1 diff --git a/global.json b/global.json index 1795ac2bf64..ab0d52b9adc 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "tools": { - "dotnet": "10.0.100-preview.3.25178.6", + "dotnet": "10.0.100-preview.4.25202.23", "runtimes": { "aspnetcore": [ "$(MicrosoftAspNetCoreApp60Version)", diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 17f67465aef..adfedd89235 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -13,6 +13,24 @@ + + $(IntermediateOutputPath)/$(TargetFramework)/TestDotNetHost.g.cs + $(MicrosoftNETCoreApp31Version) + $(MicrosoftNETCoreApp50Version) + $(MicrosoftNETCoreApp60Version) + $(MicrosoftNETCoreApp70Version) + $(MicrosoftNETCoreApp80Version) + $(MicrosoftNETCoreApp90Version) + $(MicrosoftNETCoreApp100Version) + $(MicrosoftAspNetCoreApp31Version) + $(MicrosoftAspNetCoreApp50Version) + $(MicrosoftAspNetCoreApp60Version) + $(MicrosoftAspNetCoreApp70Version) + $(MicrosoftAspNetCoreApp80Version) + $(MicrosoftAspNetCoreApp90Version) + $(MicrosoftAspNetCoreApp100Version) + + diff --git a/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs b/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs index aa5e0d8c757..5e868364369 100644 --- a/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs +++ b/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs @@ -3,6 +3,7 @@ using System; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Monitoring.Extension.S3Storage { @@ -51,6 +52,7 @@ internal sealed partial class S3StorageEgressProviderOptions ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_PreSignedUrlExpiry))] [Range(typeof(TimeSpan), "00:01:00", "1.00:00:00")] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? PreSignedUrlExpiry { get; set; } [Display( diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj b/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj index f11b2d63e0e..02fc73c7735 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj +++ b/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj @@ -1,4 +1,6 @@ - + + + - - $(IntermediateOutputPath)/$(TargetFramework)/TestDotNetHost.g.cs - $(MicrosoftNETCoreApp31Version) - $(MicrosoftNETCoreApp50Version) - $(MicrosoftNETCoreApp60Version) - $(MicrosoftNETCoreApp70Version) - $(MicrosoftNETCoreApp80Version) - $(MicrosoftNETCoreApp90Version) - $(MicrosoftNETCoreApp100Version) - $(MicrosoftAspNetCoreApp31Version) - $(MicrosoftAspNetCoreApp50Version) - $(MicrosoftAspNetCoreApp60Version) - $(MicrosoftAspNetCoreApp70Version) - $(MicrosoftAspNetCoreApp80Version) - $(MicrosoftAspNetCoreApp90Version) - $(MicrosoftAspNetCoreApp100Version) - - $([System.IO.File]::ReadAllText('TestDotNetHost.cs.template')) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj index 37ccbaf9ab3..4ff7f536c46 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj @@ -1,8 +1,9 @@ - + $(TestTargetFrameworks) $(DefineConstants);UNITTEST + $(NoWarn);NU1603 $(SignOnlyRuntimeIdentifiers) $(OutputPath) diff --git a/src/Tools/dotnet-monitor/Auth/ApiKey/GeneratedJwtKey.cs b/src/Tools/dotnet-monitor/Auth/ApiKey/GeneratedJwtKey.cs index 3b78f8d8e21..0ee9831044d 100644 --- a/src/Tools/dotnet-monitor/Auth/ApiKey/GeneratedJwtKey.cs +++ b/src/Tools/dotnet-monitor/Auth/ApiKey/GeneratedJwtKey.cs @@ -54,7 +54,7 @@ public static GeneratedJwtKey Create(TimeSpan expirationOffset) ECDsa pubDsa = ECDsa.Create(dsa.ExportParameters(includePrivateParameters: false)); ECDsaSecurityKey pubSecKey = new ECDsaSecurityKey(pubDsa); JsonWebKey jwk = JsonWebKeyConverter.ConvertFromECDsaSecurityKey(pubSecKey); - string publicKeyJson = JsonSerializer.Serialize(jwk, new JsonSerializerOptions() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); + string publicKeyJson = JsonSerializer.Serialize(jwk, JsonWebKeyContext.Default.JsonWebKey); string publicKeyEncoded = Base64UrlEncoder.Encode(publicKeyJson); JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); @@ -63,4 +63,9 @@ public static GeneratedJwtKey Create(TimeSpan expirationOffset) return new GeneratedJwtKey(output, subjectStr, publicKeyEncoded); } } + + [JsonSerializable(typeof(JsonWebKey))] + partial class JsonWebKeyContext : JsonSerializerContext + { + } } diff --git a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs index 2cae0a91b75..40bea50bedd 100644 --- a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs +++ b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs @@ -1,7 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; @@ -9,6 +12,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Threading; namespace Microsoft.Diagnostics.Tools.Monitor.Auth.ApiKey { @@ -21,20 +25,26 @@ internal sealed class MonitorApiKeyPostConfigure : { private readonly ILogger _logger; private readonly IOptionsMonitor _apiKeyOptions; + private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public MonitorApiKeyPostConfigure( + IServiceProvider serviceProvider, ILogger logger, IOptionsMonitor apiKeyOptions) { _logger = logger; _apiKeyOptions = apiKeyOptions; + _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public void PostConfigure(string? name, MonitorApiKeyConfiguration options) { MonitorApiKeyOptions sourceOptions = _apiKeyOptions.CurrentValue; - IList errors = new List(); + List errors = new List(); + // If nothing is set, lets not attach an error and instead pass along the blank config if (sourceOptions.Subject == null && sourceOptions.PublicKey == null) @@ -48,11 +58,7 @@ public void PostConfigure(string? name, MonitorApiKeyConfiguration options) // Some options are configured (but may not be valid) options.Configured = true; - Validator.TryValidateObject( - sourceOptions, - new ValidationContext(sourceOptions, null, null), - errors, - validateAllProperties: true); + ValidationHelper.TryValidateObject(sourceOptions, typeof(MonitorApiKeyOptions), _validationOptions, errors); string? jwkJson = null; try diff --git a/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs b/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs index c4dbc2bab83..5c6d42dd155 100644 --- a/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs +++ b/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs @@ -1,10 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Tools.Monitor.Auth.ApiKey; using Microsoft.Diagnostics.Tools.Monitor.Auth.AzureAd; using Microsoft.Diagnostics.Tools.Monitor.Auth.NoAuth; using Microsoft.Extensions.Configuration; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Extensions.Hosting; using System; using System.Collections.Generic; @@ -21,7 +23,7 @@ internal enum StartupAuthenticationMode internal static class AuthConfiguratorFactory { - public static IAuthenticationConfigurator Create(StartupAuthenticationMode startupAuthMode, HostBuilderContext context) + public static IAuthenticationConfigurator Create(StartupAuthenticationMode startupAuthMode, HostBuilderContext context, ValidationOptions validationOptions) { switch (startupAuthMode) { @@ -46,12 +48,12 @@ public static IAuthenticationConfigurator Create(StartupAuthenticationMode start if (authConfigSection.Exists()) { authConfigSection.Bind(authOptions); - ValidateAuthConfigSection(authOptions, authConfigSection.Path); + ValidateAuthConfigSection(authOptions, authConfigSection.Path, validationOptions); } if (authOptions.AzureAd != null) { - ValidateAuthConfigSection(authOptions.AzureAd, ConfigurationPath.Combine(authConfigSection.Path, ConfigurationKeys.AzureAd)); + ValidateAuthConfigSection(authOptions.AzureAd, ConfigurationPath.Combine(authConfigSection.Path, ConfigurationKeys.AzureAd), validationOptions); return new AzureAdAuthConfigurator(authOptions.AzureAd); } @@ -62,10 +64,10 @@ public static IAuthenticationConfigurator Create(StartupAuthenticationMode start } } - private static void ValidateAuthConfigSection(T options, string configurationPath) where T : notnull + private static void ValidateAuthConfigSection(T options, string configurationPath, ValidationOptions validationOptions) where T : notnull { List results = new(); - if (!Validator.TryValidateObject(options, new ValidationContext(options), results, validateAllProperties: true)) + if (!ValidationHelper.TryValidateObject(options, typeof(T), validationOptions, results)) { throw new DeferredAuthenticationValidationException(configurationPath, results); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs index ac740410b20..0d081788d51 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs @@ -1,12 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions @@ -15,10 +17,12 @@ internal sealed class CollectDumpActionFactory : ICollectionRuleActionFactory { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public CollectDumpActionFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, CollectDumpOptions options) @@ -28,8 +32,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectDumpOptions throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectDumpOptions), _validationOptions); return new CollectDumpAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs index efc8f2150ce..afa64f21355 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs @@ -1,10 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; @@ -12,6 +16,13 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions { internal sealed class CollectExceptionsActionFactory : ICollectionRuleActionFactory { + private readonly ValidationOptions _validationOptions; + + public CollectExceptionsActionFactory(IOptions validationOptions) + { + _validationOptions = validationOptions?.Value ?? throw new ArgumentNullException(nameof(validationOptions)); + } + public ICollectionRuleAction Create(IProcessInfo processInfo, CollectExceptionsOptions options) { if (null == options) @@ -19,8 +30,12 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectExceptionsO throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, processInfo.EndpointInfo.ServiceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + List result = new(); + if (!ValidationHelper.TryValidateObject(options, typeof(CollectExceptionsOptions), _validationOptions, result)) + { + throw new ValidationException( + string.Join(Environment.NewLine, result.ConvertAll(r => r.ErrorMessage))); + } return new CollectExceptionsAction(processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs index 21157f86952..a3634b2f4df 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs @@ -4,9 +4,11 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using System; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; +using Microsoft.AspNetCore.Http.Validation; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions { @@ -14,10 +16,12 @@ internal sealed class CollectGCDumpActionFactory : ICollectionRuleActionFactory { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public CollectGCDumpActionFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, CollectGCDumpOptions options) @@ -26,9 +30,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectGCDumpOptio { throw new ArgumentNullException(nameof(options)); } - - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectGCDumpOptions), _validationOptions); return new CollectGCDumpAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs index 9ba039edc59..303a272a798 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs @@ -1,14 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.EventPipe; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions @@ -17,10 +18,12 @@ internal sealed class CollectLiveMetricsActionFactory : ICollectionRuleActionFactory { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public CollectLiveMetricsActionFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, CollectLiveMetricsOptions options) @@ -30,8 +33,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectLiveMetrics throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectLiveMetricsOptions), _validationOptions); return new CollectLiveMetricsAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs index 41546ca8182..11b0886e116 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs @@ -1,15 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.EventPipe; using Microsoft.Diagnostics.Monitoring.Options; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions @@ -18,10 +20,12 @@ internal sealed class CollectLogsActionFactory : ICollectionRuleActionFactory { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public CollectLogsActionFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, CollectLogsOptions options) @@ -31,8 +35,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectLogsOptions throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectLogsOptions), _validationOptions); return new CollectLogsAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs index 5c9c53c2d67..40494d8aca3 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs @@ -1,11 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions @@ -13,10 +15,12 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions internal sealed class CollectStacksActionFactory : ICollectionRuleActionFactory { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public CollectStacksActionFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, CollectStacksOptions options) @@ -26,8 +30,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectStacksOptio throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectStacksOptions), _validationOptions); return new CollectStacksAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs index cd5d6c1540c..5687186b6c2 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs @@ -1,14 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.EventPipe; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions @@ -17,6 +18,7 @@ internal sealed class CollectTraceActionFactory : ICollectionRuleActionFactory { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public ICollectionRuleAction Create(IProcessInfo processInfo, CollectTraceOptions options) { @@ -25,8 +27,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectTraceOption throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectTraceOptions), _validationOptions); return new CollectTraceAction(_serviceProvider, processInfo, options); } @@ -34,6 +35,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectTraceOption public CollectTraceActionFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } private sealed class CollectTraceAction : diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs index aea65cae497..ec5bf0a508f 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs @@ -59,19 +59,6 @@ public bool TryCreateFactory( } /// - public bool TryCreateOptions( - string actionName, - out object options) - { - if (_map.TryGetValue(actionName, out ICollectionRuleActionDescriptor descriptor)) - { - options = Activator.CreateInstance(descriptor.OptionsType); - return true; - } - - options = null; - return false; - } /// public bool TryValidateOptions( diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs index eb77d0c0926..a363d539254 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs @@ -1,12 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.EventPipe; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.Globalization; using System.IO; @@ -18,6 +20,13 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions internal sealed class ExecuteActionFactory : ICollectionRuleActionFactory { + private readonly ValidationOptions _validationOptions; + + public ExecuteActionFactory(IOptions validationOptions) + { + _validationOptions = validationOptions?.Value ?? throw new ArgumentNullException(nameof(validationOptions)); + } + public ICollectionRuleAction Create(IProcessInfo processInfo, ExecuteOptions options) { if (null == options) @@ -25,8 +34,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, ExecuteOptions opt throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, null, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(ExecuteOptions), _validationOptions); return new ExecuteAction(processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs index a75d576916b..73bb616c252 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs @@ -1,13 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.NETCore.Client; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; using System.Threading; using System.Threading.Tasks; @@ -18,11 +21,13 @@ internal sealed partial class GetEnvironmentVariableActionFactory : { private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; + private readonly ValidationOptions _validationOptions; public GetEnvironmentVariableActionFactory(IServiceProvider serviceProvider, ILogger logger) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); _logger = logger ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, GetEnvironmentVariableOptions options) @@ -32,8 +37,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, GetEnvironmentVari throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(GetEnvironmentVariableOptions), _validationOptions); return new GetEnvironmentVariableAction(_logger, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs index e6168312093..374488415e4 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs @@ -21,14 +21,6 @@ bool TryCreateFactory( string actionName, out ICollectionRuleActionFactoryProxy action); - /// - /// Attempts to create an options instance of the options type - /// associated with the registered action name. - /// - bool TryCreateOptions( - string actionName, - out object options); - /// /// Attempts to validate an options instance of the options type /// associated with the registered action name. diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs index d3338bd8520..c6ba04ce178 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs @@ -1,12 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.NETCore.Client; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.Logging; using System; -using System.ComponentModel.DataAnnotations; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System.Threading; using System.Threading.Tasks; @@ -17,11 +20,13 @@ internal sealed class LoadProfilerActionFactory : { private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; + private readonly ValidationOptions _validationOptions; public LoadProfilerActionFactory(IServiceProvider serviceProvider, ILogger logger) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); _logger = logger ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, LoadProfilerOptions options) @@ -31,8 +36,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, LoadProfilerOption throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(LoadProfilerOptions), _validationOptions); return new LoadProfilerAction(_logger, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs index edd4298089c..92d1f2b95f5 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs @@ -1,12 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.NETCore.Client; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using System; -using System.ComponentModel.DataAnnotations; using System.Threading; using System.Threading.Tasks; @@ -17,11 +20,13 @@ internal sealed partial class SetEnvironmentVariableActionFactory : { private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; + private readonly ValidationOptions _validationOptions; public SetEnvironmentVariableActionFactory(IServiceProvider serviceProvider, ILogger logger) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, SetEnvironmentVariableOptions options) @@ -31,8 +36,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, SetEnvironmentVari throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(SetEnvironmentVariableOptions), _validationOptions); return new SetEnvironmentVariableAction(_logger, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs index 548c4bd3cc6..9690a738a46 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs @@ -1,8 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Triggers; using Microsoft.Extensions.Configuration; @@ -10,29 +14,167 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration { internal static class CollectionRuleBindingHelper { - public static void BindActionSettings(IConfigurationSection actionSection, CollectionRuleActionOptions actionOptions, ICollectionRuleActionOperations actionOperations) - { - if (null != actionOptions && - actionOperations.TryCreateOptions(actionOptions.Type, out object actionSettings)) - { - IConfigurationSection settingsSection = actionSection.GetSection(nameof(CollectionRuleActionOptions.Settings)); + public static object CreateActionSettings( + string actionType, + Func collectDump, + Func collectExceptions + ) => actionType switch { + KnownCollectionRuleActions.CollectDump => collectDump(), + KnownCollectionRuleActions.CollectExceptions => collectExceptions(), + }; + + // public static object NewActionSettings(string actionType) => + // actionType switch { + // KnownCollectionRuleActions.CollectDump => new CollectDumpOptions(), + // KnownCollectionRuleActions.CollectExceptions => new CollectExceptionsOptions(), + // _ => null + // }; + + // public static Action SelectAction( + // string actionType, + // Action collectDump, + // Action collectExceptions + // ) => actionType switch { + // KnownCollectionRuleActions.CollectDump => collectDump, + // KnownCollectionRuleActions.CollectExceptions => collectExceptions, + // }; + - settingsSection.Bind(actionSettings); + public static void BindActionSettings(IConfigurationSection actionSection, CollectionRuleActionOptions actionOptions) + { + if (actionOptions is null) + return; - actionOptions.Settings = actionSettings; + actionSection.Bind(actionOptions); + IConfigurationSection settingsSection = actionSection.GetSection(nameof(CollectionRuleActionOptions.Settings)); + switch (actionOptions.Type) + { + case KnownCollectionRuleActions.CollectDump: { + var actionSettings = new CollectDumpOptions(); + settingsSection.Bind(actionSettings); + actionOptions.Settings = actionSettings; + break; + } + case KnownCollectionRuleActions.CollectExceptions: { + var actionSettings = new CollectExceptionsOptions(); + settingsSection.Bind(actionSettings); + actionOptions.Settings = actionSettings; + break; + } + case KnownCollectionRuleActions.CollectGCDump: { + var actionSettings = new CollectGCDumpOptions(); + settingsSection.Bind(actionSettings); + actionOptions.Settings = actionSettings; + break; + } + case KnownCollectionRuleActions.CollectLiveMetrics: { + var actionSettings = new CollectLiveMetricsOptions(); + settingsSection.Bind(actionSettings); + actionOptions.Settings = actionSettings; + break; + } + case KnownCollectionRuleActions.CollectLogs: { + var actionSettings = new CollectLogsOptions(); + settingsSection.Bind(actionSettings); + actionOptions.Settings = actionSettings; + break; + } + case KnownCollectionRuleActions.CollectStacks: { + var actionSettings = new CollectStacksOptions(); + settingsSection.Bind(actionSettings); + actionOptions.Settings = actionSettings; + break; + } + case KnownCollectionRuleActions.CollectTrace: { + var actionSettings = new CollectTraceOptions(); + settingsSection.Bind(actionSettings); + actionOptions.Settings = actionSettings; + break; + } + case KnownCollectionRuleActions.Execute: { + var actionSettings = new ExecuteOptions(); + settingsSection.Bind(actionSettings); + actionOptions.Settings = actionSettings; + break; + } + case KnownCollectionRuleActions.LoadProfiler: { + var actionSettings = new LoadProfilerOptions(); + settingsSection.Bind(actionSettings); + actionOptions.Settings = actionSettings; + break; + } + case KnownCollectionRuleActions.SetEnvironmentVariable: { + var actionSettings = new SetEnvironmentVariableOptions(); + settingsSection.Bind(actionSettings); + actionOptions.Settings = actionSettings; + break; + } + case KnownCollectionRuleActions.GetEnvironmentVariable: { + var actionSettings = new GetEnvironmentVariableOptions(); + settingsSection.Bind(actionSettings); + actionOptions.Settings = actionSettings; + break; + } } } public static void BindTriggerSettings(IConfigurationSection triggerSection, CollectionRuleTriggerOptions triggerOptions, ICollectionRuleTriggerOperations triggerOperations) { - if (null != triggerOptions && - triggerOperations.TryCreateOptions(triggerOptions.Type, out object triggerSettings)) - { - IConfigurationSection settingsSection = triggerSection.GetSection(nameof(CollectionRuleTriggerOptions.Settings)); + if (triggerOptions is null) + return; - settingsSection.Bind(triggerSettings); - - triggerOptions.Settings = triggerSettings; + triggerSection.Bind(triggerOptions); + IConfigurationSection settingsSection = triggerSection.GetSection(nameof(CollectionRuleTriggerOptions.Settings)); + switch (triggerOptions.Type) + { + case KnownCollectionRuleTriggers.AspNetRequestCount: { + var triggerSettings = new AspNetRequestCountOptions(); + settingsSection.Bind(triggerSettings); + triggerOptions.Settings = triggerSettings; + break; + } + case KnownCollectionRuleTriggers.AspNetRequestDuration: { + var triggerSettings = new AspNetRequestDurationOptions(); + settingsSection.Bind(triggerSettings); + triggerOptions.Settings = triggerSettings; + break; + } + case KnownCollectionRuleTriggers.AspNetResponseStatus: { + var triggerSettings = new AspNetResponseStatusOptions(); + settingsSection.Bind(triggerSettings); + triggerOptions.Settings = triggerSettings; + break; + } + case KnownCollectionRuleTriggers.EventCounter: { + var triggerSettings = new EventCounterOptions(); + settingsSection.Bind(triggerSettings); + triggerOptions.Settings = triggerSettings; + break; + } + case KnownCollectionRuleTriggers.CPUUsage: { + var triggerSettings = new CPUUsageOptions(); + settingsSection.Bind(triggerSettings); + triggerOptions.Settings = triggerSettings; + break; + } + case KnownCollectionRuleTriggers.GCHeapSize: { + var triggerSettings = new GCHeapSizeOptions(); + settingsSection.Bind(triggerSettings); + triggerOptions.Settings = triggerSettings; + break; + } + case KnownCollectionRuleTriggers.ThreadpoolQueueLength: { + var triggerSettings = new ThreadpoolQueueLengthOptions(); + settingsSection.Bind(triggerSettings); + triggerOptions.Settings = triggerSettings; + break; + } + case KnownCollectionRuleTriggers.EventMeter: { + var triggerSettings = new EventMeterOptions(); + settingsSection.Bind(triggerSettings); + triggerOptions.Settings = triggerSettings; + break; + } } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs index 1c412f58eaf..c79818ca45e 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; @@ -10,7 +11,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; using System.Globalization; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration @@ -64,9 +64,8 @@ private void ResolveActionList(CollectionRuleOptions ruleOptions, IConfiguration { CollectionRuleActionOptions actionOptions = new(); - actionSection.Bind(actionOptions); - CollectionRuleBindingHelper.BindActionSettings(actionSection, actionOptions, _actionOperations); + CollectionRuleBindingHelper.BindActionSettings(actionSection, actionOptions); ruleOptions.Actions.Add(actionOptions); } @@ -132,7 +131,7 @@ private void ResolveLimits(CollectionRuleOptions ruleOptions, IConfigurationSect if (!templatesOptions.TryGetValue(templateKey, out templatesValue)) { templatesValue = new(); - ruleOptions.ErrorList.Add(new ValidationResult(string.Format(CultureInfo.CurrentCulture, Strings.ErrorMessage_TemplateNotFound, templateKey))); + ruleOptions.ErrorList.Add(string.Format(CultureInfo.CurrentCulture, Strings.ErrorMessage_TemplateNotFound, templateKey)); return false; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/TemplatesConfigureNamedOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/TemplatesConfigureNamedOptions.cs index ff35634307f..bed6c601132 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/TemplatesConfigureNamedOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/TemplatesConfigureNamedOptions.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Triggers; using Microsoft.Extensions.Configuration; @@ -13,23 +12,21 @@ internal sealed class TemplatesPostConfigureOptions : IPostConfigureOptions { private readonly ICollectionRuleTriggerOperations _triggerOperations; - private readonly ICollectionRuleActionOperations _actionOperations; private readonly IConfiguration _configuration; private static readonly string collectionRuleActionsPath = ConfigurationPath.Combine(nameof(RootOptions.Templates), nameof(TemplateOptions.CollectionRuleActions)); private static readonly string collectionRuleTriggersPath = ConfigurationPath.Combine(nameof(RootOptions.Templates), nameof(TemplateOptions.CollectionRuleTriggers)); public TemplatesPostConfigureOptions( ICollectionRuleTriggerOperations triggerOperations, - ICollectionRuleActionOperations actionOperations, IConfiguration configuration) { _triggerOperations = triggerOperations; - _actionOperations = actionOperations; _configuration = configuration; } public void PostConfigure(string? name, TemplateOptions options) { + System.Console.WriteLine("TemplatesConfigureNamedOptions PostConfigure"); IConfigurationSection collectionRuleActionsSection = _configuration.GetSection(collectionRuleActionsPath); if (options.CollectionRuleActions != null) @@ -40,7 +37,7 @@ public void PostConfigure(string? name, TemplateOptions options) if (actionSection.Exists()) { - CollectionRuleBindingHelper.BindActionSettings(actionSection, options.CollectionRuleActions[key], _actionOperations); + CollectionRuleBindingHelper.BindActionSettings(actionSection, options.CollectionRuleActions[key]); } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs index 7bba676bd59..7010eac43f3 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs @@ -10,6 +10,7 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions { @@ -42,6 +43,7 @@ internal sealed partial record class CollectLiveMetricsOptions : BaseRecordOptio ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Duration))] [Range(typeof(TimeSpan), ActionOptionsConstants.Duration_MinValue, ActionOptionsConstants.Duration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] [DefaultValue(CollectLiveMetricsOptionsDefaults.Duration)] public TimeSpan? Duration { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs deleted file mode 100644 index e8ede3ded8c..00000000000 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Extensions.Logging; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; - -#if UNITTEST -namespace Microsoft.Diagnostics.Monitoring.TestCommon.Options -#else -namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions -#endif -{ - partial record class CollectLogsOptions : - IValidatableObject - { - IEnumerable IValidatableObject.Validate(ValidationContext validationContext) - { - List results = new(); - - if (null != FilterSpecs) - { - RequiredAttribute requiredAttribute = new(); - EnumDataTypeAttribute enumValidationAttribute = new(typeof(LogLevel)); - - ValidationContext filterSpecsContext = new(FilterSpecs, validationContext, validationContext.Items); - filterSpecsContext.MemberName = nameof(FilterSpecs); - - // Validate that the category is not null and that the level is a valid level value. - foreach ((string category, LogLevel? level) in FilterSpecs) - { - ValidationResult? result = requiredAttribute.GetValidationResult(category, filterSpecsContext); - if (!result.IsSuccess()) - { - results.Add(result); - } - - result = enumValidationAttribute.GetValidationResult(level, filterSpecsContext); - if (!result.IsSuccess()) - { - results.Add(result); - } - } - } - - return results; - } - } -} diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs index ed0a8ba62fb..147ebb29ddc 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs @@ -12,6 +12,7 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions { @@ -46,6 +47,7 @@ internal sealed partial record class CollectLogsOptions : BaseRecordOptions, IEg ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Duration))] [Range(typeof(TimeSpan), ActionOptionsConstants.Duration_MinValue, ActionOptionsConstants.Duration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] [DefaultValue(CollectLogsOptionsDefaults.Duration)] public TimeSpan? Duration { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs index 6874ec2354b..ea47f26d0a7 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs @@ -82,23 +82,6 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali { results.AddRange(e.Failures.Select((string failure) => new ValidationResult(e.Message))); } - - // Validate that each provider is valid. - int index = 0; - foreach (EventPipeProvider provider in Providers) - { - ValidationContext providerContext = new(provider, validationContext, validationContext.Items); - providerContext.MemberName = nameof(Providers) + "[" + index.ToString(CultureInfo.InvariantCulture) + "]"; - - Validator.TryValidateObject(provider, providerContext, results, validateAllProperties: true); - - if (counterOptions != null && !CounterValidator.ValidateProvider(counterOptions, provider, out string? errorMessage)) - { - results.Add(new ValidationResult(errorMessage, new[] { nameof(EventPipeProvider.Arguments) })); - } - - index++; - } } else { diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs index 3a32d2a9460..2491c12a88b 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs @@ -11,6 +11,7 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions { @@ -51,6 +52,7 @@ internal sealed partial record class CollectTraceOptions : BaseRecordOptions, IE ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Duration))] [Range(typeof(TimeSpan), ActionOptionsConstants.Duration_MinValue, ActionOptionsConstants.Duration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] [DefaultValue(CollectTraceOptionsDefaults.Duration)] public TimeSpan? Duration { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs index 9f3e893be53..64096acc700 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs @@ -4,6 +4,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using System; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options { @@ -19,12 +20,14 @@ internal sealed class CollectionRuleLimitsDefaultsOptions ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsDefaultsOptions_ActionCountSlidingWindowDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MinValue, CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? ActionCountSlidingWindowDuration { get; set; } [Display( ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsDefaultsOptions_RuleDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.RuleDuration_MinValue, CollectionRuleOptionsConstants.RuleDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? RuleDuration { get; set; } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs index d53f0f36051..74d657ce290 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs @@ -5,6 +5,7 @@ using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options { @@ -24,12 +25,14 @@ internal sealed class CollectionRuleLimitsOptions ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsOptions_ActionCountSlidingWindowDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MinValue, CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? ActionCountSlidingWindowDuration { get; set; } [Display( ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsOptions_RuleDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.RuleDuration_MinValue, CollectionRuleOptionsConstants.RuleDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? RuleDuration { get; set; } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs deleted file mode 100644 index 141f2d4c30b..00000000000 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable disable - -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Globalization; - -namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options -{ - partial class CollectionRuleOptions : IValidatableObject - { - IEnumerable IValidatableObject.Validate(ValidationContext validationContext) - { - List results = new(); - - // ErrorList is populated by incorrectly using templates - this will be empty if all templates names can be resolved or if templates are not used. - results.AddRange(ErrorList); - - if (results.Count > 0) - { - return results; - } - - ValidationContext filtersContext = new(Filters, validationContext, validationContext.Items); - filtersContext.MemberName = nameof(Filters); - ValidationHelper.TryValidateItems(Filters, filtersContext, results); - - if (null != Trigger) - { - ValidationContext triggerContext = new(Trigger, validationContext, validationContext.Items); - triggerContext.MemberName = nameof(Trigger); - Validator.TryValidateObject(Trigger, triggerContext, results); - } - - ValidationContext actionsContext = new(Actions, validationContext, validationContext.Items); - actionsContext.MemberName = nameof(Actions); - ValidationHelper.TryValidateItems(Actions, actionsContext, results); - - var actionNames = new HashSet(StringComparer.Ordinal); - foreach (CollectionRuleActionOptions option in Actions) - { - if (!string.IsNullOrEmpty(option.Name) && !actionNames.Add(option.Name)) - { - results.Add(new ValidationResult( - string.Format(CultureInfo.CurrentCulture, Strings.ErrorMessage_DuplicateActionName, option.Name), - new[] { nameof(option.Name) })); - } - } - - return results; - } - } -} diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs index 128848d3bd3..1f549d13b00 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs @@ -37,6 +37,6 @@ internal sealed partial class CollectionRuleOptions Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Limits))] public CollectionRuleLimitsOptions? Limits { get; set; } - internal List ErrorList { get; } = new List(); + internal List ErrorList { get; } = new List(); } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs index ffe3e8d0467..59b4b5e4ebc 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; using System; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options { @@ -26,6 +27,7 @@ internal sealed class CollectionRuleTriggerDefaultsOptions ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleTriggerDefaultsOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? SlidingWindowDuration { get; set; } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs index adb6868e8fa..973795d5bf7 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs @@ -5,16 +5,20 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; +using Microsoft.Extensions.Options; using System; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers { /// /// Options for the AspNetRequestCount trigger. /// - internal sealed class AspNetRequestCountOptions : - IAspNetActionPathFilters, ISlidingWindowDurationProperties, IRequestCountProperties + [OptionsValidator] + internal sealed partial class AspNetRequestCountOptions : + IAspNetActionPathFilters, ISlidingWindowDurationProperties, IRequestCountProperties, + IValidateOptions { [Display( ResourceType = typeof(OptionsDisplayStrings), @@ -30,6 +34,7 @@ internal sealed class AspNetRequestCountOptions : ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestCountOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? SlidingWindowDuration { get; set; } // CONSIDER: Currently described that paths have to exactly match one item in the list. diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs index 1967a34f1f8..3009fd19fd5 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs @@ -5,17 +5,21 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; +using Microsoft.Extensions.Options; using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers { /// /// Options for the AspNetRequestDuration trigger. /// - internal sealed class AspNetRequestDurationOptions : - IAspNetActionPathFilters, ISlidingWindowDurationProperties, IRequestCountProperties + [OptionsValidator] + internal sealed partial class AspNetRequestDurationOptions : + IAspNetActionPathFilters, ISlidingWindowDurationProperties, IRequestCountProperties, + IValidateOptions { public const string RequestDuration_MaxValue = "01:00:00"; public const string RequestDuration_MinValue = "00:00:00"; @@ -35,12 +39,14 @@ internal sealed class AspNetRequestDurationOptions : Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_RequestDuration))] [DefaultValue(AspNetRequestDurationOptionsDefaults.RequestDuration)] [Range(typeof(TimeSpan), RequestDuration_MinValue, RequestDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? RequestDuration { get; set; } [Display( ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? SlidingWindowDuration { get; set; } // CONSIDER: Currently described that paths have to exactly match one item in the list. diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs index 9f998a007cf..abeb51e0e87 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs @@ -5,16 +5,20 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; +using Microsoft.Extensions.Options; using System; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers { /// /// Options for the AspNetResponseStatus trigger. /// - internal sealed class AspNetResponseStatusOptions : - IAspNetActionPathFilters, ISlidingWindowDurationProperties + [OptionsValidator] + internal sealed partial class AspNetResponseStatusOptions : + IAspNetActionPathFilters, ISlidingWindowDurationProperties, + IValidateOptions { private const string StatusCodeRegex = "[1-5][0-9]{2}"; private const string StatusCodesRegex = StatusCodeRegex + "(-" + StatusCodeRegex + ")?"; @@ -25,6 +29,7 @@ internal sealed class AspNetResponseStatusOptions : Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_StatusCodes))] [Required] [MinLength(1)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Count of string property is preserved by DynamicDependency.")] [RegularExpressions(StatusCodesRegex, ErrorMessageResourceType = typeof(OptionsDisplayStrings), ErrorMessageResourceName = nameof(OptionsDisplayStrings.ErrorMessage_StatusCodesRegularExpressionDoesNotMatch))] @@ -45,6 +50,7 @@ internal sealed class AspNetResponseStatusOptions : ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? SlidingWindowDuration { get; set; } // CONSIDER: Currently described that paths have to exactly match one item in the list. diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs index 3c02bcd03cf..6b68b783c7e 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs @@ -3,15 +3,18 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; +using Microsoft.Extensions.Options; using System; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers { /// /// Options for the EventCounter trigger. /// - internal sealed partial class EventCounterOptions : ISlidingWindowDurationProperties + [OptionsValidator] + internal sealed partial class EventCounterOptions : IValidateOptions, ISlidingWindowDurationProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), @@ -39,6 +42,7 @@ internal sealed partial class EventCounterOptions : ISlidingWindowDurationProper ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? SlidingWindowDuration { get; set; } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs index 59878ace042..d67f7c8edac 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs @@ -3,16 +3,19 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; +using Microsoft.Extensions.Options; using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts { /// /// Options for the CPUUsage trigger. /// - internal sealed partial class CPUUsageOptions : IEventCounterShortcuts, ISlidingWindowDurationProperties + [OptionsValidator] + internal sealed partial class CPUUsageOptions : IValidateOptions, IEventCounterShortcuts, ISlidingWindowDurationProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), @@ -31,6 +34,7 @@ internal sealed partial class CPUUsageOptions : IEventCounterShortcuts, ISliding ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] [DefaultValue(EventCounterOptionsDefaults.SlidingWindowDuration)] public TimeSpan? SlidingWindowDuration { get; set; } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/GCHeapSizeOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/GCHeapSizeOptions.cs index 1411ea183d0..e067b0c03aa 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/GCHeapSizeOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/GCHeapSizeOptions.cs @@ -3,16 +3,19 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; +using Microsoft.Extensions.Options; using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts { /// /// Options for the GCHeapSize trigger. /// - internal sealed partial class GCHeapSizeOptions : IEventCounterShortcuts, ISlidingWindowDurationProperties + [OptionsValidator] + internal sealed partial class GCHeapSizeOptions : IValidateOptions, IEventCounterShortcuts, ISlidingWindowDurationProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), @@ -31,6 +34,7 @@ internal sealed partial class GCHeapSizeOptions : IEventCounterShortcuts, ISlidi ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] [DefaultValue(EventCounterOptionsDefaults.SlidingWindowDuration)] public TimeSpan? SlidingWindowDuration { get; set; } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/ThreadpoolQueueLengthOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/ThreadpoolQueueLengthOptions.cs index 6d42e99a1b8..94c815fce23 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/ThreadpoolQueueLengthOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/ThreadpoolQueueLengthOptions.cs @@ -3,16 +3,19 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; +using Microsoft.Extensions.Options; using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts { /// /// Options for the ThreadpoolQueueLength trigger. /// - internal sealed partial class ThreadpoolQueueLengthOptions : IEventCounterShortcuts, ISlidingWindowDurationProperties + [OptionsValidator] + internal sealed partial class ThreadpoolQueueLengthOptions : IValidateOptions, IEventCounterShortcuts, ISlidingWindowDurationProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), @@ -32,6 +35,7 @@ internal sealed partial class ThreadpoolQueueLengthOptions : IEventCounterShortc ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] [DefaultValue(EventCounterOptionsDefaults.SlidingWindowDuration)] public TimeSpan? SlidingWindowDuration { get; set; } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.cs index cc22561940f..07bed84ec52 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.cs @@ -3,15 +3,18 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; +using Microsoft.Extensions.Options; using System; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers { /// /// Options for the EventMeter trigger. /// - internal sealed partial class EventMeterOptions : ISlidingWindowDurationProperties + [OptionsValidator] + internal sealed partial class EventMeterOptions : IValidateOptions, ISlidingWindowDurationProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), @@ -39,6 +42,7 @@ internal sealed partial class EventMeterOptions : ISlidingWindowDurationProperti ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventMeterOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? SlidingWindowDuration { get; set; } [Display( diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs index c99543df9c0..6090102ffdc 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs @@ -1,32 +1,23 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; using System.Reflection; +using System.Threading; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options { internal static class ValidationHelper { - public static void TryValidateItems(IEnumerable items, ValidationContext validationContext, ICollection results) - { - int index = 0; - foreach (object item in items) - { - ValidationContext itemContext = new(item, validationContext, validationContext.Items); - itemContext.MemberName = validationContext.MemberName + "[" + index.ToString() + "]"; - - Validator.TryValidateObject(item, itemContext, results); - - index++; - } - } - #nullable disable + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(TimeSpan))] + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicProperties, typeof(string))] public static bool TryValidateOptions(Type optionsType, object options, ValidationContext validationContext, ICollection results) { RequiredAttribute requiredAttribute = new(); @@ -60,5 +51,56 @@ public static bool TryValidateOptions(Type optionsType, object options, Validati } } #nullable restore + + public static bool TryValidateObject(object options, Type type, ValidationOptions validationOptions, ValidationContext validationContext, ICollection results) + { + return TryValidateObject(options, type, validationOptions, validationContext, results); + } + + public static bool TryValidateObject(object options, Type type, ValidationOptions validationOptions, List results) + { + var validationContext = new ValidationContext(options, type.Name, null, items: null) { + MemberName = type.Name + }; + return TryValidateObject(options, type, validationOptions, validationContext, results); + } + + public static bool TryValidateObject(object options, Type type, ValidationOptions validationOptions, ValidationContext validationContext, List results) + { + if (!validationOptions.TryGetValidatableTypeInfo(type, out IValidatableInfo? validatableTypeInfo)) + { + throw new Exception("No type info found for type " + type.FullName); + } + if (validationContext.MemberName is null) + { + throw new ArgumentNullException(nameof(validationContext.MemberName)); + } + var validateContext = new ValidateContext() + { + ValidationOptions = validationOptions, + ValidationContext = new(options, validationContext.MemberName, null, items: null) + }; + validatableTypeInfo.ValidateAsync(options, validateContext, CancellationToken.None).GetAwaiter().GetResult(); + if (validateContext.ValidationErrors is Dictionary validationErrors) + { + foreach (var (name, errors) in validationErrors) + { + foreach (var error in errors) + { + results.Add(new ValidationResult(error, [name])); + } + } + return false; + } + return true; + } + + public static void ValidateObject(object options, Type type, ValidationOptions validationOptions) + { + if (!TryValidateObject(options, type, validationOptions, new List())) + { + throw new ValidationException("Validation failed for " + type.FullName); + } + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs index 1b1dfac9460..c32f8c165c7 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs @@ -70,23 +70,6 @@ public bool TryCreateFactory( return false; } - /// - public bool TryCreateOptions( - string triggerName, - out object options) - { - // Check that the trigger is registered and has options - if (_map.TryGetValue(triggerName, out ICollectionRuleTriggerDescriptor descriptor) && - null != descriptor.OptionsType) - { - options = Activator.CreateInstance(descriptor.OptionsType); - return true; - } - - options = null; - return false; - } - /// public bool TryValidateOptions( string triggerName, diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/ICollectionRuleTriggerOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/ICollectionRuleTriggerOperations.cs index 083adf8dd5d..237202a4dfd 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/ICollectionRuleTriggerOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/ICollectionRuleTriggerOperations.cs @@ -19,13 +19,6 @@ bool TryCreateFactory( string triggerName, out ICollectionRuleTriggerFactoryProxy factory); - /// - /// Attempts to create an options instance of the options type - /// associated with the registered trigger name. - /// - bool TryCreateOptions( - string triggerName, - out object options); /// /// Attempts to validate an options instance of the options type diff --git a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs index c16dcb791d5..ff4840b1454 100644 --- a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs +++ b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.Auth; @@ -85,7 +86,8 @@ private static IHostBuilder Configure(this IHostBuilder builder, StartupAuthenti { return builder.ConfigureServices((HostBuilderContext context, IServiceCollection services) => { - IAuthenticationConfigurator authConfigurator = AuthConfiguratorFactory.Create(startupAuthMode, context); + var validationOptions = services.BuildServiceProvider().GetRequiredService>().Value; + IAuthenticationConfigurator authConfigurator = AuthConfiguratorFactory.Create(startupAuthMode, context, validationOptions); services.AddSingleton(authConfigurator); //TODO Many of these service additions should be done through extension methods diff --git a/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs b/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs index a13b184fcdc..cf86ae17cf7 100644 --- a/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs +++ b/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs @@ -12,6 +12,7 @@ using System.IO; using System.Text; using System.Text.Json; +using System.Text.Json.Serialization; namespace Microsoft.Diagnostics.Tools.Monitor.Commands { @@ -48,7 +49,7 @@ public static void Invoke(OutputFormat output, TimeSpan expiration, TextWriter o Authentication = opts.Authentication, AuthorizationHeader = $"{AuthConstants.ApiKeySchema} {newJwt.Token}" // This is the actual format of the HTTP header and should not be localized }; - outputBldr.AppendLine(JsonSerializer.Serialize(result, result.GetType(), new JsonSerializerOptions() { WriteIndented = true })); + outputBldr.AppendLine(JsonSerializer.Serialize(result, MachineOutputFormatContext.Default.MachineOutputFormat)); } else { @@ -145,4 +146,10 @@ internal class MachineOutputFormat public required string AuthorizationHeader { get; set; } } } + + [JsonSourceGenerationOptions(WriteIndented = true)] + [JsonSerializable(typeof(GenerateApiKeyCommandHandler.MachineOutputFormat))] + internal partial class MachineOutputFormatContext : JsonSerializerContext + { + } } diff --git a/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs b/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs index 2b6548a03b3..2942b434859 100644 --- a/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs +++ b/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs @@ -3,11 +3,13 @@ #nullable enable +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Extensions.Options; +using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; #if EXTENSION namespace Microsoft.Diagnostics.Monitoring.Extension.Common @@ -20,33 +22,40 @@ internal sealed class DataAnnotationValidateOptions : where TOptions : class { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public DataAnnotationValidateOptions(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ValidateOptionsResult Validate(string? name, TOptions options) { - ValidationContext validationContext = new(options, _serviceProvider, null); - ICollection results = new Collection(); - if (!Validator.TryValidateObject(options, validationContext, results, validateAllProperties: true)) + var results = new List(); + if (!ValidationHelper.TryValidateObject(options, typeof(TOptions), _validationOptions, results)) { IList failures = new List(); foreach (ValidationResult result in results) { - if (ValidationResult.Success != result) + if (result.MemberNames is IEnumerable memberNames) { -#nullable disable + foreach (string memberName in memberNames) + { + failures.Add($"{memberName}: {result.ErrorMessage}"); + } + } + else + { + if (result.ErrorMessage is null) + { + throw new ArgumentNullException(nameof(result.ErrorMessage)); + } failures.Add(result.ErrorMessage); -#nullable restore } } - if (failures.Count > 0) - { - return ValidateOptionsResult.Fail(failures); - } + return ValidateOptionsResult.Fail(failures); } return ValidateOptionsResult.Success; diff --git a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs index a95ab55d174..fe56dc95e1c 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs @@ -8,6 +8,7 @@ using System; using System.Diagnostics; using System.Text.Json; +using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; @@ -19,16 +20,18 @@ internal class OutputParser : IDisposable where TResult : class, IExten { private readonly ILogger _logger; private readonly TaskCompletionSource _resultCompletionSource; + private readonly JsonTypeInfo _jsonTypeInfo; private readonly EventWaitHandle _beginReadsHandle; private readonly Process _process; // We need to store the process ID for logging because we can't access it after the process exits private int _processId = -1; - public OutputParser(Process process, ILogger logger) + public OutputParser(Process process, ILogger logger, JsonTypeInfo jsonTypeInfo) { _process = process; _logger = logger; _resultCompletionSource = new TaskCompletionSource(); + _jsonTypeInfo = jsonTypeInfo; _beginReadsHandle = new EventWaitHandle(false, EventResetMode.AutoReset); _process.OutputDataReceived += ParseStdOut; @@ -68,7 +71,7 @@ private void ParseStdOut(object sender, DataReceivedEventArgs eventArgs) try { // Check if the object is a TResult - TResult result = JsonSerializer.Deserialize(eventArgs.Data); + TResult result = JsonSerializer.Deserialize(eventArgs.Data, _jsonTypeInfo); if (result.IsValid()) { _resultCompletionSource.TrySetResult(result); diff --git a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs index fdcf814c0ac..48167f3cd29 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs @@ -3,9 +3,12 @@ #nullable disable +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Tools.Monitor.Egress.Configuration; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using System; @@ -17,6 +20,7 @@ using System.Runtime.InteropServices; using System.Text; using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; @@ -29,6 +33,7 @@ internal partial class EgressExtension : IExtension, IEgressExtension private readonly string _extensionPath; private readonly ILogger _logger; private readonly ExtensionManifest _manifest; + private readonly ValidationOptions _validationOptions; private readonly IDictionary _processEnvironmentVariables = new Dictionary(); private const int PayloadProtocolVersion = 1; @@ -38,12 +43,14 @@ public EgressExtension( ExtensionManifest manifest, string extensionPath, IEgressConfigurationProvider configurationProvider, - ILogger logger) + ILogger logger, + IOptions validationOptions) { _configurationProvider = configurationProvider ?? throw new ArgumentNullException(nameof(configurationProvider)); _extensionPath = extensionPath ?? throw new ArgumentNullException(nameof(extensionPath)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _manifest = manifest ?? throw new ArgumentNullException(nameof(manifest)); + _validationOptions = validationOptions?.Value ?? throw new ArgumentNullException(nameof(validationOptions)); } /// @@ -107,7 +114,7 @@ public async Task EgressArtifact( ExtensionMode mode, CancellationToken token) { - _manifest.Validate(); + _manifest.Validate(_validationOptions); ProcessStartInfo pStart = new ProcessStartInfo() { @@ -171,7 +178,7 @@ public async Task EgressArtifact( }; var parserLogger = mode == ExtensionMode.Execute ? _logger : NullLogger.Instance; - using OutputParser parser = new(p, parserLogger); + using OutputParser parser = new(p, parserLogger, EgressArtifactResultContext.Default.EgressArtifactResult); _logger.ExtensionStarting(_manifest.Name); if (!p.Start()) @@ -183,7 +190,7 @@ public async Task EgressArtifact( // p.StandardInput.BaseStream Format: Version (int), Payload Length (long), Payload, Artifact using Stream intermediateStream = new MemoryStream(); - await JsonSerializer.SerializeAsync(intermediateStream, payload, options: null, token); + await JsonSerializer.SerializeAsync(intermediateStream, payload, ExtensionEgressPayloadContext.Default.ExtensionEgressPayload, token); using (BinaryWriter writer = new BinaryWriter(p.StandardInput.BaseStream, Encoding.UTF8, leaveOpen: true)) { @@ -284,4 +291,14 @@ private Dictionary GetConfigurationSection(string providerName, return configAsDict; } } + + [JsonSerializable(typeof(EgressArtifactResult))] + partial class EgressArtifactResultContext : JsonSerializerContext + { + } + + [JsonSerializable(typeof(ExtensionEgressPayload))] + partial class ExtensionEgressPayloadContext : JsonSerializerContext + { + } } diff --git a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs index dbc690c5bd5..95ed8ff53b9 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs @@ -1,9 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Tools.Monitor.Egress.Configuration; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace Microsoft.Diagnostics.Tools.Monitor.Egress.Extension { @@ -11,18 +14,21 @@ internal sealed class EgressExtensionFactory { private readonly IEgressConfigurationProvider _configurationProvider; private readonly ILogger _logger; + private readonly IOptions _validationOptions; public EgressExtensionFactory( IEgressConfigurationProvider configurationProvider, - ILogger logger) + ILogger logger, + IOptions validationOptions) { _configurationProvider = configurationProvider; _logger = logger; + _validationOptions = validationOptions ?? throw new ArgumentNullException(nameof(validationOptions)); } public IEgressExtension Create(ExtensionManifest manifest, string path) { - return new EgressExtension(manifest, path, _configurationProvider, _logger); + return new EgressExtension(manifest, path, _configurationProvider, _logger, _validationOptions); } } } diff --git a/src/Tools/dotnet-monitor/Egress/Extension/ExtensionEgressPayload.cs b/src/Tools/dotnet-monitor/Egress/Extension/ExtensionEgressPayload.cs index 429ee50a786..0bad8fa4e73 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/ExtensionEgressPayload.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/ExtensionEgressPayload.cs @@ -15,7 +15,7 @@ internal sealed class ExtensionEgressPayload public IDictionary Properties { get; set; } public IDictionary Configuration { get; set; } public string ProviderName { get; set; } - [JsonConverter(typeof(JsonStringEnumConverter))] + [JsonConverter(typeof(JsonStringEnumConverter))] public LogLevel LogLevel { get; set; } } } diff --git a/src/Tools/dotnet-monitor/EndpointInfo/ServerEndpointInfoSource.cs b/src/Tools/dotnet-monitor/EndpointInfo/ServerEndpointInfoSource.cs index 4e9f9a17e8d..bd063845848 100644 --- a/src/Tools/dotnet-monitor/EndpointInfo/ServerEndpointInfoSource.cs +++ b/src/Tools/dotnet-monitor/EndpointInfo/ServerEndpointInfoSource.cs @@ -184,7 +184,6 @@ private async Task ListenAsync(ReversedDiagnosticsServer server, CancellationTok try { IpcEndpointInfo info = await server.AcceptAsync(token).ConfigureAwait(false); - _ = Task.Run(async () => { try diff --git a/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs b/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs index d711f962139..24216a2f375 100644 --- a/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs +++ b/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs @@ -17,6 +17,7 @@ using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; using Models = Microsoft.Diagnostics.Monitoring.WebApi.Models; using NameFormatter = Microsoft.Diagnostics.Monitoring.WebApi.Stacks.NameFormatter; +using System.Text.Json.Serialization; namespace Microsoft.Diagnostics.Tools.Monitor.Exceptions { @@ -159,7 +160,7 @@ private async Task WriteJsonInstance(Stream stream, IExceptionInstance instance, }; } - await JsonSerializer.SerializeAsync(stream, model, cancellationToken: token); + await JsonSerializer.SerializeAsync(stream, model, ExceptionInstanceContext.Default.ExceptionInstance, cancellationToken: token); await stream.WriteAsync(JsonRecordDelimiter, token); } @@ -330,4 +331,8 @@ private static bool IncludeActivityId(IExceptionInstance instance) return !string.IsNullOrEmpty(instance.ActivityId); } } + + [JsonSerializable(typeof(Models.ExceptionInstance))] + partial class ExceptionInstanceContext : JsonSerializerContext{ + } } diff --git a/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs b/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs index 4af5efa5c31..78a67116844 100644 --- a/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs +++ b/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs @@ -3,6 +3,7 @@ #nullable disable +using Microsoft.AspNetCore.Http.Validation; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Globalization; @@ -10,16 +11,17 @@ using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; namespace Microsoft.Diagnostics.Tools.Monitor.Extensibility { - internal class ExtensionManifest : IValidatableObject + [JsonSerializable(typeof(ExtensionManifest))] + internal partial class ExtensionManifestContext : JsonSerializerContext { - private static readonly JsonSerializerOptions _serializerOptions = new() - { - Converters = { new JsonStringEnumConverter() } - }; + } + internal class ExtensionManifest : IValidatableObject + { public const string DefaultFileName = "extension.json"; /// @@ -60,7 +62,7 @@ public static ExtensionManifest FromPath(string path) try { - return JsonSerializer.Deserialize(stream, _serializerOptions); + return JsonSerializer.Deserialize(stream, ExtensionManifestContext.Default.ExtensionManifest); } catch (JsonException ex) { @@ -70,11 +72,10 @@ public static ExtensionManifest FromPath(string path) } } - public void Validate() + public void Validate(ValidationOptions validationOptions) { List results = new(); - if (!Validator.TryValidateObject(this, new ValidationContext(this), results, validateAllProperties: true) && - results.Count > 0) + if (!ValidationHelper.TryValidateObject(this, typeof(ExtensionManifest), validationOptions, results)) { ExtensionException.ThrowInvalidManifest(results.First().ErrorMessage); } diff --git a/src/Tools/dotnet-monitor/Extensibility/ExtensionMode.cs b/src/Tools/dotnet-monitor/Extensibility/ExtensionMode.cs index 5a964518860..b023587a529 100644 --- a/src/Tools/dotnet-monitor/Extensibility/ExtensionMode.cs +++ b/src/Tools/dotnet-monitor/Extensibility/ExtensionMode.cs @@ -1,8 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Text.Json.Serialization; + namespace Microsoft.Diagnostics.Tools.Monitor.Extensibility { + [JsonConverter(typeof(JsonStringEnumConverter))] internal enum ExtensionMode { Execute, diff --git a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs index ff24f7ad375..2b488129b22 100644 --- a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs @@ -8,6 +8,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi.Controllers; using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Tools.Monitor.OpenApi.Transformers; +using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models.Interfaces; diff --git a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs index 19092de8c76..0f774f6bf0a 100644 --- a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs +++ b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Authentication; @@ -40,6 +40,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; +using System.Diagnostics.CodeAnalysis; using System.IO; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; @@ -196,7 +197,7 @@ public static IServiceCollection ConfigureCollectionRules(this IServiceCollectio return services; } - public static IServiceCollection RegisterCollectionRuleAction(this IServiceCollection services, string actionName) + public static IServiceCollection RegisterCollectionRuleAction<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFactory, TOptions>(this IServiceCollection services, string actionName) where TFactory : class, ICollectionRuleActionFactory where TOptions : BaseRecordOptions, new() { @@ -209,7 +210,7 @@ public static IServiceCollection RegisterCollectionRuleAction(this IServiceCollection services, string triggerName) + public static IServiceCollection RegisterCollectionRuleTrigger<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFactory>(this IServiceCollection services, string triggerName) where TFactory : class, ICollectionRuleTriggerFactory { services.AddSingleton(); @@ -219,7 +220,7 @@ public static IServiceCollection RegisterCollectionRuleTrigger(this IS return services; } - public static IServiceCollection RegisterCollectionRuleTrigger(this IServiceCollection services, string triggerName) + public static IServiceCollection RegisterCollectionRuleTrigger<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFactory, TOptions>(this IServiceCollection services, string triggerName) where TFactory : class, ICollectionRuleTriggerFactory where TOptions : class, new() { diff --git a/src/Tools/dotnet-monitor/Startup.cs b/src/Tools/dotnet-monitor/Startup.cs index 10b3272ef78..6d137ec8c66 100644 --- a/src/Tools/dotnet-monitor/Startup.cs +++ b/src/Tools/dotnet-monitor/Startup.cs @@ -32,8 +32,11 @@ public void ConfigureServices(IServiceCollection services) { services.ConfigureHttpJsonOptions(options => { options.SerializerOptions.Converters.Add(new JsonStringEnumConverter()); + options.SerializerOptions.TypeInfoResolverChain.Add(MonitorJsonSerializerContext.Default); }); + services.AddValidation(); + services.Configure(options => { options.InvalidModelStateResponseFactory = context => diff --git a/src/Tools/dotnet-monitor/ValidatableTypes.cs b/src/Tools/dotnet-monitor/ValidatableTypes.cs new file mode 100644 index 00000000000..d535e7540ee --- /dev/null +++ b/src/Tools/dotnet-monitor/ValidatableTypes.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Http.Validation; +using Microsoft.Diagnostics.Monitoring.WebApi; + +namespace Microsoft.Diagnostics.Tools.Monitor +{ + // The Validation source generator doesn't run for libraries that don't call AddValidation, + // so we can't generate IValidatableInfo by using [ValidatableType] directly on types defined + // in ProjectReferences. This is a workaround to force the generator running in this project to + // generate IValidatableInfo for the referenced types. The containing class is not used otherwise. + [ValidatableType] + internal class ValidatableTypes + { + public required MetricsOptions MetricsOptions { get; init; } + + public required AuthenticationOptions AuthenticationOptions { get; init; } + } +} diff --git a/src/Tools/dotnet-monitor/dotnet-monitor.csproj b/src/Tools/dotnet-monitor/dotnet-monitor.csproj index fdaa8a04563..77ddaa9443a 100644 --- a/src/Tools/dotnet-monitor/dotnet-monitor.csproj +++ b/src/Tools/dotnet-monitor/dotnet-monitor.csproj @@ -1,4 +1,7 @@ - + + + + $(ToolTargetFrameworks) Microsoft.Diagnostics.Tools.Monitor @@ -12,8 +15,16 @@ false true + true + false + true + $(InterceptorsNamespaces);Microsoft.AspNetCore.Http.Validation.Generated + $(NoWarn);IDE0005 + + $(NoWarn);NU1603 + @@ -133,4 +144,25 @@ + + + + + + + + + + + From db6052f448958f070c422a45401e8d2b5aff09e2 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 7 Apr 2025 22:54:57 +0000 Subject: [PATCH 107/174] Some fixes --- eng/Versions.props | 2 +- ...nostics.Monitoring.Extension.Common.csproj | 22 +- .../Models/EgressOperationStatus.cs | 2 +- .../MonitorJsonSerializerContext.cs | 18 +- .../ExecuteActionTests.cs | 4 +- .../ActionDependencyAnalyzerTests.cs | 26 +- .../ExtensionManifestTests.cs | 11 +- ....Diagnostics.Monitoring.UnitTestApp.csproj | 2 +- .../CollectionRules/ActionListExecutor.cs | 2 +- .../ActionOptionsDependencyAnalyzer.cs | 7 +- .../CollectionRuleBindingHelper.cs | 17 +- .../Actions/CollectExceptionsOptions.cs | 6 +- .../Options/ValidationHelper.cs | 6 +- .../dotnet-monitor/CommonOptionsExtensions.cs | 265 +++++++++++++----- .../ConfigurationTokenParser.cs | 41 ++- .../DataAnnotationValidateOptions.cs | 2 + .../DynamicNamedOptionsCache.cs | 2 +- src/Tools/dotnet-monitor/Program.cs | 2 - src/Tools/dotnet-monitor/RootOptions.cs | 1 - src/Tools/dotnet-monitor/TestAssemblies.cs | 26 -- .../dotnet-monitor/dotnet-monitor.csproj | 7 + 21 files changed, 319 insertions(+), 152 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 8609f02a9ab..90ba5c67828 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -27,7 +27,7 @@ $(LatestTargetFramework) - net7.0;net8.0;$(LatestTargetFramework) + net8.0;$(LatestTargetFramework) net10.0 diff --git a/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj b/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj index 8879d6f8eb6..85b1a8f36a7 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj +++ b/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj @@ -1,9 +1,9 @@ - + Library false - $(ToolTargetFrameworks) + $(LatestTargetFramework) $(DefineConstants);EXTENSION true true @@ -11,6 +11,7 @@ + @@ -20,8 +21,6 @@ - - @@ -40,4 +39,19 @@ ResXFileCodeGenerator + + + + + + + diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EgressOperationStatus.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EgressOperationStatus.cs index 9238f2ff58e..49b6c2cd50f 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EgressOperationStatus.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EgressOperationStatus.cs @@ -60,7 +60,7 @@ public class OperationStatus : OperationSummary public OperationError? Error { get; set; } } - [JsonConverter(typeof(JsonStringEnumConverter))] + [JsonConverter(typeof(JsonStringEnumConverter))] public enum OperationState { Starting, diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs index e4267511a45..620676dba2b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs @@ -1,19 +1,35 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Collections.Generic; using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Mvc; using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Monitoring.Options; namespace Microsoft.Diagnostics.Monitoring.WebApi { [JsonSerializable(typeof(CaptureParametersConfiguration))] + [JsonSerializable(typeof(CollectionRuleDetailedDescription))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(DotnetMonitorInfo))] + [JsonSerializable(typeof(DumpType))] [JsonSerializable(typeof(EventMetricsConfiguration))] [JsonSerializable(typeof(EventPipeConfiguration))] [JsonSerializable(typeof(ExceptionsConfiguration))] - [JsonSerializable(typeof(LogsConfiguration))] + [JsonSerializable(typeof(FileResult))] + [JsonSerializable(typeof(Guid?))] + [JsonSerializable(typeof(IEnumerable))] + [JsonSerializable(typeof(IEnumerable))] [JsonSerializable(typeof(IList))] + [JsonSerializable(typeof(LogsConfiguration))] + [JsonSerializable(typeof(OperationStatus))] + [JsonSerializable(typeof(ProcessInfo))] + [JsonSerializable(typeof(ProblemDetails))] + [JsonSerializable(typeof(TraceProfile))] + [JsonSerializable(typeof(ValidationProblemDetails))] partial class MonitorJsonSerializerContext : JsonSerializerContext { } diff --git a/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs index e5bf473507b..7c9e032324c 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs @@ -1,11 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Exceptions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Extensions.Options; using System; using System.Globalization; using System.IO; @@ -175,7 +177,7 @@ private static void ValidateActionResult(CollectionRuleActionResult result, stri private static async Task ValidateAction(Action optionsCallback, Func actionCallback) { - ExecuteActionFactory factory = new(); + ExecuteActionFactory factory = new(Options.Create(new())); ExecuteOptions options = new(); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs index 003a036ec8f..c1481efe30d 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs @@ -142,14 +142,14 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => [Fact] public async Task ProcessInfoTest() { - PassThroughOptions settings = null; + CollectionRuleActionOptions actionOptions = null; await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { CollectionRuleOptions options = rootOptions.CreateCollectionRule(DefaultRuleName) .AddPassThroughAction("a1", ConfigurationTokenParser.ProcessNameReference, ConfigurationTokenParser.ProcessIdReference, ConfigurationTokenParser.CommandLineReference) .SetStartupTrigger(); - settings = (PassThroughOptions)options.Actions.Last().Settings; + actionOptions = options.Actions.Last(); }, host => { using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TimeoutMs); @@ -166,7 +166,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => CollectionRuleContext context = new(DefaultRuleName, ruleOptions, new TestProcessInfo(instanceId, processId: processId, commandLine: commandLine), HostInfo.GetCurrent(timeProvider), logger); ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); - PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, settings); + PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, actionOptions); Assert.Equal(processName, newSettings.Input1); Assert.Equal(processId.ToString(CultureInfo.InvariantCulture), newSettings.Input2); @@ -181,14 +181,14 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => [Fact] public async Task HostInfoTest() { - PassThroughOptions settings = null; + CollectionRuleActionOptions actionOptions = null; await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { CollectionRuleOptions options = rootOptions.CreateCollectionRule(DefaultRuleName) .AddPassThroughAction("a1", ConfigurationTokenParser.HostNameReference, ConfigurationTokenParser.UnixTimeReference, "test") .SetStartupTrigger(); - settings = (PassThroughOptions)options.Actions.Last().Settings; + actionOptions = options.Actions.Last(); }, host => { using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TimeoutMs); @@ -203,7 +203,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => CollectionRuleContext context = new(DefaultRuleName, ruleOptions, new TestProcessInfo(instanceId), hostInfo, logger); ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); - PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, settings); + PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, actionOptions); Assert.Equal(hostName, newSettings.Input1); Assert.Equal(hostInfo.TimeProvider.GetUtcNow().ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture), newSettings.Input2); @@ -223,7 +223,7 @@ public async Task InvalidTokenReferenceTest() string a2input3 = "$(Actions.a1.MissingResult)"; LogRecord record = new LogRecord(); - PassThroughOptions settings = null; + CollectionRuleActionOptions actionOptions = null; await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { CollectionRuleOptions options = rootOptions.CreateCollectionRule(DefaultRuleName) @@ -231,7 +231,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => .AddPassThroughAction("a2", a2input1, a2input2, a2input3) .SetStartupTrigger(); - settings = (PassThroughOptions)options.Actions.Last().Settings; + actionOptions = options.Actions.Last(); }, host => { using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TimeoutMs); @@ -245,7 +245,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); analyzer.GetActionDependencies(1); - analyzer.SubstituteOptionValues(new Dictionary(), 1, settings); + analyzer.SubstituteOptionValues(new Dictionary(), 1, actionOptions); Assert.Equal(3, record.Events.Count); Assert.Equal(LoggingEventIds.InvalidActionReferenceToken.Id(), record.Events[0].EventId.Id); @@ -264,15 +264,15 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => [Fact] public async Task RuntimeIdReferenceTest() { - PassThroughOptions settings = null; + CollectionRuleActionOptions actionOptions = null; await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { CollectionRuleOptions options = rootOptions.CreateCollectionRule(DefaultRuleName) .AddPassThroughAction("a1", ConfigurationTokenParser.RuntimeIdReference, "test", "test") .SetStartupTrigger(); - settings = (PassThroughOptions)options.Actions.Last().Settings; - }, host => + actionOptions = options.Actions.Last(); + }, host => { using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TimeoutMs); @@ -284,7 +284,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => CollectionRuleContext context = new(DefaultRuleName, ruleOptions, new TestProcessInfo(instanceId), HostInfo.GetCurrent(timeProvider), logger); ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); - PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, settings); + PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, actionOptions); Assert.Equal(instanceId.ToString("D"), newSettings.Input1); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs index b3794d70476..54ba35dfb0e 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; using System.IO; @@ -91,7 +92,7 @@ public void ExtensionManifest_EmptyObject_ThrowOnValidate() Assert.Null(manifest.AssemblyFileName); Assert.Null(manifest.ExecutableFileName); - ExtensionException ex = Assert.Throws(manifest.Validate); + ExtensionException ex = Assert.Throws(() => manifest.Validate(new Microsoft.AspNetCore.Http.Validation.ValidationOptions())); Assert.Null(ex.InnerException); } @@ -115,7 +116,7 @@ public void ExtensionManifest_NameOnly_ThrowOnValidate() Assert.Null(manifest.AssemblyFileName); Assert.Null(manifest.ExecutableFileName); - ExtensionException ex = Assert.Throws(manifest.Validate); + ExtensionException ex = Assert.Throws(() => manifest.Validate(new ValidationOptions())); Assert.Null(ex.InnerException); } @@ -141,7 +142,7 @@ public void ExtensionManifest_ExecutableAndAssembly_ThrowOnValidate() Assert.Equal(ExpectedAssemblyName, manifest.AssemblyFileName); Assert.Equal(ExpectedExecutableName, manifest.ExecutableFileName); - ExtensionException ex = Assert.Throws(manifest.Validate); + ExtensionException ex = Assert.Throws(() => manifest.Validate(new ValidationOptions())); Assert.Null(ex.InnerException); } @@ -166,7 +167,7 @@ public void ExtensionManifest_NameAndAssembly_Valid() Assert.Equal(ExpectedAssemblyName, manifest.AssemblyFileName); Assert.Null(manifest.ExecutableFileName); - manifest.Validate(); + manifest.Validate(new ValidationOptions()); } [Fact] @@ -190,7 +191,7 @@ public void ExtensionManifest_NameAndExecutable_Valid() Assert.Null(manifest.AssemblyFileName); Assert.Equal(ExpectedExecutableName, manifest.ExecutableFileName); - manifest.Validate(); + manifest.Validate(new ValidationOptions()); } private static Stream CreateManifestStream(TemporaryDirectory dir, out string path) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Microsoft.Diagnostics.Monitoring.UnitTestApp.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Microsoft.Diagnostics.Monitoring.UnitTestApp.csproj index 491846954a5..c3b4483e1b7 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Microsoft.Diagnostics.Monitoring.UnitTestApp.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Microsoft.Diagnostics.Monitoring.UnitTestApp.csproj @@ -26,7 +26,7 @@ - + > ExecuteAction )); } - object? newSettings = dependencyAnalyzer.SubstituteOptionValues(actionResults, actionIndex, actionOption.Settings); + object? newSettings = dependencyAnalyzer.SubstituteOptionValues(actionResults, actionIndex, actionOption); ICollectionRuleAction? action = factory.Create(context.ProcessInfo, newSettings); try diff --git a/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs b/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs index 2efb134cf1f..5e30eeb561a 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs @@ -112,8 +112,9 @@ public IList GetActionDependencies(int actionIndex) } #nullable restore - public object? SubstituteOptionValues(IDictionary actionResults, int actionIndex, object? settings) + public object? SubstituteOptionValues(IDictionary actionResults, int actionIndex, CollectionRuleActionOptions actionOptions) { + object? settings = actionOptions.Settings; //Attempt to substitute context properties. object? originalSettings = settings; @@ -160,7 +161,7 @@ public IList GetActionDependencies(int actionIndex) } string? commandLine = _ruleContext.EndpointInfo.CommandLine; - settings = _tokenParser.SubstituteOptionValues(settings, new TokenContext + settings = _tokenParser.SubstituteOptionValues(actionOptions, new TokenContext { CloneOnSubstitution = ReferenceEquals(originalSettings, settings), RuntimeId = _ruleContext.EndpointInfo.RuntimeInstanceCookie, @@ -289,7 +290,7 @@ private bool GetActionResultReference(string actionReference, int actionIndex, private static IEnumerable GetDependencyPropertiesFromSettings(CollectionRuleActionOptions options) { - return ConfigurationTokenParser.GetPropertiesFromSettings(options.Settings, p => p.GetCustomAttributes(typeof(ActionOptionsDependencyPropertyAttribute), inherit: true).Any()); + return ConfigurationTokenParser.GetPropertiesFromSettings(options, p => p.GetCustomAttributes(typeof(ActionOptionsDependencyPropertyAttribute), inherit: true).Any()); } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs index 9690a738a46..5d5cd0358ea 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs @@ -14,14 +14,15 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration { internal static class CollectionRuleBindingHelper { - public static object CreateActionSettings( - string actionType, - Func collectDump, - Func collectExceptions - ) => actionType switch { - KnownCollectionRuleActions.CollectDump => collectDump(), - KnownCollectionRuleActions.CollectExceptions => collectExceptions(), - }; + // public static object CreateActionSettings( + // string actionType, + // Func collectDump, + // Func collectExceptions + // ) => actionType switch { + // KnownCollectionRuleActions.CollectDump => collectDump(), + // KnownCollectionRuleActions.CollectExceptions => collectExceptions(), + // _ => throw new ArgumentException($"Unknown action type: {actionType}", nameof(actionType)) + // }; // public static object NewActionSettings(string actionType) => // actionType switch { diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs index c9913707cf4..34ea08dc30b 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs @@ -16,7 +16,11 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions #if SCHEMAGEN [NJsonSchema.Annotations.JsonSchemaFlatten] #endif - internal sealed partial record class CollectExceptionsOptions : BaseRecordOptions, IEgressProviderProperties + + internal sealed partial record class CollectExceptionsOptions : + BaseRecordOptions, + // IValidateOptions, + IEgressProviderProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs index 6090102ffdc..674ed9cf682 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs @@ -11,7 +11,11 @@ using System.Reflection; using System.Threading; +#if EXTENSION +namespace Microsoft.Diagnostics.Monitoring.Extension.Common +#else namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options +#endif { internal static class ValidationHelper { @@ -50,7 +54,7 @@ public static bool TryValidateOptions(Type optionsType, object options, Validati return false; } } -#nullable restore +#nullable enable public static bool TryValidateObject(object options, Type type, ValidationOptions validationOptions, ValidationContext validationContext, ICollection results) { diff --git a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs b/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs index 718ffa4f27a..a5ac2e51956 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs @@ -6,14 +6,11 @@ #if UNITTEST using Microsoft.Diagnostics.Monitoring.TestCommon; #endif +using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Extensions.Configuration; using System; -using System.Collections; using System.Collections.Generic; using System.Globalization; -using System.Linq; -using System.Reflection; -using System.Text; namespace Microsoft.Diagnostics.Tools.Monitor { @@ -30,7 +27,7 @@ internal static class CommonOptionsExtensions public static IDictionary ToConfigurationValues(this RootOptions options) { Dictionary variables = new(StringComparer.OrdinalIgnoreCase); - MapObject(options, string.Empty, ConfigurationPath.KeyDelimiter, variables); + MapRootOptions(options, string.Empty, ConfigurationPath.KeyDelimiter, variables); return variables; } @@ -43,7 +40,7 @@ public static IDictionary ToConfigurationValues(this RootOptions public static IDictionary ToEnvironmentConfiguration(this RootOptions options, bool useDotnetMonitorPrefix = false) { Dictionary variables = new(StringComparer.OrdinalIgnoreCase); - MapObject(options, useDotnetMonitorPrefix ? ToolIdentifiers.StandardPrefix : string.Empty, KeySegmentSeparator, variables); + MapRootOptions(options, useDotnetMonitorPrefix ? ToolIdentifiers.StandardPrefix : string.Empty, KeySegmentSeparator, variables); return variables; } @@ -56,101 +53,221 @@ public static IDictionary ToEnvironmentConfiguration(this RootOp public static IDictionary ToKeyPerFileConfiguration(this RootOptions options) { Dictionary variables = new(StringComparer.OrdinalIgnoreCase); - MapObject(options, string.Empty, KeySegmentSeparator, variables); + MapRootOptions(options, string.Empty, KeySegmentSeparator, variables); return variables; } - private static void MapDictionary(IDictionary dictionary, string prefix, string separator, IDictionary map) + // private static void MapDictionary(IDictionary dictionary, string prefix, string separator, IDictionary map) + // { + // foreach (var key in dictionary.Keys) + // { + // object? value = dictionary[key]; + + // if (null != value) + // { + // string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); + // MapValue( + // value, + // FormattableString.Invariant($"{prefix}{keyString}"), + // separator, + // map); + // } + // } + // } + + // private static void MapList(IList list, string prefix, string separator, IDictionary map) + // { + // for (int index = 0; index < list.Count; index++) + // { + // object? value = list[index]; + // if (null != value) + // { + // MapValue( + // value, + // FormattableString.Invariant($"{prefix}{index}"), + // separator, + // map); + // } + // } + // } + + private static void MapRootOptions(RootOptions obj, string prefix, string separator, IDictionary map) + { + // TODO: in Tests, it has an additional property. Weird. + MapAuthenticationOptions(obj.Authentication, FormattableString.Invariant($"{prefix}{nameof(obj.Authentication)}"), separator, map); + // GlobalCounterOptions + MapGlobalCounterOptions(obj.GlobalCounter, FormattableString.Invariant($"{prefix}{nameof(obj.GlobalCounter)}"), separator, map); + // InProcessFeaturesOptions + // CorsConfigurationOptions + // DiagnosticPortOptions + // EgressOptions + // MetricsOptions + // StorageOptions + // ProcessFilterOptions + // CollectionRuleDefaultsOptions + // Templates + // DotnetMonitorDebugOptions + // FOR TESTS: Logging? + } + + // private static void MapObject<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>(object obj, string prefix, string separator, IDictionary map) + // { + // foreach (PropertyInfo property in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)) + // { + // if (!property.GetIndexParameters().Any()) + // { + // MapValue( + // property.GetValue(obj), + // FormattableString.Invariant($"{prefix}{property.Name}"), + // separator, + // map); + // } + // } + // } + + private static void MapAuthenticationOptions(AuthenticationOptions? obj, string valueName, string separator, IDictionary map) { - foreach (var key in dictionary.Keys) + if (null != obj) { - object? value = dictionary[key]; - - if (null != value) - { - string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); - MapValue( - value, - FormattableString.Invariant($"{prefix}{keyString}"), - separator, - map); - } + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapMonitorApiKeyOptions(obj.MonitorApiKey, prefix, separator, map); + MapAzureAdOptions(obj.AzureAd, prefix, separator, map); } } - private static void MapList(IList list, string prefix, string separator, IDictionary map) + private static void MapMonitorApiKeyOptions(MonitorApiKeyOptions? obj, string valueName, string separator, IDictionary map) { - for (int index = 0; index < list.Count; index++) + if (null != obj) { - object? value = list[index]; - if (null != value) - { - MapValue( - value, - FormattableString.Invariant($"{prefix}{index}"), - separator, - map); - } + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Subject, FormattableString.Invariant($"{prefix}{nameof(obj.Subject)}"), map); + MapString(obj.PublicKey, FormattableString.Invariant($"{prefix}{nameof(obj.PublicKey)}"), map); + MapString(obj.Issuer, FormattableString.Invariant($"{prefix}{nameof(obj.Issuer)}"), map); } } - private static void MapObject(object obj, string prefix, string separator, IDictionary map) + private static void MapString(string? value, string valueName, IDictionary map) { - foreach (PropertyInfo property in obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) + if (null != value) { - if (!property.GetIndexParameters().Any()) - { - MapValue( - property.GetValue(obj), - FormattableString.Invariant($"{prefix}{property.Name}"), - separator, - map); - } + map.Add(valueName, value); } } - private static void MapValue(object? value, string valueName, string separator, IDictionary map) + private static void MapAzureAdOptions(AzureAdOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapUri(obj.Instance, FormattableString.Invariant($"{prefix}{nameof(obj.Instance)}"), separator, map); + MapString(obj.TenantId, FormattableString.Invariant($"{prefix}{nameof(obj.TenantId)}"), map); + MapString(obj.ClientId, FormattableString.Invariant($"{prefix}{nameof(obj.ClientId)}"), map); + MapUri(obj.AppIdUri, FormattableString.Invariant($"{prefix}{nameof(obj.AppIdUri)}"), separator, map); + MapString(obj.RequiredRole, FormattableString.Invariant($"{prefix}{nameof(obj.RequiredRole)}"), map); + } + } + + private static void MapUri(Uri? value, string valueName, string separator, IDictionary map) { if (null != value) { - Type valueType = value.GetType(); - if (valueType.IsPrimitive || - valueType.IsEnum || - typeof(Guid) == valueType || - typeof(string) == valueType || - typeof(TimeSpan) == valueType) - { - map.Add( - valueName, - ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - else - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - if (value is IDictionary dictionary) - { - MapDictionary(dictionary, prefix, separator, map); - } - else if (value is IList list) - { - MapList(list, prefix, separator, map); - } - else - { - MapObject(value, prefix, separator, map); - } - } + // TODO! + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(value.AbsolutePath, FormattableString.Invariant($"{prefix}{nameof(value.AbsolutePath)}"), map); + MapString(value.AbsoluteUri, FormattableString.Invariant($"{prefix}{nameof(value.AbsoluteUri)}"), map); + MapString(value.Authority, FormattableString.Invariant($"{prefix}{nameof(value.Authority)}"), map); + MapString(value.DnsSafeHost, FormattableString.Invariant($"{prefix}{nameof(value.DnsSafeHost)}"), map); + MapString(value.Fragment, FormattableString.Invariant($"{prefix}{nameof(value.Fragment)}"), map); + MapString(value.Host, FormattableString.Invariant($"{prefix}{nameof(value.Host)}"), map); + // MapHostNameType() + MapString(value.IdnHost, FormattableString.Invariant($"{prefix}{nameof(value.IdnHost)}"), map); + // MapBool(value.IsAbsoluteUri, FormattableString.Invariant($"{prefix}{nameof(value.IsAbsoluteUri)}"), map); + // MapBool(value.IsDefaultPort, FormattableString.Invariant($"{prefix}{nameof(value.IsDefaultPort)}"), map); + // MapBool(value.IsFile, FormattableString.Invariant($"{prefix}{nameof(value.IsFile)}"), map); + // MapBool(value.IsLoopback, FormattableString.Invariant($"{prefix}{nameof(value.IsLoopback)}"), map); + // MapBool(value.IsUnc, FormattableString.Invariant($"{prefix}{nameof(value.IsUnc)}"), map); + MapString(value.LocalPath, FormattableString.Invariant($"{prefix}{nameof(value.LocalPath)}"), map); + MapString(value.OriginalString, FormattableString.Invariant($"{prefix}{nameof(value.OriginalString)}"), map); + MapString(value.PathAndQuery, FormattableString.Invariant($"{prefix}{nameof(value.PathAndQuery)}"), map); + // MapInt(value.Port, FormattableString.Invariant($"{prefix}{nameof(value.Port)}"), map); + MapString(value.Query, FormattableString.Invariant($"{prefix}{nameof(value.Query)}"), map); + MapString(value.Scheme, FormattableString.Invariant($"{prefix}{nameof(value.Scheme)}"), map); + // MapStringArray(value.Segments, FormattableString.Invariant($"{prefix}{nameof(value.Segments)}"), separator, map); + // MapBool(value.UserEscaped, FormattableString.Invariant($"{prefix}{nameof(value.UserEscaped)}"), map); + MapString(value.UserInfo, FormattableString.Invariant($"{prefix}{nameof(value.UserInfo)}"), map); } } - private static string ToHexString(byte[] data) + private static void MapGlobalCounterOptions(GlobalCounterOptions? obj, string valueName, string separator, IDictionary map) { - StringBuilder builder = new(2 * data.Length); - foreach (byte b in data) + if (null != obj) { - builder.Append(b.ToString("X2", CultureInfo.InvariantCulture)); + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapFloat(obj.IntervalSeconds, FormattableString.Invariant($"{prefix}{nameof(obj.IntervalSeconds)}"), map); + MapInt(obj.MaxHistograms, FormattableString.Invariant($"{prefix}{nameof(obj.MaxHistograms)}"), map); + MapInt(obj.MaxTimeSeries, FormattableString.Invariant($"{prefix}{nameof(obj.MaxTimeSeries)}"), map); + // MapDictionary(obj.Providers, prefix, separator, map); } - return builder.ToString(); } + + private static void MapFloat(float? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + + private static void MapInt(int? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + + // private static void MapValue(object? value, string valueName, string separator, IDictionary map) + // { + // if (null != value) + // { + // Type valueType = value.GetType(); + // if (valueType.IsPrimitive || + // valueType.IsEnum || + // typeof(Guid) == valueType || + // typeof(string) == valueType || + // typeof(TimeSpan) == valueType) + // { + // map.Add( + // valueName, + // ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + // } + // else + // { + // string prefix = FormattableString.Invariant($"{valueName}{separator}"); + // if (value is IDictionary dictionary) + // { + // MapDictionary(dictionary, prefix, separator, map); + // } + // else if (value is IList list) + // { + // MapList(list, prefix, separator, map); + // } + // else + // { + // MapObject(value, prefix, separator, map); + // } + // } + // } + // } + + // private static string ToHexString(byte[] data) + // { + // StringBuilder builder = new(2 * data.Length); + // foreach (byte b in data) + // { + // builder.Append(b.ToString("X2", CultureInfo.InvariantCulture)); + // } + // return builder.ToString(); + // } } } diff --git a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs index a672c46b097..03f03e1d2a0 100644 --- a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs +++ b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs @@ -1,10 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; @@ -60,11 +63,12 @@ public ConfigurationTokenParser(ILogger logger) _logger = logger; } - public object? SubstituteOptionValues(object? originalSettings, TokenContext context) + public object? SubstituteOptionValues(CollectionRuleActionOptions actionOptions, TokenContext context) { + var originalSettings = actionOptions.Settings; object? settings = originalSettings; - foreach (PropertyInfo propertyInfo in GetPropertiesFromSettings(settings)) + foreach (PropertyInfo propertyInfo in GetPropertiesFromSettings(actionOptions)) { string? originalPropertyValue = (string?)propertyInfo.GetValue(settings); if (string.IsNullOrEmpty(originalPropertyValue)) @@ -119,11 +123,34 @@ public bool TryCloneSettings(object? originalSettings, ref object? settings) return true; } - public static IEnumerable GetPropertiesFromSettings(object? settings, Predicate? predicate = null) => - settings?.GetType() - .GetProperties(BindingFlags.Public | BindingFlags.Instance) - .Where(p => p.PropertyType == typeof(string) && (predicate?.Invoke(p) ?? true)) ?? - Enumerable.Empty(); + public static IEnumerable GetPropertiesFromSettings(CollectionRuleActionOptions actionOptions, Predicate? predicate = null) + { + object? settings = actionOptions.Settings; + return actionOptions.Type switch { + KnownCollectionRuleActions.CollectDump => GetPropertiesFromSettings(typeof(CollectDumpOptions), predicate), + KnownCollectionRuleActions.CollectExceptions => GetPropertiesFromSettings(typeof(CollectExceptionsOptions), predicate), + KnownCollectionRuleActions.CollectGCDump => GetPropertiesFromSettings(typeof(CollectGCDumpOptions), predicate), + KnownCollectionRuleActions.CollectLogs => GetPropertiesFromSettings(typeof(CollectLogsOptions), predicate), + KnownCollectionRuleActions.CollectStacks => GetPropertiesFromSettings(typeof(CollectStacksOptions), predicate), + KnownCollectionRuleActions.CollectTrace => GetPropertiesFromSettings(typeof(CollectTraceOptions), predicate), + KnownCollectionRuleActions.CollectLiveMetrics => GetPropertiesFromSettings(typeof(CollectLiveMetricsOptions), predicate), + KnownCollectionRuleActions.Execute => GetPropertiesFromSettings(typeof(ExecuteOptions), predicate), + KnownCollectionRuleActions.LoadProfiler => GetPropertiesFromSettings(typeof(LoadProfilerOptions), predicate), + KnownCollectionRuleActions.SetEnvironmentVariable => GetPropertiesFromSettings(typeof(SetEnvironmentVariableOptions), predicate), + KnownCollectionRuleActions.GetEnvironmentVariable => GetPropertiesFromSettings(typeof(GetEnvironmentVariableOptions), predicate), + _ => throw new ArgumentException(string.Format( + CultureInfo.InvariantCulture, + "Unknown action type: {0}", + actionOptions.Type)) + }; + + static IEnumerable GetPropertiesFromSettings([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type, Predicate? predicate = null) + { + return type.GetProperties(BindingFlags.Public | BindingFlags.Instance) + .Where(p => p.PropertyType == typeof(string) && (predicate?.Invoke(p) ?? true)) + .ToArray(); + } + } private static string CreateTokenReference(string category, string token) => FormattableString.Invariant($"{SubstitutionPrefix}{category}{Separator}{token}{SubstitutionSuffix}"); diff --git a/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs b/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs index 2942b434859..767299b0d72 100644 --- a/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs +++ b/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs @@ -9,7 +9,9 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +#if !EXTENSION using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +#endif #if EXTENSION namespace Microsoft.Diagnostics.Monitoring.Extension.Common diff --git a/src/Tools/dotnet-monitor/DynamicNamedOptionsCache.cs b/src/Tools/dotnet-monitor/DynamicNamedOptionsCache.cs index 8efbcff1595..a56f1badc22 100644 --- a/src/Tools/dotnet-monitor/DynamicNamedOptionsCache.cs +++ b/src/Tools/dotnet-monitor/DynamicNamedOptionsCache.cs @@ -20,7 +20,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor /// internal sealed class DynamicNamedOptionsCache : OptionsCache - where TOptions : class + where TOptions : class, new() { public override TOptions GetOrAdd(string name, Func createOptions) { diff --git a/src/Tools/dotnet-monitor/Program.cs b/src/Tools/dotnet-monitor/Program.cs index 2547446eba4..e8c2fff128e 100644 --- a/src/Tools/dotnet-monitor/Program.cs +++ b/src/Tools/dotnet-monitor/Program.cs @@ -217,8 +217,6 @@ public static Task Main(string[] args) // Prevent child processes from inheriting startup hooks Environment.SetEnvironmentVariable(ToolIdentifiers.EnvironmentVariables.StartupHooks, null); - TestAssemblies.SimulateStartupHook(); - RootCommand root = new() { CollectCommand(), diff --git a/src/Tools/dotnet-monitor/RootOptions.cs b/src/Tools/dotnet-monitor/RootOptions.cs index f3a42b42575..3ee1691a5da 100644 --- a/src/Tools/dotnet-monitor/RootOptions.cs +++ b/src/Tools/dotnet-monitor/RootOptions.cs @@ -38,6 +38,5 @@ internal sealed partial class RootOptions public TemplateOptions? Templates { get; set; } public DotnetMonitorDebugOptions? DotnetMonitorDebug { get; set; } - } } diff --git a/src/Tools/dotnet-monitor/TestAssemblies.cs b/src/Tools/dotnet-monitor/TestAssemblies.cs index 92aab047af5..f90ae87eef7 100644 --- a/src/Tools/dotnet-monitor/TestAssemblies.cs +++ b/src/Tools/dotnet-monitor/TestAssemblies.cs @@ -19,32 +19,6 @@ internal static class TestAssemblies { private const string ArtifactsDirectoryName = "artifacts"; private const string TestHostingStartupAssemblyName = "Microsoft.Diagnostics.Monitoring.Tool.TestHostingStartup"; - private const string TestStartupHookAssemblyName = "Microsoft.Diagnostics.Monitoring.Tool.TestStartupHook"; - -#nullable disable - [Conditional("DEBUG")] - public static void SimulateStartupHook() - { - // This code is to aid loading the TestStartupHook assembly when debug launching dotnet-monitor - // so that additional manual configuration is not necessary. The functional tests already bootstrap - // loading this assembly and initialize the hosting startup using standard dotnet environment variables. - - AssemblyLoadContext alc = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()); - // Skip attempting to load if it is already loaded - if (!alc.Assemblies.Any(a => TestStartupHookAssemblyName.Equals(a.GetName().Name))) - { - // Only load if can compute the path correctly - if (TryComputeBuildOutputAssemblyPath(TestStartupHookAssemblyName, out string startupHookAssemblyPath)) - { - // Load and simulate startup hook initialization - Assembly startupHookAssembly = alc.LoadFromAssemblyPath(startupHookAssemblyPath); - Type startupHookType = startupHookAssembly.GetType("StartupHook"); - MethodInfo initializeMethod = startupHookType.GetMethod("Initialize", BindingFlags.Public | BindingFlags.Static); - initializeMethod.Invoke(null, Array.Empty()); - } - } - } -#nullable restore [Conditional("DEBUG")] public static void AddHostingStartup(IWebHostBuilder builder) diff --git a/src/Tools/dotnet-monitor/dotnet-monitor.csproj b/src/Tools/dotnet-monitor/dotnet-monitor.csproj index 77ddaa9443a..456fc217d8b 100644 --- a/src/Tools/dotnet-monitor/dotnet-monitor.csproj +++ b/src/Tools/dotnet-monitor/dotnet-monitor.csproj @@ -165,4 +165,11 @@ LatestRuntimeFrameworkVersion="$(AspNetCoreAppVersion)" /> + + + + + + + From 309d27a452b53b8a2be31dad03999b39a703d516 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 7 Apr 2025 23:08:29 +0000 Subject: [PATCH 108/174] Remove BaseOptions reference --- .../Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj index 4ff7f536c46..6f70d1ba2c1 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj @@ -69,7 +69,6 @@ - From 6c14f869c7ec9d1d22f1e03c403805bb8a049772 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 8 Apr 2025 22:39:48 +0000 Subject: [PATCH 109/174] Add generated resolver --- .../MonitorJsonSerializerContext.cs | 1 + src/Tools/dotnet-monitor/Startup.cs | 3 +- .../dotnet-monitor/ValidatableInfoResolver.cs | 285 ++++++++++++++++++ 3 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 src/Tools/dotnet-monitor/ValidatableInfoResolver.cs diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs index 620676dba2b..1e60566bd6b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs @@ -25,6 +25,7 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi [JsonSerializable(typeof(IEnumerable))] [JsonSerializable(typeof(IList))] [JsonSerializable(typeof(LogsConfiguration))] + [JsonSerializable(typeof(MetricsOptions))] [JsonSerializable(typeof(OperationStatus))] [JsonSerializable(typeof(ProcessInfo))] [JsonSerializable(typeof(ProblemDetails))] diff --git a/src/Tools/dotnet-monitor/Startup.cs b/src/Tools/dotnet-monitor/Startup.cs index 6d137ec8c66..5557b57b56b 100644 --- a/src/Tools/dotnet-monitor/Startup.cs +++ b/src/Tools/dotnet-monitor/Startup.cs @@ -15,6 +15,7 @@ using System.IO.Compression; using System.Text.Json.Serialization; using System.Reflection; +using Microsoft.AspNetCore.Http.Validation.Generated; namespace Microsoft.Diagnostics.Tools.Monitor { @@ -35,7 +36,7 @@ public void ConfigureServices(IServiceCollection services) options.SerializerOptions.TypeInfoResolverChain.Add(MonitorJsonSerializerContext.Default); }); - services.AddValidation(); + MyExtensions.AddValidation(services); services.Configure(options => { diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs new file mode 100644 index 00000000000..9d6dc1de686 --- /dev/null +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -0,0 +1,285 @@ +#nullable enable annotations +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ +#nullable enable + +namespace System.Runtime.CompilerServices +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : System.Attribute + { + public InterceptsLocationAttribute(int version, string data) + { + } + } +} + +namespace Microsoft.AspNetCore.Http.Validation.Generated +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file sealed class GeneratedValidatablePropertyInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatablePropertyInfo + { + public GeneratedValidatablePropertyInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] + global::System.Type containingType, + global::System.Type propertyType, + string name, + string displayName) : base(containingType, propertyType, name, displayName) + { + ContainingType = containingType; + Name = name; + } + + [global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] + internal global::System.Type ContainingType { get; } + internal string Name { get; } + + protected override global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes() + => ValidationAttributeCache.GetValidationAttributes(ContainingType, Name); + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file sealed class GeneratedValidatableTypeInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatableTypeInfo + { + public GeneratedValidatableTypeInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.Interfaces)] + global::System.Type type, + ValidatablePropertyInfo[] members) : base(type, members) { } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file class GeneratedValidatableInfoResolver : global::Microsoft.AspNetCore.Http.Validation.IValidatableInfoResolver + { + public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) + { + System.Console.WriteLine("My TryGetValidatableTypeInfo"); + validatableInfo = null; + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider)) + { + validatableInfo = CreateMetricProvider(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions)) + { + validatableInfo = CreateMetricsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions)) + { + validatableInfo = CreateMonitorApiKeyOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions)) + { + validatableInfo = CreateAzureAdOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions)) + { + validatableInfo = CreateAuthenticationOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes)) + { + validatableInfo = CreateValidatableTypes(); + return true; + } + + return false; + } + + // No-ops, rely on runtime code for ParameterInfo-based resolution + public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterInfo parameterInfo, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) + { + validatableInfo = null; + return false; + } + + private ValidatableTypeInfo CreateMetricProvider() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), + propertyType: typeof(string), + name: "ProviderName", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateMetricsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + propertyType: typeof(int?), + name: "MetricCount", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Providers", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateMonitorApiKeyOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + propertyType: typeof(string), + name: "Subject", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + propertyType: typeof(string), + name: "PublicKey", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateAzureAdOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "TenantId", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "ClientId", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(global::System.Uri), + name: "AppIdUri", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "RequiredRole", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateAuthenticationOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + name: "MonitorApiKey", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + name: "AzureAd", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateValidatableTypes() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + name: "MetricsOptions", + displayName: "MetricsOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + name: "AuthenticationOptions", + displayName: "AuthenticationOptions" + ), + ] + ); + } + + } + + static class MyExtensions + { + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + { + return GeneratedServiceCollectionExtensions.AddValidation(services, configureOptions); + } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file static class GeneratedServiceCollectionExtensions + { + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "KANyLGuJNiNmJ3Sx9yUA6pQGAABTdGFydHVwLmNz")] + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + { + System.Console.WriteLine("My AddValidation"); + // Use non-extension method to avoid infinite recursion. + return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => + { + options.Resolvers.Insert(0, new GeneratedValidatableInfoResolver()); + if (configureOptions is not null) + { + configureOptions(options); + } + }); + } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file static class ValidationAttributeCache + { + private sealed record CacheKey([property: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] global::System.Type ContainingType, string PropertyName); + private static readonly global::System.Collections.Concurrent.ConcurrentDictionary _cache = new(); + + public static global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes( + [global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] + global::System.Type containingType, + string propertyName) + { + var key = new CacheKey(containingType, propertyName); + return _cache.GetOrAdd(key, static k => + { + var property = k.ContainingType.GetProperty(k.PropertyName); + if (property == null) + { + return []; + } + + return [.. global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(property, inherit: true)]; + }); + } + } +} \ No newline at end of file From 82b89b825bdad6d059649dd7a6d6731861c3ad8c Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 9 Apr 2025 17:39:14 +0000 Subject: [PATCH 110/174] Remove JsonSerializable(MetricsOptions) This type was needed for validation only. --- .../MonitorJsonSerializerContext.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs index 1e60566bd6b..620676dba2b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs @@ -25,7 +25,6 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi [JsonSerializable(typeof(IEnumerable))] [JsonSerializable(typeof(IList))] [JsonSerializable(typeof(LogsConfiguration))] - [JsonSerializable(typeof(MetricsOptions))] [JsonSerializable(typeof(OperationStatus))] [JsonSerializable(typeof(ProcessInfo))] [JsonSerializable(typeof(ProblemDetails))] From c454bf08c89c2eb18a7e2cd29639679a02421bb8 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 9 Apr 2025 22:27:16 +0000 Subject: [PATCH 111/174] Fix ExtensionManifest_EmptyObject_ThrowOnValidate test --- Directory.Packages.props | 1 + .../CollectionRuleActions.UnitTests.csproj | 1 - .../ExtensionManifestTests.cs | 22 +++++++++++---- ...agnostics.Monitoring.Tool.UnitTests.csproj | 9 +++++- ...ics.Monitoring.Tool.UnitTestsSample.csproj | 20 +++++++++++++ .../Program.cs | 17 +++++++++++ .../Extensibility/ExtensionManifest.cs | 7 +++-- .../HostBuilder/HostBuilderHelper.cs | 2 -- src/Tools/dotnet-monitor/Startup.cs | 2 -- .../dotnet-monitor/ValidatableInfoResolver.cs | 28 +++++++++++++++---- .../dotnet-monitor/dotnet-monitor.csproj | 2 +- 11 files changed, 90 insertions(+), 21 deletions(-) create mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj create mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index f37bd594e4c..ec92f28debd 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -29,5 +29,6 @@ + diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj b/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj index aa0591b54fc..77d43fdf25c 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj @@ -2,7 +2,6 @@ $(ToolTargetFrameworks) - true diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs index 54ba35dfb0e..7997a5942a1 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs @@ -4,6 +4,9 @@ using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.AspNetCore.Mvc.Testing; using System.IO; using System.Text.Json; using Xunit; @@ -11,18 +14,24 @@ namespace Microsoft.Diagnostics.Monitoring.Tool.UnitTests { + public class ExtensionManifestFixture : WebApplicationFactory + { + } + [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] - public sealed class ExtensionManifestTests + public sealed class ExtensionManifestTests : IClassFixture { private const string ExpectedName = "CustomEgress"; private const string ExpectedExecutableName = "CustomExecutable"; private const string ExpectedAssemblyName = "CustomAssembly"; private readonly ITestOutputHelper _outputHelper; + private readonly ExtensionManifestFixture _fixture; - public ExtensionManifestTests(ITestOutputHelper outputHelper) + public ExtensionManifestTests(ITestOutputHelper outputHelper, ExtensionManifestFixture fixture) { _outputHelper = outputHelper; + _fixture = fixture; } [Fact] @@ -92,7 +101,8 @@ public void ExtensionManifest_EmptyObject_ThrowOnValidate() Assert.Null(manifest.AssemblyFileName); Assert.Null(manifest.ExecutableFileName); - ExtensionException ex = Assert.Throws(() => manifest.Validate(new Microsoft.AspNetCore.Http.Validation.ValidationOptions())); + var validationOptions = _fixture.Services.GetRequiredService>().Value; + ExtensionException ex = Assert.Throws(() => manifest.Validate(validationOptions)); Assert.Null(ex.InnerException); } @@ -106,8 +116,7 @@ public void ExtensionManifest_NameOnly_ThrowOnValidate() { using Utf8JsonWriter writer = new(stream); writer.WriteStartObject(); - writer.WriteString(nameof(ExtensionManifest.Name), ExpectedName); - writer.WriteEndObject(); + writer.WriteString(nameof(ExtensionManifest.Name), ExpectedName);writer.WriteEndObject(); writer.Flush(); } @@ -116,7 +125,8 @@ public void ExtensionManifest_NameOnly_ThrowOnValidate() Assert.Null(manifest.AssemblyFileName); Assert.Null(manifest.ExecutableFileName); - ExtensionException ex = Assert.Throws(() => manifest.Validate(new ValidationOptions())); + var validationOptions = _fixture.Services.GetRequiredService>().Value; + ExtensionException ex = Assert.Throws(() => manifest.Validate(validationOptions)); Assert.Null(ex.InnerException); } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj index cb44deedb4b..a5c69515fa1 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj @@ -1,4 +1,4 @@ - + $(ToolTargetFrameworks) @@ -8,6 +8,7 @@ + @@ -15,6 +16,7 @@ + @@ -182,4 +184,9 @@ + + + + + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj new file mode 100644 index 00000000000..d6e2b1a4fb4 --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj @@ -0,0 +1,20 @@ + + + + net10.0 + enable + enable + $(InterceptorsNamespaces);Microsoft.AspNetCore.Http.Validation.Generated + true + + + + + + + + + + + + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs new file mode 100644 index 00000000000..144268118c5 --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Http.Validation; +using Microsoft.Diagnostics.Tools.Monitor.Extensibility; + +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddValidation(); +builder.Build(); + +public partial class Program {} + +[ValidatableType] +sealed class TestValidatableType +{ + public required ExtensionManifest ExtensionManifest { get; init; } +} diff --git a/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs b/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs index 78a67116844..ca9a5e4a7d0 100644 --- a/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs +++ b/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs @@ -20,6 +20,7 @@ internal partial class ExtensionManifestContext : JsonSerializerContext { } + [ValidatableType] internal class ExtensionManifest : IValidatableObject { public const string DefaultFileName = "extension.json"; @@ -96,7 +97,8 @@ public IEnumerable Validate(ValidationContext validationContex CultureInfo.InvariantCulture, Strings.ErrorMessage_TwoFieldsCannotBeSpecified, nameof(AssemblyFileName), - nameof(ExecutableFileName)))); + nameof(ExecutableFileName)), + [nameof(AssemblyFileName), nameof(ExecutableFileName)])); } if (!hasAssemblyFileName && !hasExecutableFileName) @@ -107,7 +109,8 @@ public IEnumerable Validate(ValidationContext validationContex CultureInfo.InvariantCulture, Strings.ErrorMessage_TwoFieldsMissing, nameof(AssemblyFileName), - nameof(ExecutableFileName)))); + nameof(ExecutableFileName)), + [nameof(AssemblyFileName), nameof(ExecutableFileName)])); } return results; diff --git a/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs b/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs index ed3cb744a00..f04780d753d 100644 --- a/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs +++ b/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs @@ -115,8 +115,6 @@ public static IHostBuilder CreateHostBuilder(HostBuilderSettings settings) //is not added until WebHostDefaults are added. .ConfigureWebHostDefaults(webBuilder => { - TestAssemblies.AddHostingStartup(webBuilder); - // ASP.NET will initially create a configuration that primarily contains // the ASPNETCORE_* environment variables. This IWebHostBuilder configuration callback // is invoked before any of the usual configuration phases (host, app, service, container) diff --git a/src/Tools/dotnet-monitor/Startup.cs b/src/Tools/dotnet-monitor/Startup.cs index 5557b57b56b..47f567b0930 100644 --- a/src/Tools/dotnet-monitor/Startup.cs +++ b/src/Tools/dotnet-monitor/Startup.cs @@ -36,8 +36,6 @@ public void ConfigureServices(IServiceCollection services) options.SerializerOptions.TypeInfoResolverChain.Add(MonitorJsonSerializerContext.Default); }); - MyExtensions.AddValidation(services); - services.Configure(options => { options.InvalidModelStateResponseFactory = context => diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index 9d6dc1de686..decce8f8067 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -1,4 +1,4 @@ -#nullable enable annotations +#nullable enable annotations //------------------------------------------------------------------------------ // // This code was generated by a tool. @@ -59,8 +59,12 @@ public GeneratedValidatableTypeInfo( { public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) { - System.Console.WriteLine("My TryGetValidatableTypeInfo"); validatableInfo = null; + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest)) + { + validatableInfo = CreateExtensionManifest(); + return true; + } if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider)) { validatableInfo = CreateMetricProvider(); @@ -102,6 +106,20 @@ public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterIn return false; } + private ValidatableTypeInfo CreateExtensionManifest() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), + propertyType: typeof(string), + name: "Name", + displayName: "Name" + ), + ] + ); + } private ValidatableTypeInfo CreateMetricProvider() { return new GeneratedValidatableTypeInfo( @@ -242,10 +260,9 @@ static class MyExtensions [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] file static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "KANyLGuJNiNmJ3Sx9yUA6pQGAABTdGFydHVwLmNz")] + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "M2kOaR09/X9mJ22GvhUC4+4FAABTdGFydHVwLmNz")] public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { - System.Console.WriteLine("My AddValidation"); // Use non-extension method to avoid infinite recursion. return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => { @@ -265,7 +282,6 @@ private sealed record CacheKey([property: global::System.Diagnostics.CodeAnalysi private static readonly global::System.Collections.Concurrent.ConcurrentDictionary _cache = new(); public static global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes( - [global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] global::System.Type containingType, string propertyName) { @@ -282,4 +298,4 @@ private sealed record CacheKey([property: global::System.Diagnostics.CodeAnalysi }); } } -} \ No newline at end of file +} diff --git a/src/Tools/dotnet-monitor/dotnet-monitor.csproj b/src/Tools/dotnet-monitor/dotnet-monitor.csproj index 456fc217d8b..ee6933ead84 100644 --- a/src/Tools/dotnet-monitor/dotnet-monitor.csproj +++ b/src/Tools/dotnet-monitor/dotnet-monitor.csproj @@ -54,6 +54,7 @@ + @@ -167,7 +168,6 @@ - From db1ee7e3496eacc9de14b504d01f88306a836aac Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 9 Apr 2025 23:13:59 +0000 Subject: [PATCH 112/174] Clean up Mcirosoft.Extensions.Logging.Abstractions version --- eng/dependabot/net10.0/Versions.props | 1 - .../Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj | 1 - 2 files changed, 2 deletions(-) diff --git a/eng/dependabot/net10.0/Versions.props b/eng/dependabot/net10.0/Versions.props index 51c0eb6b725..1df4da9faf3 100644 --- a/eng/dependabot/net10.0/Versions.props +++ b/eng/dependabot/net10.0/Versions.props @@ -13,6 +13,5 @@ $(MicrosoftNETCoreApp100Version) - 10.0.0-preview.4.25207.7 diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj index 2ec74e69f6c..5252a66798e 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj @@ -76,7 +76,6 @@ - From dd7bd60b9381e0bb1f232e50e5cc7a357d158486 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Thu, 10 Apr 2025 22:38:37 +0000 Subject: [PATCH 113/174] Remove PublishTrimmed --- src/Tools/dotnet-monitor/dotnet-monitor.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Tools/dotnet-monitor/dotnet-monitor.csproj b/src/Tools/dotnet-monitor/dotnet-monitor.csproj index ee6933ead84..391f453db5a 100644 --- a/src/Tools/dotnet-monitor/dotnet-monitor.csproj +++ b/src/Tools/dotnet-monitor/dotnet-monitor.csproj @@ -15,7 +15,6 @@ false true - true false true $(InterceptorsNamespaces);Microsoft.AspNetCore.Http.Validation.Generated From 052713ce5d6b735df563f7931109bef97ecba101 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 11 Apr 2025 16:52:48 +0000 Subject: [PATCH 114/174] Fix build --- .../Microsoft.Diagnostics.Monitoring.TestCommon.csproj | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Microsoft.Diagnostics.Monitoring.TestCommon.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Microsoft.Diagnostics.Monitoring.TestCommon.csproj index b57f4c6f978..2334234588c 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Microsoft.Diagnostics.Monitoring.TestCommon.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Microsoft.Diagnostics.Monitoring.TestCommon.csproj @@ -1,4 +1,6 @@ - + + + $(TestTargetFrameworks) @@ -36,6 +38,8 @@ + + From 31a8a9fb869b70bd843677dc666b4ec0d75f311c Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 11 Apr 2025 18:13:04 +0000 Subject: [PATCH 115/174] Call AddValidation --- src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs b/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs index f04780d753d..0e02219e242 100644 --- a/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs +++ b/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation.Generated; using Microsoft.AspNetCore.Hosting; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.Auth; @@ -129,6 +130,7 @@ public static IHostBuilder CreateHostBuilder(HostBuilderSettings settings) services.AddSingleton(listenResults); services.AddSingleton(); services.AddHostedService(); + MyExtensions.AddValidation(services); }) .ConfigureKestrel((context, options) => { From c9a1288d8d8576fee75078712c7bc7634392bae5 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 11 Apr 2025 18:20:17 +0000 Subject: [PATCH 116/174] Update openapi.json --- documentation/openapi.json | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/documentation/openapi.json b/documentation/openapi.json index d93f298a835..287b1e1f4f5 100644 --- a/documentation/openapi.json +++ b/documentation/openapi.json @@ -1912,16 +1912,20 @@ "type": "object", "properties": { "exceptionType": { - "type": "string" + "type": "string", + "nullable": true }, "moduleName": { - "type": "string" + "type": "string", + "nullable": true }, "typeName": { - "type": "string" + "type": "string", + "nullable": true }, "methodName": { - "type": "string" + "type": "string", + "nullable": true } }, "additionalProperties": false @@ -2030,9 +2034,10 @@ "Warning", "Error", "Critical", - "None", - null - ] + "None" + ], + "type": "string", + "nullable": true }, "OperationError": { "type": "object", From 0a621a4bbf939f4522ceadfe8185dfc8c1ea63b9 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 11 Apr 2025 20:49:40 +0000 Subject: [PATCH 117/174] Fix DefaultDiagnosticPort_Supported_ListenModeOnNonWindows --- .../dotnet-monitor/CommonOptionsExtensions.cs | 58 ++++++++++++++++--- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs b/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs index a5ac2e51956..994f232f51a 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs @@ -99,10 +99,11 @@ private static void MapRootOptions(RootOptions obj, string prefix, string separa MapGlobalCounterOptions(obj.GlobalCounter, FormattableString.Invariant($"{prefix}{nameof(obj.GlobalCounter)}"), separator, map); // InProcessFeaturesOptions // CorsConfigurationOptions + MapDiagnosticPortOptions(obj.DiagnosticPort, FormattableString.Invariant($"{prefix}{nameof(obj.DiagnosticPort)}"), separator, map); // DiagnosticPortOptions // EgressOptions // MetricsOptions - // StorageOptions + MapStorageOptions(obj.Storage, FormattableString.Invariant($"{prefix}{nameof(obj.Storage)}"), separator, map); // ProcessFilterOptions // CollectionRuleDefaultsOptions // Templates @@ -146,14 +147,6 @@ private static void MapMonitorApiKeyOptions(MonitorApiKeyOptions? obj, string va } } - private static void MapString(string? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, value); - } - } - private static void MapAzureAdOptions(AzureAdOptions? obj, string valueName, string separator, IDictionary map) { if (null != obj) @@ -210,6 +203,45 @@ private static void MapGlobalCounterOptions(GlobalCounterOptions? obj, string va } } + private static void MapDiagnosticPortOptions(DiagnosticPortOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapDiagnosticPortConnectionMode(obj.ConnectionMode, FormattableString.Invariant($"{prefix}{nameof(obj.ConnectionMode)}"), map); + MapString(obj.EndpointName, FormattableString.Invariant($"{prefix}{nameof(obj.EndpointName)}"), map); + MapInt(obj.MaxConnections, FormattableString.Invariant($"{prefix}{nameof(obj.MaxConnections)}"), map); + MapBool(obj.DeleteEndpointOnStartup, FormattableString.Invariant($"{prefix}{nameof(obj.DeleteEndpointOnStartup)}"), map); + } + } + + private static void MapDiagnosticPortConnectionMode(DiagnosticPortConnectionMode? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + + private static void MapStorageOptions(StorageOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.DefaultSharedPath, FormattableString.Invariant($"{prefix}{nameof(obj.DefaultSharedPath)}"), map); + MapString(obj.DumpTempFolder, FormattableString.Invariant($"{prefix}{nameof(obj.DumpTempFolder)}"), map); + MapString(obj.SharedLibraryPath, FormattableString.Invariant($"{prefix}{nameof(obj.SharedLibraryPath)}"), map); + } + } + + private static void MapString(string? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + private static void MapFloat(float? value, string valueName, IDictionary map) { if (null != value) @@ -226,6 +258,14 @@ private static void MapInt(int? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + // private static void MapValue(object? value, string valueName, string separator, IDictionary map) // { // if (null != value) From 771d2f2b1fc6722d545c76d7404874aed8afb614 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 11 Apr 2025 21:17:25 +0000 Subject: [PATCH 118/174] Fix FileSystemEgressExtension_DirectoryPath_Success --- ...rosoft.Diagnostics.Monitoring.Options.csproj | 1 + .../FileSystemEgressExtensionTests.cs | 17 ++++++++++++++--- .../Program.cs | 6 ++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj b/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj index 02fc73c7735..c3fb05d3ab0 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj +++ b/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj @@ -22,6 +22,7 @@ + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/FileSystemEgressExtensionTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/FileSystemEgressExtensionTests.cs index 9a9ba33bf8b..5989905b166 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/FileSystemEgressExtensionTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/FileSystemEgressExtensionTests.cs @@ -1,12 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; +using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.Egress; using Microsoft.Diagnostics.Tools.Monitor.Egress.Configuration; using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Moq; @@ -22,8 +25,12 @@ namespace Microsoft.Diagnostics.Monitoring.Tool.UnitTests { + public class FileSystemEgressExtensionFixture : WebApplicationFactory + { + } + [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] - public sealed class FileSystemEgressExtensionTests + public sealed class FileSystemEgressExtensionTests : IClassFixture { const string ProviderName = "TestProvider"; const string ExpectedFileName = "EgressedData.txt"; @@ -35,10 +42,12 @@ public sealed class FileSystemEgressExtensionTests FileSystemEgressProviderOptions.CopyBufferSize_MaxValue.ToString()); private readonly ITestOutputHelper _outputHelper; + private readonly FileSystemEgressExtensionFixture _fixture; - public FileSystemEgressExtensionTests(ITestOutputHelper outputHelper) + public FileSystemEgressExtensionTests(ITestOutputHelper outputHelper, FileSystemEgressExtensionFixture fixture) { _outputHelper = outputHelper; + _fixture = fixture; } [Fact] @@ -145,7 +154,7 @@ public async Task FileSystemEgressExtension_IntermediateDirectoryPath_Success() Assert.False(intermediateDirInfo.EnumerateFiles().Any(), "Intermediate directory should not contain any files."); } - private static IEgressExtension CreateExtension(Action callback = null) + private IEgressExtension CreateExtension(Action callback = null) { List configProviders = new() { @@ -163,6 +172,8 @@ private static IEgressExtension CreateExtension(Action cal Mock> mockLogger = new(); Mock mockServiceProvider = new(); + mockServiceProvider.Setup(provider => provider.GetService(typeof(IOptions))) + .Returns(_fixture.Services.GetRequiredService>()); return new FileSystemEgressExtension(mockServiceProvider.Object, mockConfigurationProvider.Object, mockLogger.Object); } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs index 144268118c5..1563f3ba5ca 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs @@ -2,7 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http.Validation; +using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; +using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; var builder = WebApplication.CreateBuilder(args); builder.Services.AddValidation(); @@ -14,4 +16,8 @@ public partial class Program {} sealed class TestValidatableType { public required ExtensionManifest ExtensionManifest { get; init; } + + // public RootOptions RootOptions { get; init; } // TODO: this hits bad generated code. + // Take a more granular approach for now. + public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } } From d1f05d2b2ea6489bd9d58ce7f265c285084a936a Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 11 Apr 2025 22:51:57 +0000 Subject: [PATCH 119/174] Begin mapping collection rules Ensure generated type info is passed through for ActionListExecutor testcase --- .../ActionListExecutorTests.cs | 6 ++- .../CollectionRuleActions.UnitTests.csproj | 1 + .../TestValidatableType.cs | 22 +++++++++ .../Options/ValidationHelper.cs | 2 +- .../dotnet-monitor/CommonOptionsExtensions.cs | 45 +++++++++++++++++++ .../DataAnnotationValidateOptions.cs | 6 ++- 6 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs diff --git a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs index 417612e9baa..d0ea6f771bb 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Monitoring.TestCommon.Options; using Microsoft.Diagnostics.Tools.Monitor; @@ -128,7 +129,7 @@ public Task ActionListExecutor_FirstActionFail_DeferredCompletion() return ActionListExecutor_FirstActionFail(waitForCompletion: false); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/61379")] public Task ActionListExecutor_FirstActionFail_WaitedCompletion() { return ActionListExecutor_FirstActionFail(waitForCompletion: true); @@ -165,6 +166,9 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => Assert.Equal(string.Format(Strings.ErrorMessage_NonzeroExitCode, "1"), actionExecutionException.Message); VerifyStartCallbackCount(waitForCompletion, callbackCount); + }, services => + { + services.AddValidation(); }); } diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj b/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj index 77d43fdf25c..3913f4a24c1 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj @@ -2,6 +2,7 @@ $(ToolTargetFrameworks) + $(InterceptorsNamespaces);Microsoft.AspNetCore.Http.Validation.Generated diff --git a/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs b/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs new file mode 100644 index 00000000000..dcb5d4b49f8 --- /dev/null +++ b/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Http.Validation; +using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; + +namespace Microsoft.Diagnostics.Tools.Monitor +{ + // The Validation source generator doesn't run for libraries that don't call AddValidation, + // so we can't generate IValidatableInfo by using [ValidatableType] directly on types defined + // in ProjectReferences. This is a workaround to force the generator running in this project to + // generate IValidatableInfo for the referenced types. The containing class is not used otherwise. + [ValidatableType] + internal class TestValidatableTypes + { + public required CollectionRuleOptions CollectionRuleOptions { get; init; } + + public required ExecuteOptions ExecuteOptions { get; init; } + } +} diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs index 674ed9cf682..e47c88962d2 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs @@ -82,7 +82,7 @@ public static bool TryValidateObject(object options, Type type, ValidationOption var validateContext = new ValidateContext() { ValidationOptions = validationOptions, - ValidationContext = new(options, validationContext.MemberName, null, items: null) + ValidationContext = validationContext }; validatableTypeInfo.ValidateAsync(options, validateContext, CancellationToken.None).GetAwaiter().GetResult(); if (validateContext.ValidationErrors is Dictionary validationErrors) diff --git a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs b/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs index 994f232f51a..2a377255014 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs @@ -7,6 +7,7 @@ using Microsoft.Diagnostics.Monitoring.TestCommon; #endif using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; @@ -95,6 +96,7 @@ private static void MapRootOptions(RootOptions obj, string prefix, string separa { // TODO: in Tests, it has an additional property. Weird. MapAuthenticationOptions(obj.Authentication, FormattableString.Invariant($"{prefix}{nameof(obj.Authentication)}"), separator, map); + MapCollectionRules(obj.CollectionRules, FormattableString.Invariant($"{prefix}{nameof(obj.CollectionRules)}"), separator, map); // GlobalCounterOptions MapGlobalCounterOptions(obj.GlobalCounter, FormattableString.Invariant($"{prefix}{nameof(obj.GlobalCounter)}"), separator, map); // InProcessFeaturesOptions @@ -126,6 +128,49 @@ private static void MapRootOptions(RootOptions obj, string prefix, string separa // } // } + private static void MapCollectionRules(IDictionary? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + System.Console.WriteLine("MapCollectionRules"); + var prefix = FormattableString.Invariant($"{valueName}{separator}"); // passed to mapdictionary. + foreach ((string key, CollectionRuleOptions value) in obj) + { + string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); + System.Console.WriteLine($"key: {keyString}"); + MapCollectionRuleOptions(value, FormattableString.Invariant($"{prefix}{keyString}"), separator, map); + } + } + } + + private static void MapCollectionRuleOptions(CollectionRuleOptions obj, string valueName, string separator, IDictionary map) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + // MapFilters(obj.Filters, FormattableString.Invariant($"{prefix}{nameof(obj.Filters)}"), separator, map); + // MapTrigger(obj.Trigger, FormattableString.Invariant($"{prefix}{nameof(obj.Trigger)}"), separator, map); + MapActions(obj.Actions, FormattableString.Invariant($"{prefix}{nameof(obj.Actions)}"), separator, map); + // MapLimits(obj.Limits, FormattableString.Invariant($"{prefix}{nameof(obj.Limits)}"), separator, map); + } + + private static void MapActions(List obj, string valueName, string separator, IDictionary map) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + for (int index = 0; index < obj.Count; index++) + { + CollectionRuleActionOptions value = obj[index]; + MapCollectionRuleActionOptions(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); + } + } + + private static void MapCollectionRuleActionOptions(CollectionRuleActionOptions obj, string valueName, string separator, IDictionary map) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Name, FormattableString.Invariant($"{prefix}{nameof(obj.Name)}"), map); + MapString(obj.Type, FormattableString.Invariant($"{prefix}{nameof(obj.Type)}"), map); + // TODO: map object Settings + MapBool(obj.WaitForCompletion, FormattableString.Invariant($"{prefix}{nameof(obj.WaitForCompletion)}"), map); + } + private static void MapAuthenticationOptions(AuthenticationOptions? obj, string valueName, string separator, IDictionary map) { if (null != obj) diff --git a/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs b/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs index 767299b0d72..bc144fff731 100644 --- a/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs +++ b/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs @@ -35,7 +35,11 @@ public DataAnnotationValidateOptions(IServiceProvider serviceProvider) public ValidateOptionsResult Validate(string? name, TOptions options) { var results = new List(); - if (!ValidationHelper.TryValidateObject(options, typeof(TOptions), _validationOptions, results)) + var typeName = typeof(TOptions).Name; + var validationContext = new ValidationContext(options, typeName, _serviceProvider, items: null) { + MemberName = typeName + }; + if (!ValidationHelper.TryValidateObject(options, typeof(TOptions), _validationOptions, validationContext, results)) { IList failures = new List(); foreach (ValidationResult result in results) From 2a3d8c3a6baca89ced1cb3649b927b99095ea169 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 11 Apr 2025 23:26:54 +0000 Subject: [PATCH 120/174] Fix build warnings --- .../CollectionRuleActions.UnitTests/ActionListExecutorTests.cs | 1 - .../CollectionRuleActions.UnitTests/TestValidatableType.cs | 3 +-- .../Program.cs | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs index d0ea6f771bb..04f447fb0e7 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Monitoring.TestCommon.Options; using Microsoft.Diagnostics.Tools.Monitor; diff --git a/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs b/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs index dcb5d4b49f8..782517c93d7 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http.Validation; -using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; @@ -13,7 +12,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor // in ProjectReferences. This is a workaround to force the generator running in this project to // generate IValidatableInfo for the referenced types. The containing class is not used otherwise. [ValidatableType] - internal class TestValidatableTypes + internal sealed class TestValidatableTypes { public required CollectionRuleOptions CollectionRuleOptions { get; init; } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs index 1563f3ba5ca..9cb1b960386 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http.Validation; -using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; From 7126ed725612a1f3391f78eacdb86c6685b1dcca Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 14 Apr 2025 18:10:41 +0000 Subject: [PATCH 121/174] Fix validation behavior for CollectionRuleActionOptions The generator expects IValidatableObject results to have a MemberName. --- .../ActionListExecutorTests.cs | 12 ++++++++--- .../CollectionRuleActions.UnitTests.csproj | 20 ++++++++++++++++++- .../CollectionRuleActionOptions.Validate.cs | 4 ++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs index 04f447fb0e7..6a922ee493a 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs @@ -76,7 +76,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] public Task ActionListExecutor_SecondActionFail_DeferredCompletion() { return ActionListExecutor_SecondActionFail(waitForCompletion: false); @@ -165,9 +165,9 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => Assert.Equal(string.Format(Strings.ErrorMessage_NonzeroExitCode, "1"), actionExecutionException.Message); VerifyStartCallbackCount(waitForCompletion, callbackCount); - }, services => + }, serviceCollection => { - services.AddValidation(); + AddValidation(serviceCollection); }); } @@ -190,9 +190,15 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(nameof(PassThroughAction)); + AddValidation(serviceCollection); }); } + static void AddValidation(IServiceCollection serviceCollection) + { + serviceCollection.AddValidation(); + } + private static void VerifyStartCallbackCount(bool waitForCompletion, int callbackCount) { //Currently, any attempt to wait on completion will automatically trigger the start callback. diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj b/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj index 3913f4a24c1..fbb9be45a45 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj @@ -1,4 +1,6 @@ - + + + $(ToolTargetFrameworks) @@ -16,4 +18,20 @@ + + + + + + + + diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.Validate.cs index 45d41c6977a..904c8ff6366 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.Validate.cs @@ -18,6 +18,10 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali if (!string.IsNullOrEmpty(Type)) { + validationContext = new ValidationContext(this, displayName: Type, validationContext, items: null) + { + MemberName = nameof(Settings) + }; actionOperations.TryValidateOptions(Type, Settings, validationContext, results); } From 03287fbbd6016b78d4752c74c2a1270ba44aab0f Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 14 Apr 2025 18:34:37 +0000 Subject: [PATCH 122/174] Fix build --- .../ActionListExecutorTests.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs index 6a922ee493a..a9f6d69eab7 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs @@ -165,10 +165,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => Assert.Equal(string.Format(Strings.ErrorMessage_NonzeroExitCode, "1"), actionExecutionException.Message); VerifyStartCallbackCount(waitForCompletion, callbackCount); - }, serviceCollection => - { - AddValidation(serviceCollection); - }); + }, AddValidation); } From e647e875157e0817c8660e62f23a7bceeb1c2358 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 15 Apr 2025 00:05:04 +0000 Subject: [PATCH 123/174] More test fixes - Wire up generated type info to more tests - Skip some test due to record bug - Check in generated source and fix up IDictionary type info - Pass IServiceProvider through ValidationContext - Set MemberNames on ValidationResult - Map more options --- .../AuthenticationOptions.Validate.cs | 2 +- .../ActionListExecutorTests.cs | 18 +- .../CollectDumpActionTests.cs | 3 +- .../CollectTraceActionTests.cs | 6 +- .../CollectionRuleActions.UnitTests.csproj | 10 + .../EnvironmentVariableActionTests.cs | 12 +- .../ExecuteActionTests.cs | 29 +- .../TestValidatableType.cs | 16 + .../ValidatableInfoResolver.cs | 1056 +++++++++++++++++ .../ExtensionManifestTests.cs | 14 +- .../Program.cs | 3 + .../Auth/ApiKey/MonitorApiKeyPostConfigure.cs | 2 +- .../Auth/AuthConfiguratorFactory.cs | 13 +- .../Actions/CollectDumpAction.cs | 2 +- .../Actions/CollectExceptionsAction.cs | 6 +- .../Actions/CollectGCDumpAction.cs | 2 +- .../Actions/CollectLiveMetricsAction.cs | 2 +- .../Actions/CollectLogsAction.cs | 2 +- .../Actions/CollectStacksAction.cs | 2 +- .../Actions/CollectTraceAction.cs | 2 +- .../Actions/CollectionRuleActionOperations.cs | 2 +- .../CollectionRules/Actions/ExecuteAction.cs | 6 +- .../Actions/GetEnvironmentVariableAction.cs | 2 +- .../Actions/LoadProfilerAction.cs | 2 +- .../Actions/SetEnvironmentVariableAction.cs | 2 +- .../CollectExceptionsOptions.Validate.cs | 2 +- .../Actions/CollectStacksOptions.Validate.cs | 2 +- .../Actions/CollectTraceOptions.Validate.cs | 8 +- .../Options/Actions/RequiredGuidAttribute.cs | 8 +- .../ValidateEgressProviderAttribute.cs | 8 +- .../Triggers/EventCounterOptions.Validate.cs | 4 +- .../IEventCounterShortcuts.Validate.cs | 2 +- .../Triggers/EventMeterOptions.Validate.cs | 4 +- .../Options/ValidationHelper.cs | 10 +- .../CollectionRuleTriggerOperations.cs | 2 +- .../Commands/CollectCommandHandler.cs | 3 +- .../dotnet-monitor/CommonOptionsExtensions.cs | 246 +++- .../Egress/Extension/EgressExtension.cs | 8 +- .../Extension/EgressExtensionFactory.cs | 8 +- .../Extensibility/ExtensionManifest.cs | 5 +- 40 files changed, 1441 insertions(+), 95 deletions(-) create mode 100644 src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.Validate.cs b/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.Validate.cs index d684f739526..6b11722b7a1 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.Validate.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.Validate.cs @@ -20,7 +20,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali results.Add( new ValidationResult( string.Format( - OptionsDisplayStrings.ErrorMessage_MultipleAuthenticationModesSpecified))); + OptionsDisplayStrings.ErrorMessage_MultipleAuthenticationModesSpecified), [nameof(MonitorApiKey), nameof(AzureAd)])); } return results; diff --git a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs index a9f6d69eab7..66b5d26a9dd 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs @@ -46,7 +46,7 @@ public ActionListExecutorTests(ITestOutputHelper outputHelper) _outputHelper = outputHelper; } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] public async Task ActionListExecutor_AllActionsSucceed() { await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => @@ -73,7 +73,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => await executor.ExecuteActions(context, startCallback, cancellationTokenSource.Token); VerifyStartCallbackCount(waitForCompletion: false, callbackCount); - }); + }, TestValidatableTypes.AddValidation); } [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] @@ -119,10 +119,10 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => Assert.Equal(string.Format(Strings.ErrorMessage_NonzeroExitCode, "1"), actionExecutionException.Message); VerifyStartCallbackCount(waitForCompletion, callbackCount); - }); + }, TestValidatableTypes.AddValidation); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/61379")] public Task ActionListExecutor_FirstActionFail_DeferredCompletion() { return ActionListExecutor_FirstActionFail(waitForCompletion: false); @@ -165,7 +165,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => Assert.Equal(string.Format(Strings.ErrorMessage_NonzeroExitCode, "1"), actionExecutionException.Message); VerifyStartCallbackCount(waitForCompletion, callbackCount); - }, AddValidation); + }, TestValidatableTypes.AddValidation); } @@ -187,15 +187,9 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(nameof(PassThroughAction)); - AddValidation(serviceCollection); + TestValidatableTypes.AddValidation(serviceCollection); }); } - - static void AddValidation(IServiceCollection serviceCollection) - { - serviceCollection.AddValidation(); - } - private static void VerifyStartCallbackCount(bool waitForCompletion, int callbackCount) { //Currently, any attempt to wait on completion will automatically trigger the start callback. diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs index be96a7eb410..bac44584bdd 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs @@ -6,6 +6,7 @@ using Microsoft.Diagnostics.Monitoring.TestCommon.Runners; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; @@ -101,7 +102,7 @@ await runner.ExecuteAsync(async () => await runner.SendCommandAsync(TestAppScenarios.AsyncWait.Commands.Continue); }); - }); + }, TestValidatableTypes.AddValidation); } } } diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs index 7f27357ca24..82718eaaa7c 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs @@ -6,6 +6,7 @@ using Microsoft.Diagnostics.Monitoring.TestCommon.Runners; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; @@ -55,7 +56,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, async host => { await PerformTrace(host, tfm); - }); + }, TestValidatableTypes.AddValidation); } [Theory] @@ -99,7 +100,8 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => options.Duration = TimeSpan.FromSeconds(2); }) .SetStartupTrigger(); - }, host => PerformTrace(host, TargetFrameworkMoniker.Current, artifactName)); + }, host => PerformTrace(host, TargetFrameworkMoniker.Current, artifactName), + TestValidatableTypes.AddValidation); } private async Task PerformTrace(IHost host, TargetFrameworkMoniker tfm, string artifactName = null) diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj b/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj index fbb9be45a45..e5d269750f7 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj @@ -5,10 +5,12 @@ $(ToolTargetFrameworks) $(InterceptorsNamespaces);Microsoft.AspNetCore.Http.Validation.Generated + true + @@ -16,6 +18,7 @@ + @@ -34,4 +37,11 @@ + + + + + + + diff --git a/src/Tests/CollectionRuleActions.UnitTests/EnvironmentVariableActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/EnvironmentVariableActionTests.cs index 4152d6724e9..e358b2fa962 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/EnvironmentVariableActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/EnvironmentVariableActionTests.cs @@ -41,7 +41,7 @@ public EnvironmentVariableActionTests(ITestOutputHelper outputHelper) /// /// The required APIs only exist on .NET 6.0+ /// - [Theory] + [Theory(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] [MemberData(nameof(ActionTestsHelper.GetTfms), MemberType = typeof(ActionTestsHelper))] public async Task TestSetEnvVar(TargetFrameworkMoniker tfm) { @@ -79,7 +79,7 @@ await runner.ExecuteAsync(async () => await runner.SendCommandAsync(TestAppScenarios.EnvironmentVariables.Commands.ShutdownScenario); }); - }); + }, TestValidatableTypes.AddValidation); } /// @@ -88,7 +88,7 @@ await runner.ExecuteAsync(async () => /// /// The required APIs only exist on .NET 6.0+ /// - [Theory] + [Theory(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] [MemberData(nameof(ActionTestsHelper.GetTfms), MemberType = typeof(ActionTestsHelper))] public async Task TestGetEnvVar(TargetFrameworkMoniker tfm) { @@ -145,7 +145,7 @@ await runner.ExecuteAsync(async () => await runner.SendCommandAsync(TestAppScenarios.EnvironmentVariables.Commands.ShutdownScenario); }); - }); + }, TestValidatableTypes.AddValidation); } /// @@ -155,7 +155,7 @@ await runner.ExecuteAsync(async () => /// /// The required APIs only exist on .NET 6.0+ /// - [Theory] + [Theory(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] [MemberData(nameof(ActionTestsHelper.GetTfms), MemberType = typeof(ActionTestsHelper))] public async Task TestEnvVarRoundTrip(TargetFrameworkMoniker tfm) { @@ -199,7 +199,7 @@ await runner.ExecuteAsync(async () => Assert.True(getResult.OutputValues.TryGetValue(CollectionRuleActionConstants.EnvironmentVariableValueName, out string value)); Assert.Equal(DefaultVarValue, value); }); - }); + }, TestValidatableTypes.AddValidation); } } } diff --git a/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs index 7c9e032324c..db76a4ebb4e 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs @@ -2,11 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http.Validation; +using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Exceptions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; using System.Globalization; @@ -20,20 +22,26 @@ namespace CollectionRuleActions.UnitTests { + public class ExecuteActionFixture : WebApplicationFactory + { + } + [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] [Collection(TestCollections.CollectionRuleActions)] - public sealed class ExecuteActionTests + public sealed class ExecuteActionTests : IClassFixture { private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30); private readonly ITestOutputHelper _outputHelper; + private readonly ExecuteActionFixture _fixture; - public ExecuteActionTests(ITestOutputHelper outputHelper) + public ExecuteActionTests(ITestOutputHelper outputHelper, ExecuteActionFixture fixture) { _outputHelper = outputHelper; + _fixture = fixture; } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] public async Task ExecuteAction_ZeroExitCode() { await ValidateAction( @@ -52,7 +60,7 @@ await ValidateAction( }); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] public async Task ExecuteAction_NonzeroExitCode() { await ValidateAction( @@ -72,7 +80,7 @@ await ValidateAction( }); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] public async Task ExecuteAction_TokenCancellation() { // This timeout is much shorter than the default test timeout. @@ -99,7 +107,7 @@ await Assert.ThrowsAsync( }); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] public async Task ExecuteAction_TextFileOutput() { using TemporaryDirectory outputDirectory = new(_outputHelper); @@ -126,7 +134,7 @@ await ValidateAction( Assert.Equal(testMessage, File.ReadAllText(textFileOutputPath)); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] public async Task ExecuteAction_InvalidPath() { string uniquePathName = Guid.NewGuid().ToString(); @@ -146,7 +154,7 @@ await ValidateAction( }); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] public async Task ExecuteAction_IgnoreExitCode() { await ValidateAction( @@ -175,9 +183,10 @@ private static void ValidateActionResult(CollectionRuleActionResult result, stri Assert.Equal(expectedExitCode, actualExitCode); } - private static async Task ValidateAction(Action optionsCallback, Func actionCallback) + private async Task ValidateAction(Action optionsCallback, Func actionCallback) { - ExecuteActionFactory factory = new(Options.Create(new())); + var validationOptions = _fixture.Services.GetService>(); + ExecuteActionFactory factory = new(_fixture.Services, validationOptions); ExecuteOptions options = new(); diff --git a/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs b/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs index 782517c93d7..acab632a55c 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs @@ -2,8 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http.Validation; +using Microsoft.AspNetCore.Http.Validation.Generated; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Monitoring.WebApi; namespace Microsoft.Diagnostics.Tools.Monitor { @@ -17,5 +20,18 @@ internal sealed class TestValidatableTypes public required CollectionRuleOptions CollectionRuleOptions { get; init; } public required ExecuteOptions ExecuteOptions { get; init; } + + public required SetEnvironmentVariableOptions SetEnvironmentVariableOptions { get; init; } + + public required GetEnvironmentVariableOptions GetEnvironmentVariableOptions { get; init; } + + public required CollectTraceOptions CollectTraceOptions { get; init; } + + public required GlobalCounterOptions GlobalCounterOptions { get; init; } + + public static void AddValidation(IServiceCollection services) + { + GeneratedServiceCollectionExtensions.AddValidation(services); + } } } diff --git a/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs b/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs new file mode 100644 index 00000000000..8aecf128e05 --- /dev/null +++ b/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs @@ -0,0 +1,1056 @@ +#nullable enable annotations +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ +#nullable enable + +namespace System.Runtime.CompilerServices +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : System.Attribute + { + public InterceptsLocationAttribute(int version, string data) + { + } + } +} + +namespace Microsoft.AspNetCore.Http.Validation.Generated +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file sealed class GeneratedValidatablePropertyInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatablePropertyInfo + { + public GeneratedValidatablePropertyInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] + global::System.Type containingType, + global::System.Type propertyType, + string name, + string displayName) : base(containingType, propertyType, name, displayName) + { + ContainingType = containingType; + Name = name; + } + + internal global::System.Type ContainingType { get; } + internal string Name { get; } + + protected override global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes() + => ValidationAttributeCache.GetValidationAttributes(ContainingType, Name); + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file sealed class GeneratedValidatableTypeInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatableTypeInfo + { + public GeneratedValidatableTypeInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.Interfaces)] + global::System.Type type, + ValidatablePropertyInfo[] members) : base(type, members) { } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file class GeneratedValidatableInfoResolver : global::Microsoft.AspNetCore.Http.Validation.IValidatableInfoResolver + { + public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) + { + validatableInfo = null; + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions)) + { + validatableInfo = CreateCollectionRuleTriggerOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions)) + { + validatableInfo = CreateCollectionRuleActionOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions)) + { + validatableInfo = CreateCollectionRuleLimitsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions)) + { + validatableInfo = CreateCollectionRuleOptions(); + return true; + } + if (type == typeof(global::System.Reflection.MethodBase)) + { + validatableInfo = CreateMethodBase(); + return true; + } + if (type == typeof(global::System.Reflection.ConstructorInfo)) + { + validatableInfo = CreateConstructorInfo(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeTypedArgument)) + { + validatableInfo = CreateCustomAttributeTypedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeNamedArgument)) + { + validatableInfo = CreateCustomAttributeNamedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeData)) + { + validatableInfo = CreateCustomAttributeData(); + return true; + } + if (type == typeof(global::System.Reflection.ParameterInfo)) + { + validatableInfo = CreateParameterInfo(); + return true; + } + if (type == typeof(global::System.Reflection.MethodInfo)) + { + validatableInfo = CreateMethodInfo(); + return true; + } + if (type == typeof(global::System.Reflection.EventInfo)) + { + validatableInfo = CreateEventInfo(); + return true; + } + if (type == typeof(global::System.Reflection.FieldInfo)) + { + validatableInfo = CreateFieldInfo(); + return true; + } + if (type == typeof(global::System.Reflection.PropertyInfo)) + { + validatableInfo = CreatePropertyInfo(); + return true; + } + if (type == typeof(global::System.Reflection.TypeInfo)) + { + validatableInfo = CreateTypeInfo(); + return true; + } + if (type == typeof(global::System.Reflection.Assembly)) + { + validatableInfo = CreateAssembly(); + return true; + } + if (type == typeof(global::System.Guid)) + { + validatableInfo = CreateGuid(); + return true; + } + if (type == typeof(global::System.Reflection.Module)) + { + validatableInfo = CreateModule(); + return true; + } + if (type == typeof(global::System.Reflection.MemberInfo)) + { + validatableInfo = CreateMemberInfo(); + return true; + } + if (type == typeof(global::System.Type)) + { + validatableInfo = CreateType(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions)) + { + validatableInfo = CreateBaseRecordOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions)) + { + validatableInfo = CreateExecuteOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions)) + { + validatableInfo = CreateSetEnvironmentVariableOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions)) + { + validatableInfo = CreateGetEnvironmentVariableOptions(); + return true; + } + if (type == typeof(global::System.Collections.Generic.IDictionary)) + { + validatableInfo = CreateIDictionary_2(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter)) + { + validatableInfo = CreateTraceEventFilter(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions)) + { + validatableInfo = CreateCollectTraceOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions)) + { + validatableInfo = CreateGlobalCounterOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes)) + { + validatableInfo = CreateTestValidatableTypes(); + return true; + } + + return false; + } + + // No-ops, rely on runtime code for ParameterInfo-based resolution + public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterInfo parameterInfo, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) + { + validatableInfo = null; + return false; + } + + private ValidatableTypeInfo CreateCollectionRuleTriggerOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + propertyType: typeof(string), + name: "Type", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleActionOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), + propertyType: typeof(string), + name: "Type", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleLimitsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(int?), + name: "ActionCount", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "ActionCountSlidingWindowDuration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RuleDuration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + name: "Trigger", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Actions", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + name: "Limits", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateMethodBase() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodBase), + members: [] + ); + } + private ValidatableTypeInfo CreateConstructorInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ConstructorInfo), + members: [] + ); + } + private ValidatableTypeInfo CreateCustomAttributeTypedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeTypedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + propertyType: typeof(global::System.Type), + name: "ArgumentType", + displayName: "ArgumentType" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeNamedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeNamedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "MemberInfo", + displayName: "MemberInfo" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + name: "TypedValue", + displayName: "TypedValue" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeData() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeData), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Type), + name: "AttributeType", + displayName: "AttributeType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "Constructor", + displayName: "Constructor" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "ConstructorArguments", + displayName: "ConstructorArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "NamedArguments", + displayName: "NamedArguments" + ), + ] + ); + } + private ValidatableTypeInfo CreateParameterInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ParameterInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "Member", + displayName: "Member" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Type), + name: "ParameterType", + displayName: "ParameterType" + ), + ] + ); + } + private ValidatableTypeInfo CreateMethodInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.ParameterInfo), + name: "ReturnParameter", + displayName: "ReturnParameter" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Type), + name: "ReturnType", + displayName: "ReturnType" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.EventInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "AddMethod", + displayName: "AddMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Type), + name: "EventHandlerType", + displayName: "EventHandlerType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RaiseMethod", + displayName: "RaiseMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RemoveMethod", + displayName: "RemoveMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateFieldInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.FieldInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Type), + name: "FieldType", + displayName: "FieldType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + ] + ); + } + private ValidatableTypeInfo CreatePropertyInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.PropertyInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "GetMethod", + displayName: "GetMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Type), + name: "PropertyType", + displayName: "PropertyType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "SetMethod", + displayName: "SetMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateTypeInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.TypeInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredConstructors", + displayName: "DeclaredConstructors" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredEvents", + displayName: "DeclaredEvents" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredFields", + displayName: "DeclaredFields" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMembers", + displayName: "DeclaredMembers" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMethods", + displayName: "DeclaredMethods" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredNestedTypes", + displayName: "DeclaredNestedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredProperties", + displayName: "DeclaredProperties" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ImplementedInterfaces", + displayName: "ImplementedInterfaces" + ), + ] + ); + } + private ValidatableTypeInfo CreateAssembly() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Assembly), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DefinedTypes", + displayName: "DefinedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "EntryPoint", + displayName: "EntryPoint" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ExportedTypes", + displayName: "ExportedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.Module), + name: "ManifestModule", + displayName: "ManifestModule" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "Modules", + displayName: "Modules" + ), + ] + ); + } + private ValidatableTypeInfo CreateGuid() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Guid), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Guid), + propertyType: typeof(global::System.Guid), + name: "AllBitsSet", + displayName: "AllBitsSet" + ), + ] + ); + } + private ValidatableTypeInfo CreateModule() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Module), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Guid), + name: "ModuleVersionId", + displayName: "ModuleVersionId" + ), + ] + ); + } + private ValidatableTypeInfo CreateMemberInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MemberInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + ] + ); + } + private ValidatableTypeInfo CreateType() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Type), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "BaseType", + displayName: "BaseType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MethodBase), + name: "DeclaringMethod", + displayName: "DeclaringMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type[]), + name: "GenericTypeArguments", + displayName: "GenericTypeArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Guid), + name: "GUID", + displayName: "GUID" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "TypeInitializer", + displayName: "TypeInitializer" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "UnderlyingSystemType", + displayName: "UnderlyingSystemType" + ), + ] + ); + } + private ValidatableTypeInfo CreateBaseRecordOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + ] + ); + } + private ValidatableTypeInfo CreateExecuteOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + propertyType: typeof(global::System.Type), + name: "EqualityContract", + displayName: "EqualityContract" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + propertyType: typeof(string), + name: "Path", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + propertyType: typeof(global::System.Type), + name: "EqualityContract", + displayName: "EqualityContract" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + propertyType: typeof(string), + name: "Name", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + propertyType: typeof(global::System.Type), + name: "EqualityContract", + displayName: "EqualityContract" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + propertyType: typeof(string), + name: "Name", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateIDictionary_2() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Collections.Generic.IDictionary), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Collections.Generic.IDictionary), + propertyType: typeof(global::System.Collections.Generic.ICollection), + name: "Values", + displayName: "Values" + ), + ] + ); + } + private ValidatableTypeInfo CreateTraceEventFilter() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(global::System.Type), + name: "EqualityContract", + displayName: "EqualityContract" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(string), + name: "ProviderName", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(string), + name: "EventName", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "PayloadFilter", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectTraceOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.TraceProfile?), + name: "Profile", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(int?), + name: "BufferSizeMegabytes", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + name: "StoppingEvent", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateGlobalCounterOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(float?), + name: "IntervalSeconds", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(int?), + name: "MaxHistograms", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(int?), + name: "MaxTimeSeries", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Providers", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateTestValidatableTypes() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + name: "CollectionRuleOptions", + displayName: "CollectionRuleOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + name: "ExecuteOptions", + displayName: "ExecuteOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + name: "SetEnvironmentVariableOptions", + displayName: "SetEnvironmentVariableOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + name: "GetEnvironmentVariableOptions", + displayName: "GetEnvironmentVariableOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + name: "CollectTraceOptions", + displayName: "CollectTraceOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + name: "GlobalCounterOptions", + displayName: "GlobalCounterOptions" + ), + ] + ); + } + + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + internal static class GeneratedServiceCollectionExtensions + { + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "dimYgDF+jHmuFD/Mz8NJRdrOAABWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + { + // Use non-extension method to avoid infinite recursion. + return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => + { + options.Resolvers.Insert(0, new GeneratedValidatableInfoResolver()); + if (configureOptions is not null) + { + configureOptions(options); + } + }); + } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file static class ValidationAttributeCache + { + private sealed record CacheKey(global::System.Type ContainingType, string PropertyName); + private static readonly global::System.Collections.Concurrent.ConcurrentDictionary _cache = new(); + + public static global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes( + global::System.Type containingType, + string propertyName) + { + var key = new CacheKey(containingType, propertyName); + return _cache.GetOrAdd(key, static k => + { + var property = k.ContainingType.GetProperty(k.PropertyName); + if (property == null) + { + return []; + } + + return [.. global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(property, inherit: true)]; + }); + } + } +} \ No newline at end of file diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs index 7997a5942a1..7f0c2d60ce0 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs @@ -102,7 +102,7 @@ public void ExtensionManifest_EmptyObject_ThrowOnValidate() Assert.Null(manifest.ExecutableFileName); var validationOptions = _fixture.Services.GetRequiredService>().Value; - ExtensionException ex = Assert.Throws(() => manifest.Validate(validationOptions)); + ExtensionException ex = Assert.Throws(() => manifest.Validate(_fixture.Services, validationOptions)); Assert.Null(ex.InnerException); } @@ -126,7 +126,7 @@ public void ExtensionManifest_NameOnly_ThrowOnValidate() Assert.Null(manifest.ExecutableFileName); var validationOptions = _fixture.Services.GetRequiredService>().Value; - ExtensionException ex = Assert.Throws(() => manifest.Validate(validationOptions)); + ExtensionException ex = Assert.Throws(() => manifest.Validate(_fixture.Services, validationOptions)); Assert.Null(ex.InnerException); } @@ -152,7 +152,8 @@ public void ExtensionManifest_ExecutableAndAssembly_ThrowOnValidate() Assert.Equal(ExpectedAssemblyName, manifest.AssemblyFileName); Assert.Equal(ExpectedExecutableName, manifest.ExecutableFileName); - ExtensionException ex = Assert.Throws(() => manifest.Validate(new ValidationOptions())); + var validationOptions = _fixture.Services.GetRequiredService>().Value; + ExtensionException ex = Assert.Throws(() => manifest.Validate(_fixture.Services, validationOptions)); Assert.Null(ex.InnerException); } @@ -177,7 +178,9 @@ public void ExtensionManifest_NameAndAssembly_Valid() Assert.Equal(ExpectedAssemblyName, manifest.AssemblyFileName); Assert.Null(manifest.ExecutableFileName); - manifest.Validate(new ValidationOptions()); + + var validationOptions = _fixture.Services.GetRequiredService>().Value; + manifest.Validate(_fixture.Services, validationOptions); } [Fact] @@ -201,7 +204,8 @@ public void ExtensionManifest_NameAndExecutable_Valid() Assert.Null(manifest.AssemblyFileName); Assert.Equal(ExpectedExecutableName, manifest.ExecutableFileName); - manifest.Validate(new ValidationOptions()); + var validationOptions = _fixture.Services.GetRequiredService>().Value; + manifest.Validate(_fixture.Services, validationOptions); } private static Stream CreateManifestStream(TemporaryDirectory dir, out string path) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs index 9cb1b960386..4ff488c8d8a 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http.Validation; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; @@ -19,4 +20,6 @@ sealed class TestValidatableType // public RootOptions RootOptions { get; init; } // TODO: this hits bad generated code. // Take a more granular approach for now. public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } + + public required ExecuteOptions ExecuteOptions { get; init; } } diff --git a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs index 40bea50bedd..f3b3daf0846 100644 --- a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs +++ b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs @@ -58,7 +58,7 @@ public void PostConfigure(string? name, MonitorApiKeyConfiguration options) // Some options are configured (but may not be valid) options.Configured = true; - ValidationHelper.TryValidateObject(sourceOptions, typeof(MonitorApiKeyOptions), _validationOptions, errors); + ValidationHelper.TryValidateObject(sourceOptions, typeof(MonitorApiKeyOptions), _validationOptions, _serviceProvider, errors); string? jwkJson = null; try diff --git a/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs b/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs index 5c6d42dd155..c2fb4aa8be5 100644 --- a/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs +++ b/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs @@ -6,6 +6,8 @@ using Microsoft.Diagnostics.Tools.Monitor.Auth.AzureAd; using Microsoft.Diagnostics.Tools.Monitor.Auth.NoAuth; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Extensions.Hosting; using System; @@ -23,7 +25,7 @@ internal enum StartupAuthenticationMode internal static class AuthConfiguratorFactory { - public static IAuthenticationConfigurator Create(StartupAuthenticationMode startupAuthMode, HostBuilderContext context, ValidationOptions validationOptions) + public static IAuthenticationConfigurator Create(StartupAuthenticationMode startupAuthMode, HostBuilderContext context, IServiceProvider services) { switch (startupAuthMode) { @@ -48,12 +50,12 @@ public static IAuthenticationConfigurator Create(StartupAuthenticationMode start if (authConfigSection.Exists()) { authConfigSection.Bind(authOptions); - ValidateAuthConfigSection(authOptions, authConfigSection.Path, validationOptions); + ValidateAuthConfigSection(authOptions, authConfigSection.Path, services); } if (authOptions.AzureAd != null) { - ValidateAuthConfigSection(authOptions.AzureAd, ConfigurationPath.Combine(authConfigSection.Path, ConfigurationKeys.AzureAd), validationOptions); + ValidateAuthConfigSection(authOptions.AzureAd, ConfigurationPath.Combine(authConfigSection.Path, ConfigurationKeys.AzureAd), services); return new AzureAdAuthConfigurator(authOptions.AzureAd); } @@ -64,10 +66,11 @@ public static IAuthenticationConfigurator Create(StartupAuthenticationMode start } } - private static void ValidateAuthConfigSection(T options, string configurationPath, ValidationOptions validationOptions) where T : notnull + private static void ValidateAuthConfigSection(T options, string configurationPath, IServiceProvider services) where T : notnull { + var validationOptions = services.GetRequiredService>().Value; List results = new(); - if (!ValidationHelper.TryValidateObject(options, typeof(T), validationOptions, results)) + if (!ValidationHelper.TryValidateObject(options, typeof(T), validationOptions, services, results)) { throw new DeferredAuthenticationValidationException(configurationPath, results); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs index 0d081788d51..c1cd7153188 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs @@ -32,7 +32,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectDumpOptions throw new ArgumentNullException(nameof(options)); } - ValidationHelper.ValidateObject(options, typeof(CollectDumpOptions), _validationOptions); + ValidationHelper.ValidateObject(options, typeof(CollectDumpOptions), _validationOptions, _serviceProvider); return new CollectDumpAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs index afa64f21355..533cf331b79 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs @@ -16,10 +16,12 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions { internal sealed class CollectExceptionsActionFactory : ICollectionRuleActionFactory { + private readonly IServiceProvider _serviceProvider; private readonly ValidationOptions _validationOptions; - public CollectExceptionsActionFactory(IOptions validationOptions) + public CollectExceptionsActionFactory(IServiceProvider serviceProvider, IOptions validationOptions) { + _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); _validationOptions = validationOptions?.Value ?? throw new ArgumentNullException(nameof(validationOptions)); } @@ -31,7 +33,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectExceptionsO } List result = new(); - if (!ValidationHelper.TryValidateObject(options, typeof(CollectExceptionsOptions), _validationOptions, result)) + if (!ValidationHelper.TryValidateObject(options, typeof(CollectExceptionsOptions), _validationOptions, _serviceProvider, result)) { throw new ValidationException( string.Join(Environment.NewLine, result.ConvertAll(r => r.ErrorMessage))); diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs index a3634b2f4df..eae7966d96c 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs @@ -30,7 +30,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectGCDumpOptio { throw new ArgumentNullException(nameof(options)); } - ValidationHelper.ValidateObject(options, typeof(CollectGCDumpOptions), _validationOptions); + ValidationHelper.ValidateObject(options, typeof(CollectGCDumpOptions), _validationOptions, _serviceProvider); return new CollectGCDumpAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs index 303a272a798..a0c83b216f2 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs @@ -33,7 +33,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectLiveMetrics throw new ArgumentNullException(nameof(options)); } - ValidationHelper.ValidateObject(options, typeof(CollectLiveMetricsOptions), _validationOptions); + ValidationHelper.ValidateObject(options, typeof(CollectLiveMetricsOptions), _validationOptions, _serviceProvider); return new CollectLiveMetricsAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs index 11b0886e116..6a01b6abf97 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs @@ -35,7 +35,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectLogsOptions throw new ArgumentNullException(nameof(options)); } - ValidationHelper.ValidateObject(options, typeof(CollectLogsOptions), _validationOptions); + ValidationHelper.ValidateObject(options, typeof(CollectLogsOptions), _validationOptions, _serviceProvider); return new CollectLogsAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs index 40494d8aca3..dffc91a6842 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs @@ -30,7 +30,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectStacksOptio throw new ArgumentNullException(nameof(options)); } - ValidationHelper.ValidateObject(options, typeof(CollectStacksOptions), _validationOptions); + ValidationHelper.ValidateObject(options, typeof(CollectStacksOptions), _validationOptions, _serviceProvider); return new CollectStacksAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs index 5687186b6c2..7aeb507e24c 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs @@ -27,7 +27,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectTraceOption throw new ArgumentNullException(nameof(options)); } - ValidationHelper.ValidateObject(options, typeof(CollectTraceOptions), _validationOptions); + ValidationHelper.ValidateObject(options, typeof(CollectTraceOptions), _validationOptions, _serviceProvider); return new CollectTraceAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs index ec5bf0a508f..b6539fd1fd5 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs @@ -73,7 +73,7 @@ public bool TryValidateOptions( } else { - results.Add(new ValidationResult(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownActionType, actionName))); + results.Add(new ValidationResult(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownActionType, actionName), [actionName])); return false; } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs index a363d539254..3d683bc95c9 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs @@ -20,10 +20,12 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions internal sealed class ExecuteActionFactory : ICollectionRuleActionFactory { + private readonly IServiceProvider _serviceProvider; private readonly ValidationOptions _validationOptions; - public ExecuteActionFactory(IOptions validationOptions) + public ExecuteActionFactory(IServiceProvider serviceProvider, IOptions validationOptions) { + _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); _validationOptions = validationOptions?.Value ?? throw new ArgumentNullException(nameof(validationOptions)); } @@ -34,7 +36,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, ExecuteOptions opt throw new ArgumentNullException(nameof(options)); } - ValidationHelper.ValidateObject(options, typeof(ExecuteOptions), _validationOptions); + ValidationHelper.ValidateObject(options, typeof(ExecuteOptions), _validationOptions, _serviceProvider); return new ExecuteAction(processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs index 73bb616c252..c51ca95dd78 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs @@ -37,7 +37,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, GetEnvironmentVari throw new ArgumentNullException(nameof(options)); } - ValidationHelper.ValidateObject(options, typeof(GetEnvironmentVariableOptions), _validationOptions); + ValidationHelper.ValidateObject(options, typeof(GetEnvironmentVariableOptions), _validationOptions, _serviceProvider); return new GetEnvironmentVariableAction(_logger, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs index c6ba04ce178..8f813050e7f 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs @@ -36,7 +36,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, LoadProfilerOption throw new ArgumentNullException(nameof(options)); } - ValidationHelper.ValidateObject(options, typeof(LoadProfilerOptions), _validationOptions); + ValidationHelper.ValidateObject(options, typeof(LoadProfilerOptions), _validationOptions, _serviceProvider); return new LoadProfilerAction(_logger, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs index 92d1f2b95f5..7741ac25afe 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs @@ -36,7 +36,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, SetEnvironmentVari throw new ArgumentNullException(nameof(options)); } - ValidationHelper.ValidateObject(options, typeof(SetEnvironmentVariableOptions), _validationOptions); + ValidationHelper.ValidateObject(options, typeof(SetEnvironmentVariableOptions), _validationOptions, _serviceProvider); return new SetEnvironmentVariableAction(_logger, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.Validate.cs index 05cf725f5f4..01f2d44124d 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.Validate.cs @@ -27,7 +27,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( CultureInfo.InvariantCulture, Strings.ErrorMessage_DisabledFeature, - nameof(CollectExceptionsAction)))); + nameof(CollectExceptionsAction)), [nameof(CollectExceptionsAction)])); } return results; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.Validate.cs index 362985a54c8..27eee18bf69 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.Validate.cs @@ -26,7 +26,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( CultureInfo.InvariantCulture, Strings.ErrorMessage_DisabledFeature, - nameof(CollectionRules.Actions.CollectStacksAction)))); + nameof(CollectionRules.Actions.CollectStacksAction)), [nameof(CollectionRules.Actions.CollectStacksAction)])); } return results; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs index ea47f26d0a7..278547f7958 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs @@ -53,7 +53,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali CultureInfo.InvariantCulture, Strings.ErrorMessage_TwoFieldsCannotBeSpecified, nameof(Profile), - nameof(StoppingEvent)))); + nameof(StoppingEvent)), [nameof(Profile), nameof(StoppingEvent)])); } if (HasProviders()) @@ -66,7 +66,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali CultureInfo.InvariantCulture, Strings.ErrorMessage_TwoFieldsCannotBeSpecified, nameof(Profile), - nameof(Providers)))); + nameof(Providers)), [nameof(Profile), nameof(Providers)])); } } else if (HasProviders()) @@ -91,7 +91,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali CultureInfo.InvariantCulture, Strings.ErrorMessage_TwoFieldsMissing, nameof(Profile), - nameof(Providers)))); + nameof(Providers)), [nameof(Profile), nameof(Providers)])); } if (HasStoppingEvent()) @@ -107,7 +107,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali Strings.ErrorMessage_MissingStoppingEventProvider, nameof(StoppingEvent), StoppingEvent.ProviderName, - nameof(Providers)))); + nameof(Providers)), [nameof(StoppingEvent), nameof(Providers)])); } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/RequiredGuidAttribute.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/RequiredGuidAttribute.cs index e23e9a230a4..117674c27f1 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/RequiredGuidAttribute.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/RequiredGuidAttribute.cs @@ -20,10 +20,14 @@ public override string FormatErrorMessage(string name) protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) { + if (validationContext.MemberName is null) + { + throw new ArgumentNullException(nameof(validationContext.MemberName)); + } if (!(value is Guid)) { return new ValidationResult( - FormatErrorMessage(validationContext.DisplayName)); + FormatErrorMessage(validationContext.DisplayName), [validationContext.MemberName]); } Guid guidVal = (Guid)value; @@ -31,7 +35,7 @@ public override string FormatErrorMessage(string name) if (guidVal == Guid.Empty) { return new ValidationResult( - FormatErrorMessage(validationContext.DisplayName)); + FormatErrorMessage(validationContext.DisplayName), [validationContext.MemberName]); } return ValidationResult.Success; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ValidateEgressProviderAttribute.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ValidateEgressProviderAttribute.cs index 5e77e45e06c..6743a5395a0 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ValidateEgressProviderAttribute.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ValidateEgressProviderAttribute.cs @@ -14,10 +14,14 @@ internal sealed class ValidateEgressProviderAttribute : { protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) { + if (validationContext.MemberName is null) + { + throw new ArgumentNullException(nameof(validationContext.MemberName)); + } if (!(value is string)) { return new ValidationResult( - FormatErrorMessage(validationContext.DisplayName)); + FormatErrorMessage(validationContext.DisplayName), [validationContext.MemberName]); } string egressProvider = (string)value; @@ -33,7 +37,7 @@ internal sealed class ValidateEgressProviderAttribute : string.Format( CultureInfo.InvariantCulture, Strings.ErrorMessage_EgressProviderDoesNotExist, - egressProvider)); + egressProvider), [validationContext.MemberName]); } return ValidationResult.Success; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.Validate.cs index 44c132c45ee..689ba328238 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.Validate.cs @@ -19,7 +19,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( Strings.ErrorMessage_TwoFieldsMissing, nameof(GreaterThan), - nameof(LessThan)))); + nameof(LessThan)), [nameof(GreaterThan), nameof(LessThan)])); } else if (GreaterThan.HasValue && LessThan.HasValue && LessThan.Value < GreaterThan.Value) { @@ -28,7 +28,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( Strings.ErrorMessage_FieldMustBeLessThanOtherField, nameof(GreaterThan), - nameof(LessThan)))); + nameof(LessThan)), [nameof(GreaterThan), nameof(LessThan)])); } return results; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/IEventCounterShortcuts.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/IEventCounterShortcuts.Validate.cs index 5f81bfb93ca..8081f9df8d3 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/IEventCounterShortcuts.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/IEventCounterShortcuts.Validate.cs @@ -19,7 +19,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( Strings.ErrorMessage_FieldMustBeLessThanOtherField, nameof(GreaterThan), - nameof(LessThan)))); + nameof(LessThan)), [nameof(GreaterThan), nameof(LessThan)])); } return results; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.Validate.cs index 3ac644373fb..30952baf8dd 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.Validate.cs @@ -19,7 +19,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( Strings.ErrorMessage_TwoFieldsMissing, nameof(GreaterThan), - nameof(LessThan)))); + nameof(LessThan)), [nameof(GreaterThan), nameof(LessThan)])); } else if (GreaterThan.HasValue && LessThan.HasValue && LessThan.Value < GreaterThan.Value) { @@ -28,7 +28,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( Strings.ErrorMessage_FieldMustBeLessThanOtherField, nameof(GreaterThan), - nameof(LessThan)))); + nameof(LessThan)), [nameof(GreaterThan), nameof(LessThan)])); } return results; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs index e47c88962d2..be98da8d6c8 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs @@ -40,7 +40,7 @@ public static bool TryValidateOptions(Type optionsType, object options, Validati { foreach (string failure in validateResult.Failures) { - results.Add(new ValidationResult(failure)); + results.Add(new ValidationResult(failure, [validationContext.MemberName])); hasFailedResults = true; } } @@ -61,9 +61,9 @@ public static bool TryValidateObject(object options, Type type, ValidationOption return TryValidateObject(options, type, validationOptions, validationContext, results); } - public static bool TryValidateObject(object options, Type type, ValidationOptions validationOptions, List results) + public static bool TryValidateObject(object options, Type type, ValidationOptions validationOptions, IServiceProvider serviceProvider, List results) { - var validationContext = new ValidationContext(options, type.Name, null, items: null) { + var validationContext = new ValidationContext(options, type.Name, serviceProvider, items: null) { MemberName = type.Name }; return TryValidateObject(options, type, validationOptions, validationContext, results); @@ -99,9 +99,9 @@ public static bool TryValidateObject(object options, Type type, ValidationOption return true; } - public static void ValidateObject(object options, Type type, ValidationOptions validationOptions) + public static void ValidateObject(object options, Type type, ValidationOptions validationOptions, IServiceProvider serviceProvider) { - if (!TryValidateObject(options, type, validationOptions, new List())) + if (!TryValidateObject(options, type, validationOptions, serviceProvider, new List())) { throw new ValidationException("Validation failed for " + type.FullName); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs index c32f8c165c7..665e87cdb27 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs @@ -89,7 +89,7 @@ public bool TryValidateOptions( } else { - results.Add(new ValidationResult(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownTriggerType, triggerName))); + results.Add(new ValidationResult(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownTriggerType, triggerName), [validationContext.MemberName])); return false; } } diff --git a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs index ff4840b1454..69a6a3ffa4c 100644 --- a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs +++ b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs @@ -86,8 +86,7 @@ private static IHostBuilder Configure(this IHostBuilder builder, StartupAuthenti { return builder.ConfigureServices((HostBuilderContext context, IServiceCollection services) => { - var validationOptions = services.BuildServiceProvider().GetRequiredService>().Value; - IAuthenticationConfigurator authConfigurator = AuthConfiguratorFactory.Create(startupAuthMode, context, validationOptions); + IAuthenticationConfigurator authConfigurator = AuthConfiguratorFactory.Create(startupAuthMode, context, services.BuildServiceProvider()); services.AddSingleton(authConfigurator); //TODO Many of these service additions should be done through extension methods diff --git a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs b/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs index 2a377255014..548af5388b0 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs @@ -7,10 +7,15 @@ using Microsoft.Diagnostics.Monitoring.TestCommon; #endif using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; +using System.Diagnostics.Tracing; using System.Globalization; namespace Microsoft.Diagnostics.Tools.Monitor @@ -96,7 +101,7 @@ private static void MapRootOptions(RootOptions obj, string prefix, string separa { // TODO: in Tests, it has an additional property. Weird. MapAuthenticationOptions(obj.Authentication, FormattableString.Invariant($"{prefix}{nameof(obj.Authentication)}"), separator, map); - MapCollectionRules(obj.CollectionRules, FormattableString.Invariant($"{prefix}{nameof(obj.CollectionRules)}"), separator, map); + MapDictionary_String_CollectionRuleOptions(obj.CollectionRules, FormattableString.Invariant($"{prefix}{nameof(obj.CollectionRules)}"), separator, map); // GlobalCounterOptions MapGlobalCounterOptions(obj.GlobalCounter, FormattableString.Invariant($"{prefix}{nameof(obj.GlobalCounter)}"), separator, map); // InProcessFeaturesOptions @@ -104,6 +109,7 @@ private static void MapRootOptions(RootOptions obj, string prefix, string separa MapDiagnosticPortOptions(obj.DiagnosticPort, FormattableString.Invariant($"{prefix}{nameof(obj.DiagnosticPort)}"), separator, map); // DiagnosticPortOptions // EgressOptions + MapEgressOptions(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), separator, map); // MetricsOptions MapStorageOptions(obj.Storage, FormattableString.Invariant($"{prefix}{nameof(obj.Storage)}"), separator, map); // ProcessFilterOptions @@ -128,16 +134,14 @@ private static void MapRootOptions(RootOptions obj, string prefix, string separa // } // } - private static void MapCollectionRules(IDictionary? obj, string valueName, string separator, IDictionary map) + private static void MapDictionary_String_CollectionRuleOptions(IDictionary? obj, string valueName, string separator, IDictionary map) { if (null != obj) { - System.Console.WriteLine("MapCollectionRules"); var prefix = FormattableString.Invariant($"{valueName}{separator}"); // passed to mapdictionary. foreach ((string key, CollectionRuleOptions value) in obj) { string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); - System.Console.WriteLine($"key: {keyString}"); MapCollectionRuleOptions(value, FormattableString.Invariant($"{prefix}{keyString}"), separator, map); } } @@ -147,7 +151,7 @@ private static void MapCollectionRuleOptions(CollectionRuleOptions obj, string v { string prefix = FormattableString.Invariant($"{valueName}{separator}"); // MapFilters(obj.Filters, FormattableString.Invariant($"{prefix}{nameof(obj.Filters)}"), separator, map); - // MapTrigger(obj.Trigger, FormattableString.Invariant($"{prefix}{nameof(obj.Trigger)}"), separator, map); + MapCollectionRuleTriggerOptions(obj.Trigger, FormattableString.Invariant($"{prefix}{nameof(obj.Trigger)}"), separator, map); MapActions(obj.Actions, FormattableString.Invariant($"{prefix}{nameof(obj.Actions)}"), separator, map); // MapLimits(obj.Limits, FormattableString.Invariant($"{prefix}{nameof(obj.Limits)}"), separator, map); } @@ -167,10 +171,206 @@ private static void MapCollectionRuleActionOptions(CollectionRuleActionOptions o string prefix = FormattableString.Invariant($"{valueName}{separator}"); MapString(obj.Name, FormattableString.Invariant($"{prefix}{nameof(obj.Name)}"), map); MapString(obj.Type, FormattableString.Invariant($"{prefix}{nameof(obj.Type)}"), map); - // TODO: map object Settings + MapCollectionRuleActionOptions_Settings(obj.Type, obj.Settings, FormattableString.Invariant($"{prefix}{nameof(obj.Settings)}"), separator, map); MapBool(obj.WaitForCompletion, FormattableString.Invariant($"{prefix}{nameof(obj.WaitForCompletion)}"), map); } + private static void MapCollectionRuleActionOptions_Settings(string type, object? settings, string valueName, string separator, IDictionary map) + { + if (null != settings) + { + switch (type) + { + case KnownCollectionRuleActions.CollectDump: + MapCollectDumpOptions(settings as CollectDumpOptions, valueName, separator, map); + break; + // case KnownCollectionRuleActions.CollectExceptions: + // MapCollectExceptionsOptions(settings as CollectExceptionsOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleActions.CollectGCDump: + // MapCollectGCDumpOptions(settings as CollectGCDumpOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleActions.CollectLiveMetrics: + // MapCollectLiveMetricsOptions(settings as CollectLiveMetricsOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleActions.CollectLogs: + // MapCollectLogsOptions(settings as CollectLogsOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleActions.CollectStacks: + // MapCollectStacksOptions(settings as CollectStacksOptions, valueName, separator, map); + // break; + case KnownCollectionRuleActions.CollectTrace: + MapCollectTraceOptions(settings as CollectTraceOptions, valueName, separator, map); + break; + // case KnownCollectionRuleActions.Execute: + // MapExecuteOptions(settings as ExecuteOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleActions.LoadProfiler: + // MapLoadProfilerOptions(settings as LoadProfilerOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleActions.SetEnvironmentVariable: + // MapSetEnvironmentVariableOptions(settings as SetEnvironmentVariableOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleActions.GetEnvironmentVariable: + // MapGetEnvironmentVariableOptions(settings as GetEnvironmentVariableOptions, valueName, separator, map); + // break; + default: + throw new NotSupportedException($"Unknown action type: {type}"); + } + } + } + + private static void MapCollectDumpOptions(CollectDumpOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapDumpType(obj.Type, FormattableString.Invariant($"{prefix}{nameof(obj.Type)}"), map); + MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); + MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); + } + } + + private static void MapCollectTraceOptions(CollectTraceOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapTraceProfile(obj.Profile, FormattableString.Invariant($"{prefix}{nameof(obj.Profile)}"), map); + MapEventProviders(obj.Providers, FormattableString.Invariant($"{prefix}{nameof(obj.Providers)}"), separator, map); + MapBool(obj.RequestRundown, FormattableString.Invariant($"{prefix}{nameof(obj.RequestRundown)}"), map); + MapInt(obj.BufferSizeMegabytes, FormattableString.Invariant($"{prefix}{nameof(obj.BufferSizeMegabytes)}"), map); + MapTimeSpan(obj.Duration, FormattableString.Invariant($"{prefix}{nameof(obj.Duration)}"), map); + MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); + MapTraceEventFilter(obj.StoppingEvent, FormattableString.Invariant($"{prefix}{nameof(obj.StoppingEvent)}"), separator, map); + MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); + } + } + + private static void MapTraceProfile(TraceProfile? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + + private static void MapEventProviders(List? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + for (int index = 0; index < obj.Count; index++) + { + EventPipeProvider value = obj[index]; + MapEventPipeProvider(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); + } + } + } + + private static void MapEventPipeProvider(EventPipeProvider obj, string valueName, string separator, IDictionary map) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Name, FormattableString.Invariant($"{prefix}{nameof(obj.Name)}"), map); + MapString(obj.Keywords, FormattableString.Invariant($"{prefix}{nameof(obj.Keywords)}"), map); + MapEventLevel(obj.EventLevel, FormattableString.Invariant($"{prefix}{nameof(obj.EventLevel)}"), map); + MapDictionary_String_String(obj.Arguments, FormattableString.Invariant($"{prefix}{nameof(obj.Arguments)}"), separator, map); + } + + private static void MapEventLevel(EventLevel? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + + private static void MapTimeSpan(TimeSpan? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + + private static void MapTraceEventFilter(TraceEventFilter? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.ProviderName, FormattableString.Invariant($"{prefix}{nameof(obj.ProviderName)}"), map); + MapString(obj.EventName, FormattableString.Invariant($"{prefix}{nameof(obj.EventName)}"), map); + MapDictionary_String_String(obj.PayloadFilter, FormattableString.Invariant($"{prefix}{nameof(obj.PayloadFilter)}"), separator, map); + } + } + + private static void MapDictionary_String_String(IDictionary? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + foreach ((string key, string value) in obj) + { + string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); + MapString(value, FormattableString.Invariant($"{prefix}{keyString}"), map); + } + } + } + + private static void MapDumpType(DumpType? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + + private static void MapCollectionRuleTriggerOptions(CollectionRuleTriggerOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Type, FormattableString.Invariant($"{prefix}{nameof(obj.Type)}"), map); + MapCollectionRuleTriggerOptions_Settings(obj.Type, obj.Settings, FormattableString.Invariant($"{prefix}{nameof(obj.Settings)}"), separator, map); + } + } + + private static void MapCollectionRuleTriggerOptions_Settings(string type, object? settings, string valueName, string separator, IDictionary map) + { + if (null != settings) + { + switch (type) + { + // case KnownCollectionRuleTriggers.AspNetRequestCount: + // MapAspNetRequestCountOptions(settings as AspNetRequestCountOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleTriggers.AspNetRequestDuration: + // MapAspNetRequestDurationOptions(settings as AspNetRequestDurationOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleTriggers.AspNetResponseStatus: + // MapAspNetResponseStatusOptions(settings as AspNetResponseStatusOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleTriggers.EventCounter: + // MapEventCounterOptions(settings as EventCounterOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleTriggers.CPUUsage: + // MapCPUUsageOptions(settings as CPUUsageOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleTriggers.GCHeapSize: + // MapGCHeapSizeOptions(settings as GCHeapSizeOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleTriggers.ThreadpoolQueueLength: + // MapThreadpoolQueueLengthOptions(settings as ThreadpoolQueueLengthOptions, valueName, separator, map); + // break; + // case KnownCollectionRuleTriggers.EventMeter: + // MapEventMeterOptions(settings as EventMeterOptions, valueName, separator, map); + // break; + default: + throw new NotSupportedException($"Unknown trigger type: {type}"); + } + } + } + private static void MapAuthenticationOptions(AuthenticationOptions? obj, string valueName, string separator, IDictionary map) { if (null != obj) @@ -268,6 +468,40 @@ private static void MapDiagnosticPortConnectionMode(DiagnosticPortConnectionMode } } + private static void MapEgressOptions(EgressOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapDictionary_String_FileSystemEgressProviderOptions(obj.FileSystem, FormattableString.Invariant($"{prefix}{nameof(obj.FileSystem)}"), separator, map); + MapDictionary_String_String(obj.Properties, FormattableString.Invariant($"{prefix}{nameof(obj.Properties)}"), separator, map); + } + } + + private static void MapDictionary_String_FileSystemEgressProviderOptions(IDictionary? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + foreach ((string key, FileSystemEgressProviderOptions value) in obj) + { + string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); + MapFileSystemEgressProviderOptions(value, FormattableString.Invariant($"{prefix}{keyString}"), separator, map); + } + } + } + + private static void MapFileSystemEgressProviderOptions(FileSystemEgressProviderOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.DirectoryPath, FormattableString.Invariant($"{prefix}{nameof(obj.DirectoryPath)}"), map); + MapString(obj.IntermediateDirectoryPath, FormattableString.Invariant($"{prefix}{nameof(obj.IntermediateDirectoryPath)}"), map); + MapInt(obj.CopyBufferSize, FormattableString.Invariant($"{prefix}{nameof(obj.CopyBufferSize)}"), map); + } + } + private static void MapStorageOptions(StorageOptions? obj, string valueName, string separator, IDictionary map) { if (null != obj) diff --git a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs index 48167f3cd29..622c21828cc 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs @@ -33,6 +33,7 @@ internal partial class EgressExtension : IExtension, IEgressExtension private readonly string _extensionPath; private readonly ILogger _logger; private readonly ExtensionManifest _manifest; + private readonly IServiceProvider _serviceProvider; private readonly ValidationOptions _validationOptions; private readonly IDictionary _processEnvironmentVariables = new Dictionary(); private const int PayloadProtocolVersion = 1; @@ -44,13 +45,14 @@ public EgressExtension( string extensionPath, IEgressConfigurationProvider configurationProvider, ILogger logger, - IOptions validationOptions) + IServiceProvider serviceProvider) { _configurationProvider = configurationProvider ?? throw new ArgumentNullException(nameof(configurationProvider)); _extensionPath = extensionPath ?? throw new ArgumentNullException(nameof(extensionPath)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _manifest = manifest ?? throw new ArgumentNullException(nameof(manifest)); - _validationOptions = validationOptions?.Value ?? throw new ArgumentNullException(nameof(validationOptions)); + _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } /// @@ -114,7 +116,7 @@ public async Task EgressArtifact( ExtensionMode mode, CancellationToken token) { - _manifest.Validate(_validationOptions); + _manifest.Validate(_serviceProvider, _validationOptions); ProcessStartInfo pStart = new ProcessStartInfo() { diff --git a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs index 95ed8ff53b9..0d1079a944b 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs @@ -14,21 +14,21 @@ internal sealed class EgressExtensionFactory { private readonly IEgressConfigurationProvider _configurationProvider; private readonly ILogger _logger; - private readonly IOptions _validationOptions; + private readonly IServiceProvider _serviceProvider; public EgressExtensionFactory( IEgressConfigurationProvider configurationProvider, ILogger logger, - IOptions validationOptions) + IServiceProvider serviceProvider) { _configurationProvider = configurationProvider; _logger = logger; - _validationOptions = validationOptions ?? throw new ArgumentNullException(nameof(validationOptions)); + _serviceProvider = serviceProvider; } public IEgressExtension Create(ExtensionManifest manifest, string path) { - return new EgressExtension(manifest, path, _configurationProvider, _logger, _validationOptions); + return new EgressExtension(manifest, path, _configurationProvider, _logger, _serviceProvider); } } } diff --git a/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs b/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs index ca9a5e4a7d0..e9aee2074bc 100644 --- a/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs +++ b/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs @@ -4,6 +4,7 @@ #nullable disable using Microsoft.AspNetCore.Http.Validation; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Globalization; @@ -73,10 +74,10 @@ public static ExtensionManifest FromPath(string path) } } - public void Validate(ValidationOptions validationOptions) + public void Validate(IServiceProvider serviceProvider, ValidationOptions validationOptions) { List results = new(); - if (!ValidationHelper.TryValidateObject(this, typeof(ExtensionManifest), validationOptions, results)) + if (!ValidationHelper.TryValidateObject(this, typeof(ExtensionManifest), validationOptions, serviceProvider, results)) { ExtensionException.ThrowInvalidManifest(results.First().ErrorMessage); } From 668e4c6058ea80b668fa8659b4758763c61d5933 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 15 Apr 2025 23:14:02 +0000 Subject: [PATCH 124/174] Fix PassThroughOptions mapping --- ...ics.Monitoring.Tool.FunctionalTests.csproj | 2 +- .../Runners/MonitorRunner.cs | 6 ++- .../TestHostHelper.cs | 21 +++++++++- .../Commands/GenerateApiKeyCommandHandler.cs | 14 ++++--- ...nsExtensions.cs => CommonOptionsMapper.cs} | 42 ++++++++++++++----- 5 files changed, 65 insertions(+), 20 deletions(-) rename src/Tools/dotnet-monitor/{CommonOptionsExtensions.cs => CommonOptionsMapper.cs} (93%) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj index 546274c7a7c..eb05f1f6488 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj @@ -71,7 +71,7 @@ - + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/MonitorRunner.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/MonitorRunner.cs index afb28d94448..36a604d4e1c 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/MonitorRunner.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/MonitorRunner.cs @@ -165,7 +165,8 @@ public virtual async Task StartAsync(string command, string[] args, Cancellation _adapter.Environment.Add("ASPNETCORE_HOSTINGSTARTUPASSEMBLIES", TestHostingStartupAssemblyName); // Set configuration via environment variables - var configurationViaEnvironment = ConfigurationFromEnvironment.ToEnvironmentConfiguration(useDotnetMonitorPrefix: true); + var optionsMapper = new CommonOptionsMapper(); + var configurationViaEnvironment = optionsMapper.ToEnvironmentConfiguration(ConfigurationFromEnvironment, useDotnetMonitorPrefix: true); if (configurationViaEnvironment.Count > 0) { // Set additional environment variables from configuration @@ -197,7 +198,8 @@ protected virtual void StandardOutputCallback(string line) public void WriteKeyPerValueConfiguration(RootOptions options) { - foreach (KeyValuePair entry in options.ToKeyPerFileConfiguration()) + CommonOptionsMapper optionsMapper = new(); + foreach (KeyValuePair entry in optionsMapper.ToKeyPerFileConfiguration(options)) { File.WriteAllText( Path.Combine(SharedConfigDirectoryPath, entry.Key), diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs index 02c48fa9433..bef5038156b 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; +using System.Globalization; using System.Threading.Tasks; using Xunit.Abstractions; @@ -73,7 +74,9 @@ public static IHost CreateHost( RootOptions options = new(); setup(options); - IDictionary configurationValues = options.ToConfigurationValues(); + CommonOptionsMapper optionsMapper = new(); + optionsMapper.AddActionSettings(nameof(PassThroughAction), MapPassThroughOptions); + IDictionary configurationValues = optionsMapper.ToConfigurationValues(options); outputHelper.WriteLine("Begin Configuration:"); foreach ((string key, string value) in configurationValues) { @@ -128,5 +131,21 @@ public static IHost CreateHost( }) .Build(); } + + private static void MapPassThroughOptions(PassThroughOptions obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Input1, FormattableString.Invariant($"{prefix}{nameof(obj.Input1)}")); + MapString(obj.Input2, FormattableString.Invariant($"{prefix}{nameof(obj.Input2)}")); + MapString(obj.Input3, FormattableString.Invariant($"{prefix}{nameof(obj.Input3)}")); + } + + void MapString(string value, string valueName) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } } } diff --git a/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs b/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs index cf86ae17cf7..5d14456b0c7 100644 --- a/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs +++ b/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs @@ -68,7 +68,8 @@ public static void Invoke(OutputFormat output, TimeSpan expiration, TextWriter o { // Create configuration from object model. MemoryConfigurationSource source = new(); - source.InitialData = (IDictionary)opts.ToConfigurationValues(); // Cast the values as nullable, since they are reference types we can safely do this. + CommonOptionsMapper optionsMapper = new(); + source.InitialData = (IDictionary)optionsMapper.ToConfigurationValues(opts); // Cast the values as nullable, since they are reference types we can safely do this. ConfigurationBuilder builder = new(); builder.Add(source); IConfigurationRoot configuration = builder.Build(); @@ -100,11 +101,14 @@ public static void Invoke(OutputFormat output, TimeSpan expiration, TextWriter o case OutputFormat.Cmd: case OutputFormat.PowerShell: case OutputFormat.Shell: - IDictionary optList = opts.ToEnvironmentConfiguration(); - foreach ((string name, string value) in optList) { - outputBldr.AppendFormat(CultureInfo.InvariantCulture, GetFormatString(output), name, value); - outputBldr.AppendLine(); + CommonOptionsMapper optionsMapper = new(); + IDictionary optList = optionsMapper.ToEnvironmentConfiguration(opts); + foreach ((string name, string value) in optList) + { + outputBldr.AppendFormat(CultureInfo.InvariantCulture, GetFormatString(output), name, value); + outputBldr.AppendLine(); + } } break; } diff --git a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs similarity index 93% rename from src/Tools/dotnet-monitor/CommonOptionsExtensions.cs rename to src/Tools/dotnet-monitor/CommonOptionsMapper.cs index 548af5388b0..a326ab8918d 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs @@ -20,7 +20,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor { - internal static class CommonOptionsExtensions + internal class CommonOptionsMapper { private const string KeySegmentSeparator = "__"; @@ -30,7 +30,7 @@ internal static class CommonOptionsExtensions /// /// Each key is the configuration path; each value is the configuration path value. /// - public static IDictionary ToConfigurationValues(this RootOptions options) + public IDictionary ToConfigurationValues(RootOptions options) { Dictionary variables = new(StringComparer.OrdinalIgnoreCase); MapRootOptions(options, string.Empty, ConfigurationPath.KeyDelimiter, variables); @@ -43,7 +43,7 @@ public static IDictionary ToConfigurationValues(this RootOptions /// /// Each key is the variable name; each value is the variable value. /// - public static IDictionary ToEnvironmentConfiguration(this RootOptions options, bool useDotnetMonitorPrefix = false) + public IDictionary ToEnvironmentConfiguration(RootOptions options, bool useDotnetMonitorPrefix = false) { Dictionary variables = new(StringComparer.OrdinalIgnoreCase); MapRootOptions(options, useDotnetMonitorPrefix ? ToolIdentifiers.StandardPrefix : string.Empty, KeySegmentSeparator, variables); @@ -56,7 +56,7 @@ public static IDictionary ToEnvironmentConfiguration(this RootOp /// /// Each key is the file name; each value is the file content. /// - public static IDictionary ToKeyPerFileConfiguration(this RootOptions options) + public IDictionary ToKeyPerFileConfiguration(RootOptions options) { Dictionary variables = new(StringComparer.OrdinalIgnoreCase); MapRootOptions(options, string.Empty, KeySegmentSeparator, variables); @@ -97,7 +97,7 @@ public static IDictionary ToKeyPerFileConfiguration(this RootOpt // } // } - private static void MapRootOptions(RootOptions obj, string prefix, string separator, IDictionary map) + private void MapRootOptions(RootOptions obj, string prefix, string separator, IDictionary map) { // TODO: in Tests, it has an additional property. Weird. MapAuthenticationOptions(obj.Authentication, FormattableString.Invariant($"{prefix}{nameof(obj.Authentication)}"), separator, map); @@ -134,7 +134,7 @@ private static void MapRootOptions(RootOptions obj, string prefix, string separa // } // } - private static void MapDictionary_String_CollectionRuleOptions(IDictionary? obj, string valueName, string separator, IDictionary map) + private void MapDictionary_String_CollectionRuleOptions(IDictionary? obj, string valueName, string separator, IDictionary map) { if (null != obj) { @@ -147,7 +147,7 @@ private static void MapDictionary_String_CollectionRuleOptions(IDictionary map) + private void MapCollectionRuleOptions(CollectionRuleOptions obj, string valueName, string separator, IDictionary map) { string prefix = FormattableString.Invariant($"{valueName}{separator}"); // MapFilters(obj.Filters, FormattableString.Invariant($"{prefix}{nameof(obj.Filters)}"), separator, map); @@ -156,7 +156,7 @@ private static void MapCollectionRuleOptions(CollectionRuleOptions obj, string v // MapLimits(obj.Limits, FormattableString.Invariant($"{prefix}{nameof(obj.Limits)}"), separator, map); } - private static void MapActions(List obj, string valueName, string separator, IDictionary map) + private void MapActions(List obj, string valueName, string separator, IDictionary map) { string prefix = FormattableString.Invariant($"{valueName}{separator}"); for (int index = 0; index < obj.Count; index++) @@ -166,7 +166,7 @@ private static void MapActions(List obj, string val } } - private static void MapCollectionRuleActionOptions(CollectionRuleActionOptions obj, string valueName, string separator, IDictionary map) + private void MapCollectionRuleActionOptions(CollectionRuleActionOptions obj, string valueName, string separator, IDictionary map) { string prefix = FormattableString.Invariant($"{valueName}{separator}"); MapString(obj.Name, FormattableString.Invariant($"{prefix}{nameof(obj.Name)}"), map); @@ -175,10 +175,21 @@ private static void MapCollectionRuleActionOptions(CollectionRuleActionOptions o MapBool(obj.WaitForCompletion, FormattableString.Invariant($"{prefix}{nameof(obj.WaitForCompletion)}"), map); } - private static void MapCollectionRuleActionOptions_Settings(string type, object? settings, string valueName, string separator, IDictionary map) + private Dictionary>>? _actionSettingsMap; + + public void AddActionSettings(string type, Action> mapAction) + { + (_actionSettingsMap ??= new()).Add(type, (obj, valueName, separator, map) => + { + mapAction((TSettings)obj, valueName, separator, map); + }); + } + + private void MapCollectionRuleActionOptions_Settings(string type, object? settings, string valueName, string separator, IDictionary map) { if (null != settings) { + // TODO: inline the well-known ones to avoid a dictionary lookup. switch (type) { case KnownCollectionRuleActions.CollectDump: @@ -206,6 +217,7 @@ private static void MapCollectionRuleActionOptions_Settings(string type, object? // MapExecuteOptions(settings as ExecuteOptions, valueName, separator, map); // break; // case KnownCollectionRuleActions.LoadProfiler: + // MapLoadProfilerOptions(settings as LoadProfilerOptions, valueName, separator, map); // break; // case KnownCollectionRuleActions.SetEnvironmentVariable: @@ -215,7 +227,15 @@ private static void MapCollectionRuleActionOptions_Settings(string type, object? // MapGetEnvironmentVariableOptions(settings as GetEnvironmentVariableOptions, valueName, separator, map); // break; default: - throw new NotSupportedException($"Unknown action type: {type}"); + if (_actionSettingsMap?.TryGetValue(type, out Action>? mapAction) == true) + { + mapAction(settings, valueName, separator, map); + } + else + { + throw new NotSupportedException($"Unknown action type: {type}"); + } + break; } } } From 6deccefb186ccad16befd69a504576e5812bc8af Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 16 Apr 2025 20:46:49 +0000 Subject: [PATCH 125/174] Add more validatable types, mapping logic --- .../ActionListExecutorTests.cs | 2 +- .../CollectGCDumpActionTests.cs | 3 +- .../CollectLiveMetricsActionTests.cs | 3 +- .../TestValidatableType.cs | 9 + .../ValidatableInfoResolver.cs | 609 +++++++++++++++++- .../dotnet-monitor/CommonOptionsMapper.cs | 223 ++++++- 6 files changed, 797 insertions(+), 52 deletions(-) diff --git a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs index 66b5d26a9dd..811bdee9f31 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs @@ -82,7 +82,7 @@ public Task ActionListExecutor_SecondActionFail_DeferredCompletion() return ActionListExecutor_SecondActionFail(waitForCompletion: false); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] public Task ActionListExecutor_SecondActionFail_WaitedCompletion() { return ActionListExecutor_SecondActionFail(waitForCompletion: true); diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs index 16903391c50..c76621a0dd6 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Monitoring.TestCommon.Options; using Microsoft.Diagnostics.Monitoring.TestCommon.Runners; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Exceptions; @@ -104,7 +105,7 @@ await runner.ExecuteAsync(async () => await runner.SendCommandAsync(TestAppScenarios.AsyncWait.Commands.Continue); }); - }); + }, TestValidatableTypes.AddValidation); } private static async Task ValidateGCDump(Stream gcdumpStream) diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectLiveMetricsActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectLiveMetricsActionTests.cs index a82a33f43c0..f172d62e9bc 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectLiveMetricsActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectLiveMetricsActionTests.cs @@ -7,6 +7,7 @@ using Microsoft.Diagnostics.Monitoring.TestCommon.Runners; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; @@ -111,7 +112,7 @@ await LiveMetricsTestUtilities.ValidateMetrics(new[] { providerName }, await runner.SendCommandAsync(TestAppScenarios.AsyncWait.Commands.Continue); }); - }); + }, TestValidatableTypes.AddValidation); } [Theory(Skip = "Flaky")] diff --git a/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs b/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs index acab632a55c..f8d61c51864 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs @@ -7,6 +7,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; namespace Microsoft.Diagnostics.Tools.Monitor { @@ -29,6 +30,14 @@ internal sealed class TestValidatableTypes public required GlobalCounterOptions GlobalCounterOptions { get; init; } + public required CollectGCDumpOptions CollectGCDumpOptions { get; init; } + + public required CollectLiveMetricsOptions CollectLiveMetricsOptions { get; init; } + + public required RootOptions RootOptions { get; init; } + + public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } + public static void AddValidation(IServiceCollection services) { GeneratedServiceCollectionExtensions.AddValidation(services); diff --git a/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs b/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs index 8aecf128e05..dc9b5c63042 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs @@ -199,6 +199,101 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateGlobalCounterOptions(); return true; } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions)) + { + validatableInfo = CreateCollectGCDumpOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions)) + { + validatableInfo = CreateCollectLiveMetricsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions)) + { + validatableInfo = CreateMonitorApiKeyOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions)) + { + validatableInfo = CreateAzureAdOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions)) + { + validatableInfo = CreateAuthenticationOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration)) + { + validatableInfo = CreateExceptionsConfiguration(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions)) + { + validatableInfo = CreateExceptionsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions)) + { + validatableInfo = CreateInProcessFeaturesOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions)) + { + validatableInfo = CreateCorsConfigurationOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions)) + { + validatableInfo = CreateEgressOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider)) + { + validatableInfo = CreateMetricProvider(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions)) + { + validatableInfo = CreateMetricsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions)) + { + validatableInfo = CreateProcessFilterOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions)) + { + validatableInfo = CreateCollectionRuleTriggerDefaultsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions)) + { + validatableInfo = CreateCollectionRuleLimitsDefaultsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions)) + { + validatableInfo = CreateCollectionRuleDefaultsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions)) + { + validatableInfo = CreateTemplateOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions)) + { + validatableInfo = CreateRootOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions)) + { + validatableInfo = CreateFileSystemEgressProviderOptions(); + return true; + } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes)) { validatableInfo = CreateTestValidatableTypes(); @@ -788,12 +883,12 @@ private ValidatableTypeInfo CreateExecuteOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - propertyType: typeof(global::System.Type), - name: "EqualityContract", - displayName: "EqualityContract" - ), + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), propertyType: typeof(string), @@ -808,12 +903,12 @@ private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), - propertyType: typeof(global::System.Type), - name: "EqualityContract", - displayName: "EqualityContract" - ), + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), propertyType: typeof(string), @@ -828,12 +923,12 @@ private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), - propertyType: typeof(global::System.Type), - name: "EqualityContract", - displayName: "EqualityContract" - ), + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), propertyType: typeof(string), @@ -862,12 +957,12 @@ private ValidatableTypeInfo CreateTraceEventFilter() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - propertyType: typeof(global::System.Type), - name: "EqualityContract", - displayName: "EqualityContract" - ), + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), propertyType: typeof(string), @@ -965,6 +1060,446 @@ private ValidatableTypeInfo CreateGlobalCounterOptions() ] ); } + private ValidatableTypeInfo CreateCollectGCDumpOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectLiveMetricsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateMonitorApiKeyOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + propertyType: typeof(string), + name: "Subject", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + propertyType: typeof(string), + name: "PublicKey", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateAzureAdOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "TenantId", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "ClientId", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(global::System.Uri), + name: "AppIdUri", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "RequiredRole", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateAuthenticationOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + name: "MonitorApiKey", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + name: "AzureAd", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateExceptionsConfiguration() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Exclude", + displayName: "Exclude" + ), + ] + ); + } + private ValidatableTypeInfo CreateExceptionsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + propertyType: typeof(int?), + name: "TopLevelLimit", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + name: "CollectionFilters", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateInProcessFeaturesOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + name: "Exceptions", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCorsConfigurationOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + propertyType: typeof(string), + name: "AllowedOrigins", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateEgressOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "FileSystem", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Properties", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateMetricProvider() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), + propertyType: typeof(string), + name: "ProviderName", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateMetricsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + propertyType: typeof(int?), + name: "MetricCount", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Providers", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateProcessFilterOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Filters", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleTriggerDefaultsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(int?), + name: "RequestCount", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(int?), + name: "ResponseCount", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleLimitsDefaultsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(int?), + name: "ActionCount", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "ActionCountSlidingWindowDuration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RuleDuration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleDefaultsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + name: "Triggers", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + name: "Limits", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateTemplateOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleFilters", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleTriggers", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleActions", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleLimits", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateRootOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + name: "Authentication", + displayName: "Authentication" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRules", + displayName: "CollectionRules" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + name: "GlobalCounter", + displayName: "GlobalCounter" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + name: "InProcessFeatures", + displayName: "InProcessFeatures" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + name: "CorsConfiguration", + displayName: "CorsConfiguration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + name: "Egress", + displayName: "Egress" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + name: "Metrics", + displayName: "Metrics" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), + name: "DefaultProcess", + displayName: "DefaultProcess" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + name: "CollectionRuleDefaults", + displayName: "CollectionRuleDefaults" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + name: "Templates", + displayName: "Templates" + ), + ] + ); + } + private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + propertyType: typeof(string), + name: "DirectoryPath", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + propertyType: typeof(int?), + name: "CopyBufferSize", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } private ValidatableTypeInfo CreateTestValidatableTypes() { return new GeneratedValidatableTypeInfo( @@ -1006,6 +1541,30 @@ private ValidatableTypeInfo CreateTestValidatableTypes() name: "GlobalCounterOptions", displayName: "GlobalCounterOptions" ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + name: "CollectGCDumpOptions", + displayName: "CollectGCDumpOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + name: "CollectLiveMetricsOptions", + displayName: "CollectLiveMetricsOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + name: "RootOptions", + displayName: "RootOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + name: "FileSystemEgressProviderOptions", + displayName: "FileSystemEgressProviderOptions" + ), ] ); } @@ -1015,7 +1574,7 @@ private ValidatableTypeInfo CreateTestValidatableTypes() [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] internal static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "dimYgDF+jHmuFD/Mz8NJRdrOAABWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "o12abVmqqV0zqGgiPVl+aU9UAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. diff --git a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs index a326ab8918d..43dde3011c7 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs @@ -6,6 +6,7 @@ #if UNITTEST using Microsoft.Diagnostics.Monitoring.TestCommon; #endif +using Microsoft.Diagnostics.Monitoring.Options; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; @@ -107,8 +108,6 @@ private void MapRootOptions(RootOptions obj, string prefix, string separator, ID // InProcessFeaturesOptions // CorsConfigurationOptions MapDiagnosticPortOptions(obj.DiagnosticPort, FormattableString.Invariant($"{prefix}{nameof(obj.DiagnosticPort)}"), separator, map); - // DiagnosticPortOptions - // EgressOptions MapEgressOptions(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), separator, map); // MetricsOptions MapStorageOptions(obj.Storage, FormattableString.Invariant($"{prefix}{nameof(obj.Storage)}"), separator, map); @@ -195,15 +194,15 @@ private void MapCollectionRuleActionOptions_Settings(string type, object? settin case KnownCollectionRuleActions.CollectDump: MapCollectDumpOptions(settings as CollectDumpOptions, valueName, separator, map); break; - // case KnownCollectionRuleActions.CollectExceptions: - // MapCollectExceptionsOptions(settings as CollectExceptionsOptions, valueName, separator, map); - // break; - // case KnownCollectionRuleActions.CollectGCDump: - // MapCollectGCDumpOptions(settings as CollectGCDumpOptions, valueName, separator, map); - // break; - // case KnownCollectionRuleActions.CollectLiveMetrics: - // MapCollectLiveMetricsOptions(settings as CollectLiveMetricsOptions, valueName, separator, map); - // break; + case KnownCollectionRuleActions.CollectExceptions: + MapCollectExceptionsOptions(settings as CollectExceptionsOptions, valueName, separator, map); + break; + case KnownCollectionRuleActions.CollectGCDump: + MapCollectGCDumpOptions(settings as CollectGCDumpOptions, valueName, separator, map); + break; + case KnownCollectionRuleActions.CollectLiveMetrics: + MapCollectLiveMetricsOptions(settings as CollectLiveMetricsOptions, valueName, separator, map); + break; // case KnownCollectionRuleActions.CollectLogs: // MapCollectLogsOptions(settings as CollectLogsOptions, valueName, separator, map); // break; @@ -213,19 +212,18 @@ private void MapCollectionRuleActionOptions_Settings(string type, object? settin case KnownCollectionRuleActions.CollectTrace: MapCollectTraceOptions(settings as CollectTraceOptions, valueName, separator, map); break; - // case KnownCollectionRuleActions.Execute: - // MapExecuteOptions(settings as ExecuteOptions, valueName, separator, map); - // break; - // case KnownCollectionRuleActions.LoadProfiler: - - // MapLoadProfilerOptions(settings as LoadProfilerOptions, valueName, separator, map); - // break; - // case KnownCollectionRuleActions.SetEnvironmentVariable: - // MapSetEnvironmentVariableOptions(settings as SetEnvironmentVariableOptions, valueName, separator, map); - // break; - // case KnownCollectionRuleActions.GetEnvironmentVariable: - // MapGetEnvironmentVariableOptions(settings as GetEnvironmentVariableOptions, valueName, separator, map); - // break; + case KnownCollectionRuleActions.Execute: + MapExecuteOptions(settings as ExecuteOptions, valueName, separator, map); + break; + case KnownCollectionRuleActions.LoadProfiler: + MapLoadProfilerOptions(settings as LoadProfilerOptions, valueName, separator, map); + break; + case KnownCollectionRuleActions.SetEnvironmentVariable: + MapSetEnvironmentVariableOptions(settings as SetEnvironmentVariableOptions, valueName, separator, map); + break; + case KnownCollectionRuleActions.GetEnvironmentVariable: + MapGetEnvironmentVariableOptions(settings as GetEnvironmentVariableOptions, valueName, separator, map); + break; default: if (_actionSettingsMap?.TryGetValue(type, out Action>? mapAction) == true) { @@ -251,6 +249,135 @@ private static void MapCollectDumpOptions(CollectDumpOptions? obj, string valueN } } + private static void MapCollectExceptionsOptions(CollectExceptionsOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); + MapExceptionFormat(obj.Format, FormattableString.Invariant($"{prefix}{nameof(obj.Format)}"), map); + MapExceptionsConfiguration(obj.Filters, FormattableString.Invariant($"{prefix}{nameof(obj.Filters)}"), separator, map); + MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); + } + } + + private static void MapExceptionFormat(ExceptionFormat? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + + private static void MapExceptionsConfiguration(ExceptionsConfiguration? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapList_ExceptionFilter(obj.Include, FormattableString.Invariant($"{prefix}{nameof(obj.Include)}"), separator, map); + MapList_ExceptionFilter(obj.Exclude, FormattableString.Invariant($"{prefix}{nameof(obj.Exclude)}"), separator, map); + } + } + + private static void MapList_ExceptionFilter(List? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + for (int index = 0; index < obj.Count; index++) + { + ExceptionFilter value = obj[index]; + MapExceptionFilter(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); + } + } + } + + private static void MapExceptionFilter(ExceptionFilter obj, string valueName, string separator, IDictionary map) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.ExceptionType, FormattableString.Invariant($"{prefix}{nameof(obj.ExceptionType)}"), map); + MapString(obj.ModuleName, FormattableString.Invariant($"{prefix}{nameof(obj.ModuleName)}"), map); + MapString(obj.TypeName, FormattableString.Invariant($"{prefix}{nameof(obj.TypeName)}"), map); + MapString(obj.MethodName, FormattableString.Invariant($"{prefix}{nameof(obj.MethodName)}"), map); + } + + private static void MapCollectGCDumpOptions(CollectGCDumpOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); + MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); + } + } + + private static void MapCollectLiveMetricsOptions(CollectLiveMetricsOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapBool(obj.IncludeDefaultProviders, FormattableString.Invariant($"{prefix}{nameof(obj.IncludeDefaultProviders)}"), map); + MapArray_EventMetricsProvider(obj.Providers, FormattableString.Invariant($"{prefix}{nameof(obj.Providers)}"), separator, map); + MapArray_EventMetricsMeter(obj.Meters, FormattableString.Invariant($"{prefix}{nameof(obj.Meters)}"), separator, map); + MapTimeSpan(obj.Duration, FormattableString.Invariant($"{prefix}{nameof(obj.Duration)}"), map); + MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); + MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); + } + } + + private static void MapArray_EventMetricsProvider(EventMetricsProvider[]? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + for (int index = 0; index < obj.Length; index++) + { + EventMetricsProvider value = obj[index]; + MapEventMetricsProvider(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); + } + } + } + + private static void MapEventMetricsProvider(EventMetricsProvider obj, string valueName, string separator, IDictionary map) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.ProviderName, FormattableString.Invariant($"{prefix}{nameof(obj.ProviderName)}"), map); + MapArray_String(obj.CounterNames, FormattableString.Invariant($"{prefix}{nameof(obj.CounterNames)}"), separator, map); + } + + private static void MapArray_String(string[]? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + for (int index = 0; index < obj.Length; index++) + { + string value = obj[index]; + MapString(value, FormattableString.Invariant($"{prefix}{index}"), map); + } + } + } + + private static void MapArray_EventMetricsMeter(EventMetricsMeter[]? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + for (int index = 0; index < obj.Length; index++) + { + EventMetricsMeter value = obj[index]; + MapEventMetricsMeter(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); + } + } + } + + private static void MapEventMetricsMeter(EventMetricsMeter obj, string valueName, string separator, IDictionary map) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.MeterName, FormattableString.Invariant($"{prefix}{nameof(obj.MeterName)}"), map); + MapArray_String(obj.InstrumentNames, FormattableString.Invariant($"{prefix}{nameof(obj.InstrumentNames)}"), separator, map); + } + private static void MapCollectTraceOptions(CollectTraceOptions? obj, string valueName, string separator, IDictionary map) { if (null != obj) @@ -267,6 +394,54 @@ private static void MapCollectTraceOptions(CollectTraceOptions? obj, string valu } } + private static void MapExecuteOptions(ExecuteOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Path, FormattableString.Invariant($"{prefix}{nameof(obj.Path)}"), map); + MapString(obj.Arguments, FormattableString.Invariant($"{prefix}{nameof(obj.Arguments)}"), map); + MapBool(obj.IgnoreExitCode, FormattableString.Invariant($"{prefix}{nameof(obj.IgnoreExitCode)}"), map); + } + } + + private static void MapLoadProfilerOptions(LoadProfilerOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Path, FormattableString.Invariant($"{prefix}{nameof(obj.Path)}"), map); + MapGuid(obj.Clsid, FormattableString.Invariant($"{prefix}{nameof(obj.Clsid)}"), map); + } + } + + private static void MapGuid(Guid? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + + private static void MapSetEnvironmentVariableOptions(SetEnvironmentVariableOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Name, FormattableString.Invariant($"{prefix}{nameof(obj.Name)}"), map); + MapString(obj.Value, FormattableString.Invariant($"{prefix}{nameof(obj.Value)}"), map); + } + } + + private static void MapGetEnvironmentVariableOptions(GetEnvironmentVariableOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Name, FormattableString.Invariant($"{prefix}{nameof(obj.Name)}"), map); + } + } + private static void MapTraceProfile(TraceProfile? value, string valueName, IDictionary map) { if (null != value) From 142a8c112e9f259243f4ca2fa7498761212ac5f0 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 16 Apr 2025 22:46:27 +0000 Subject: [PATCH 126/174] Fix more test failures --- .../CollectTraceActionTests.cs | 3 +- .../LoadProfilerActionTests.cs | 2 +- .../TestValidatableType.cs | 4 + .../ValidatableInfoResolver.cs | 89 +++++++++++++++++-- 4 files changed, 89 insertions(+), 9 deletions(-) diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs index 82718eaaa7c..143bea859bb 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs @@ -80,7 +80,8 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => options.Duration = TimeSpan.FromSeconds(2); }) .SetStartupTrigger(); - }, host => PerformTrace(host, tfm)); + }, host => PerformTrace(host, tfm), + TestValidatableTypes.AddValidation); } [Fact] diff --git a/src/Tests/CollectionRuleActions.UnitTests/LoadProfilerActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/LoadProfilerActionTests.cs index 5e1a35c2fb9..0e91544c104 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/LoadProfilerActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/LoadProfilerActionTests.cs @@ -73,7 +73,7 @@ await runner.ExecuteAsync(async () => await runner.SendCommandAsync(TestAppScenarios.AsyncWait.Commands.Continue); }); - }); + }, TestValidatableTypes.AddValidation); } /// diff --git a/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs b/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs index f8d61c51864..bf2e597118b 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs @@ -38,6 +38,10 @@ internal sealed class TestValidatableTypes public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } + public required CollectDumpOptions CollectDumpOptions { get; init; } + + public required LoadProfilerOptions LoadProfilerOptions { get; init; } + public static void AddValidation(IServiceCollection services) { GeneratedServiceCollectionExtensions.AddValidation(services); diff --git a/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs b/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs index dc9b5c63042..fd8af954f48 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs @@ -294,6 +294,16 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateFileSystemEgressProviderOptions(); return true; } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions)) + { + validatableInfo = CreateCollectDumpOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions)) + { + validatableInfo = CreateLoadProfilerOptions(); + return true; + } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes)) { validatableInfo = CreateTestValidatableTypes(); @@ -717,12 +727,13 @@ private ValidatableTypeInfo CreateGuid() return new GeneratedValidatableTypeInfo( type: typeof(global::System.Guid), members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Guid), - propertyType: typeof(global::System.Guid), - name: "AllBitsSet", - displayName: "AllBitsSet" - ), + // https://github.com/dotnet/aspnetcore/issues/61525 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::System.Guid), + // propertyType: typeof(global::System.Guid), + // name: "AllBitsSet", + // displayName: "AllBitsSet" + // ), ] ); } @@ -1500,6 +1511,58 @@ private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() ] ); } + private ValidatableTypeInfo CreateCollectDumpOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.DumpType?), + name: "Type", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateLoadProfilerOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + propertyType: typeof(string), + name: "Path", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + propertyType: typeof(global::System.Guid), + name: "Clsid", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } private ValidatableTypeInfo CreateTestValidatableTypes() { return new GeneratedValidatableTypeInfo( @@ -1565,6 +1628,18 @@ private ValidatableTypeInfo CreateTestValidatableTypes() name: "FileSystemEgressProviderOptions", displayName: "FileSystemEgressProviderOptions" ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + name: "CollectDumpOptions", + displayName: "CollectDumpOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + name: "LoadProfilerOptions", + displayName: "LoadProfilerOptions" + ), ] ); } @@ -1574,7 +1649,7 @@ private ValidatableTypeInfo CreateTestValidatableTypes() [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] internal static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "o12abVmqqV0zqGgiPVl+aU9UAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "tmDjl/scvJBp7h4Jis0nT+NkAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. From 04aed2fd27051f7546e5b89380bcfd79dc63a948 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 18 Apr 2025 18:10:12 +0000 Subject: [PATCH 127/174] Use separate action descriptor types --- .../ActionListExecutorTests.cs | 2 +- .../ActionsServiceCollectionExtensions.cs | 4 +-- .../CollectionRules/Actions/CallbackAction.cs | 15 +++++++++++ .../Actions/PassThroughAction.cs | 9 +++++++ .../ActionDependencyAnalyzerTests.cs | 12 ++++----- .../Actions/CollectDumpAction.cs | 8 ++++++ .../Actions/CollectExceptionsAction.cs | 8 ++++++ .../Actions/CollectGCDumpAction.cs | 8 ++++++ .../Actions/CollectLiveMetricsAction.cs | 8 ++++++ .../Actions/CollectLogsAction.cs | 8 ++++++ .../Actions/CollectStacksAction.cs | 8 ++++++ .../Actions/CollectTraceAction.cs | 8 ++++++ .../CollectionRules/Actions/ExecuteAction.cs | 8 ++++++ .../Actions/GetEnvironmentVariableAction.cs | 8 ++++++ .../Actions/LoadProfilerAction.cs | 8 ++++++ .../Actions/SetEnvironmentVariableAction.cs | 8 ++++++ .../CollectionRuleActionDescriptor.cs | 24 ----------------- .../ServiceCollectionExtensions.cs | 27 ++++++++++--------- 18 files changed, 135 insertions(+), 46 deletions(-) delete mode 100644 src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleActionDescriptor.cs diff --git a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs index 417612e9baa..be6564186dd 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs @@ -186,7 +186,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => Assert.Throws(() => host.Services.GetRequiredService>().Get(DefaultRuleName)); }, serviceCollection => { - serviceCollection.RegisterCollectionRuleAction(nameof(PassThroughAction)); + serviceCollection.RegisterCollectionRuleAction(); }); } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/ActionsServiceCollectionExtensions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/ActionsServiceCollectionExtensions.cs index 488893a7f6d..5ffb31ba8e1 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/ActionsServiceCollectionExtensions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/ActionsServiceCollectionExtensions.cs @@ -14,7 +14,7 @@ internal static class ActionsServiceCollectionExtensions public static IServiceCollection RegisterTestAction(this IServiceCollection services, CallbackActionService callback) { services.AddSingleton(callback); - services.RegisterCollectionRuleAction(CallbackAction.ActionName); + services.RegisterCollectionRuleAction(); return services; } @@ -22,7 +22,7 @@ public static IServiceCollection RegisterTestAction(this IServiceCollection serv public static IServiceCollection RegisterDelayedTestAction(this IServiceCollection services, CallbackActionService callback) { services.AddSingleton(callback); - services.RegisterCollectionRuleAction(DelayedCallbackAction.ActionName); + services.RegisterCollectionRuleAction(); return services; } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/CallbackAction.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/CallbackAction.cs index d3fa485312b..9ab847a8ee8 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/CallbackAction.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/CallbackAction.cs @@ -3,6 +3,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using System; using System.Collections.Generic; @@ -73,6 +74,13 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, BaseRecordOptions } } + internal sealed class CallbackActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => CallbackAction.ActionName; + public Type OptionsType => typeof(BaseRecordOptions); + public Type FactoryType => typeof(CallbackActionFactory); + } + internal sealed class DelayedCallbackAction : ICollectionRuleAction { public const string ActionName = nameof(DelayedCallbackAction); @@ -111,6 +119,13 @@ public Task WaitForCompletionAsync(CancellationToken } } + internal sealed class DelayedCallbackActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => DelayedCallbackAction.ActionName; + public Type OptionsType => typeof(BaseRecordOptions); + public Type FactoryType => typeof(DelayedCallbackActionFactory); + } + internal sealed class CallbackActionService { public TimeProvider TimeProvider { get; } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/PassThroughAction.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/PassThroughAction.cs index 182df3dfb90..d5bd00da1e7 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/PassThroughAction.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/PassThroughAction.cs @@ -3,7 +3,9 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -53,6 +55,13 @@ public Task WaitForCompletionAsync(CancellationToken } } + internal sealed class PassThroughActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => nameof(PassThroughAction); + public Type OptionsType => typeof(PassThroughOptions); + public Type FactoryType => typeof(PassThroughActionFactory); + } + internal sealed record class PassThroughOptions : BaseRecordOptions { [ActionOptionsDependencyProperty] diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs index 003a036ec8f..5e55d62eecf 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs @@ -135,7 +135,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => Assert.Equal("Output a1input3 trail", a2output3); }, serviceCollection => { - serviceCollection.RegisterCollectionRuleAction(nameof(PassThroughAction)); + serviceCollection.RegisterCollectionRuleAction(); }); } @@ -174,7 +174,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { - serviceCollection.RegisterCollectionRuleAction(nameof(PassThroughAction)); + serviceCollection.RegisterCollectionRuleAction(); }); } @@ -211,7 +211,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.AddSingleton(); - serviceCollection.RegisterCollectionRuleAction(nameof(PassThroughAction)); + serviceCollection.RegisterCollectionRuleAction(); }); } @@ -254,7 +254,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { - serviceCollection.RegisterCollectionRuleAction(nameof(PassThroughAction)); + serviceCollection.RegisterCollectionRuleAction(); }, loggingBuilder => { loggingBuilder.AddProvider(new TestLoggerProvider(record)); @@ -290,7 +290,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { - serviceCollection.RegisterCollectionRuleAction(nameof(PassThroughAction)); + serviceCollection.RegisterCollectionRuleAction(); }); } @@ -352,7 +352,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => Assert.Equal("Output a1input3 trail", a2output3); }, serviceCollection => { - serviceCollection.RegisterCollectionRuleAction(nameof(PassThroughAction)); + serviceCollection.RegisterCollectionRuleAction(); }); } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs index ac740410b20..706816008f6 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs @@ -3,6 +3,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.DependencyInjection; using System; @@ -66,4 +67,11 @@ protected override EgressOperation CreateArtifactOperation(CollectionRuleMetadat } } } + + internal sealed class CollectDumpActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => KnownCollectionRuleActions.CollectDump; + public Type FactoryType => typeof(CollectDumpActionFactory); + public Type OptionsType => typeof(CollectDumpOptions); + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs index efc8f2150ce..0cc81f403be 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs @@ -3,6 +3,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; using System; using System.ComponentModel.DataAnnotations; @@ -55,4 +56,11 @@ protected override EgressOperation CreateArtifactOperation(CollectionRuleMetadat return egressOperation; } } + + internal sealed class CollectExceptionsActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => KnownCollectionRuleActions.CollectExceptions; + public Type FactoryType => typeof(CollectExceptionsActionFactory); + public Type OptionsType => typeof(CollectExceptionsOptions); + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs index 21157f86952..67941439175 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs @@ -7,6 +7,7 @@ using System; using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions { @@ -59,4 +60,11 @@ protected override EgressOperation CreateArtifactOperation(CollectionRuleMetadat } } } + + internal sealed class CollectGCDumpActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => KnownCollectionRuleActions.CollectGCDump; + public Type FactoryType => typeof(CollectGCDumpActionFactory); + public Type OptionsType => typeof(CollectGCDumpOptions); + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs index 9ba039edc59..4c95de29d10 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; @@ -95,4 +96,11 @@ protected override EgressOperation CreateArtifactOperation(CollectionRuleMetadat } } } + + internal sealed class CollectLiveMetricsActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => KnownCollectionRuleActions.CollectLiveMetrics; + public Type FactoryType => typeof(CollectLiveMetricsActionFactory); + public Type OptionsType => typeof(CollectLiveMetricsOptions); + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs index 41546ca8182..7e2408a3e40 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Monitoring.Options; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; @@ -83,4 +84,11 @@ protected override EgressOperation CreateArtifactOperation(CollectionRuleMetadat } } } + + internal sealed class CollectLogsActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => KnownCollectionRuleActions.CollectLogs; + public Type FactoryType => typeof(CollectLogsActionFactory); + public Type OptionsType => typeof(CollectLogsOptions); + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs index 5c9c53c2d67..0a77c7064dd 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs @@ -3,6 +3,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; using System; using System.ComponentModel.DataAnnotations; @@ -71,4 +72,11 @@ private static StackFormat MapCallStackFormat(CallStackFormat format) => _ => throw new InvalidOperationException() }; } + + internal sealed class CollectStacksActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => KnownCollectionRuleActions.CollectStacks; + public Type FactoryType => typeof(CollectStacksActionFactory); + public Type OptionsType => typeof(CollectStacksOptions); + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs index cd5d6c1540c..0f0f00613d6 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; @@ -107,4 +108,11 @@ protected override EgressOperation CreateArtifactOperation(CollectionRuleMetadat } } } + + internal sealed class CollectTraceActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => KnownCollectionRuleActions.CollectTrace; + public Type FactoryType => typeof(CollectTraceActionFactory); + public Type OptionsType => typeof(CollectTraceOptions); + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs index eb77d0c0926..f21ee2f7a9d 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs @@ -4,6 +4,7 @@ using Microsoft.Diagnostics.Monitoring.EventPipe; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -105,4 +106,11 @@ internal static void ValidateExitCode(bool ignoreExitCode, int exitCode) } } } + + internal sealed class ExecuteActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => KnownCollectionRuleActions.Execute; + public Type FactoryType => typeof(ExecuteActionFactory); + public Type OptionsType => typeof(ExecuteOptions); + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs index a75d576916b..662cbbb6176 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs @@ -3,6 +3,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.NETCore.Client; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.Logging; using System; @@ -83,4 +84,11 @@ protected override async Task ExecuteCoreAsync( } } } + + internal sealed class GetEnvironmentVariableActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => KnownCollectionRuleActions.GetEnvironmentVariable; + public Type OptionsType => typeof(GetEnvironmentVariableOptions); + public Type FactoryType => typeof(GetEnvironmentVariableActionFactory); + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs index d3338bd8520..c5a0e5a384e 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs @@ -4,6 +4,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.NETCore.Client; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Logging; using System; using System.ComponentModel.DataAnnotations; @@ -68,4 +69,11 @@ protected override async Task ExecuteCoreAsync( } } } + + internal sealed class LoadProfilerActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => KnownCollectionRuleActions.LoadProfiler; + public Type FactoryType => typeof(LoadProfilerActionFactory); + public Type OptionsType => typeof(LoadProfilerOptions); + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs index edd4298089c..c64bf229317 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs @@ -4,6 +4,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.NETCore.Client; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Logging; using System; using System.ComponentModel.DataAnnotations; @@ -68,4 +69,11 @@ protected override async Task ExecuteCoreAsync( } } } + + internal sealed class SetEnvironmentVariableActionDescriptor : ICollectionRuleActionDescriptor + { + public string ActionName => KnownCollectionRuleActions.SetEnvironmentVariable; + public Type FactoryType => typeof(SetEnvironmentVariableActionFactory); + public Type OptionsType => typeof(SetEnvironmentVariableOptions); + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleActionDescriptor.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleActionDescriptor.cs deleted file mode 100644 index b032176db15..00000000000 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleActionDescriptor.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; -using System; - -namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration -{ - internal sealed class CollectionRuleActionDescriptor : - ICollectionRuleActionDescriptor - where TFactory : ICollectionRuleActionFactory - { - public CollectionRuleActionDescriptor(string actionName) - { - ActionName = actionName; - } - - public string ActionName { get; } - - public Type FactoryType => typeof(TFactory); - - public Type OptionsType => typeof(TOptions); - } -} diff --git a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs index 2a3683477b6..898612024d4 100644 --- a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs +++ b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs @@ -140,17 +140,17 @@ public static AuthenticationBuilder ConfigureMonitorApiKeyAuthentication(this IS public static IServiceCollection ConfigureCollectionRules(this IServiceCollection services) { - services.RegisterCollectionRuleAction(KnownCollectionRuleActions.CollectDump); - services.RegisterCollectionRuleAction(KnownCollectionRuleActions.CollectExceptions); - services.RegisterCollectionRuleAction(KnownCollectionRuleActions.CollectGCDump); - services.RegisterCollectionRuleAction(KnownCollectionRuleActions.CollectLiveMetrics); - services.RegisterCollectionRuleAction(KnownCollectionRuleActions.CollectLogs); - services.RegisterCollectionRuleAction(KnownCollectionRuleActions.CollectStacks); - services.RegisterCollectionRuleAction(KnownCollectionRuleActions.CollectTrace); - services.RegisterCollectionRuleAction(KnownCollectionRuleActions.Execute); - services.RegisterCollectionRuleAction(KnownCollectionRuleActions.LoadProfiler); - services.RegisterCollectionRuleAction(KnownCollectionRuleActions.SetEnvironmentVariable); - services.RegisterCollectionRuleAction(KnownCollectionRuleActions.GetEnvironmentVariable); + services.RegisterCollectionRuleAction(); + services.RegisterCollectionRuleAction(); + services.RegisterCollectionRuleAction(); + services.RegisterCollectionRuleAction(); + services.RegisterCollectionRuleAction(); + services.RegisterCollectionRuleAction(); + services.RegisterCollectionRuleAction(); + services.RegisterCollectionRuleAction(); + services.RegisterCollectionRuleAction(); + services.RegisterCollectionRuleAction(); + services.RegisterCollectionRuleAction(); services.RegisterCollectionRuleTrigger(KnownCollectionRuleTriggers.AspNetRequestCount); services.RegisterCollectionRuleTrigger(KnownCollectionRuleTriggers.AspNetRequestDuration); @@ -196,13 +196,14 @@ public static IServiceCollection ConfigureCollectionRules(this IServiceCollectio return services; } - public static IServiceCollection RegisterCollectionRuleAction(this IServiceCollection services, string actionName) + public static IServiceCollection RegisterCollectionRuleAction(this IServiceCollection services) where TFactory : class, ICollectionRuleActionFactory where TOptions : BaseRecordOptions, new() + where TDescriptor : class, ICollectionRuleActionDescriptor, new() { services.AddSingleton(); services.AddSingleton>(); - services.AddSingleton>(sp => new CollectionRuleActionDescriptor(actionName)); + services.AddSingleton(sp => new TDescriptor()); // NOTE: When opening collection rule actions for extensibility, this should not be added for all registered actions. // Each action should register its own IValidateOptions<> implementation (if it needs one). services.AddSingleton, DataAnnotationValidateOptions>(); From 65f601ac71b5736ae1e463cf438953fcdb046107 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 18 Apr 2025 18:30:15 +0000 Subject: [PATCH 128/174] Move BindOptions to action descriptors --- .../CollectionRules/Actions/CallbackAction.cs | 15 +++++++++++++++ .../CollectionRules/Actions/PassThroughAction.cs | 8 ++++++++ .../CollectionRules/Actions/CollectDumpAction.cs | 8 ++++++++ .../Actions/CollectExceptionsAction.cs | 8 ++++++++ .../Actions/CollectGCDumpAction.cs | 8 ++++++++ .../Actions/CollectLiveMetricsAction.cs | 8 ++++++++ .../CollectionRules/Actions/CollectLogsAction.cs | 8 ++++++++ .../Actions/CollectStacksAction.cs | 8 ++++++++ .../CollectionRules/Actions/CollectTraceAction.cs | 8 ++++++++ .../Actions/CollectionRuleActionOperations.cs | 7 +++++-- .../CollectionRules/Actions/ExecuteAction.cs | 8 ++++++++ .../Actions/GetEnvironmentVariableAction.cs | 8 ++++++++ .../Actions/ICollectionRuleActionOperations.cs | 4 +++- .../CollectionRules/Actions/LoadProfilerAction.cs | 8 ++++++++ .../Actions/SetEnvironmentVariableAction.cs | 8 ++++++++ .../Configuration/CollectionRuleBindingHelper.cs | 6 +----- .../ICollectionRuleActionDescriptor.cs | 3 +++ 17 files changed, 123 insertions(+), 8 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/CallbackAction.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/CallbackAction.cs index 9ab847a8ee8..4e2c28bfc82 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/CallbackAction.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/CallbackAction.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.Threading; @@ -79,6 +80,13 @@ internal sealed class CallbackActionDescriptor : ICollectionRuleActionDescriptor public string ActionName => CallbackAction.ActionName; public Type OptionsType => typeof(BaseRecordOptions); public Type FactoryType => typeof(CallbackActionFactory); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + BaseRecordOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } internal sealed class DelayedCallbackAction : ICollectionRuleAction @@ -124,6 +132,13 @@ internal sealed class DelayedCallbackActionDescriptor : ICollectionRuleActionDes public string ActionName => DelayedCallbackAction.ActionName; public Type OptionsType => typeof(BaseRecordOptions); public Type FactoryType => typeof(DelayedCallbackActionFactory); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + BaseRecordOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } internal sealed class CallbackActionService diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/PassThroughAction.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/PassThroughAction.cs index d5bd00da1e7..f8b350b6bda 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/PassThroughAction.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CollectionRules/Actions/PassThroughAction.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.Threading; @@ -60,6 +61,13 @@ internal sealed class PassThroughActionDescriptor : ICollectionRuleActionDescrip public string ActionName => nameof(PassThroughAction); public Type OptionsType => typeof(PassThroughOptions); public Type FactoryType => typeof(PassThroughActionFactory); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + PassThroughOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } internal sealed record class PassThroughOptions : BaseRecordOptions diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs index 706816008f6..e4a3debe39a 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; using System.ComponentModel.DataAnnotations; @@ -73,5 +74,12 @@ internal sealed class CollectDumpActionDescriptor : ICollectionRuleActionDescrip public string ActionName => KnownCollectionRuleActions.CollectDump; public Type FactoryType => typeof(CollectDumpActionFactory); public Type OptionsType => typeof(CollectDumpOptions); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + CollectDumpOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs index 0cc81f403be..f9156e83d77 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Configuration; using System; using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; @@ -62,5 +63,12 @@ internal sealed class CollectExceptionsActionDescriptor : ICollectionRuleActionD public string ActionName => KnownCollectionRuleActions.CollectExceptions; public Type FactoryType => typeof(CollectExceptionsActionFactory); public Type OptionsType => typeof(CollectExceptionsOptions); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + CollectExceptionsOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs index 67941439175..b2ab4445160 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs @@ -3,6 +3,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; using System.ComponentModel.DataAnnotations; @@ -66,5 +67,12 @@ internal sealed class CollectGCDumpActionDescriptor : ICollectionRuleActionDescr public string ActionName => KnownCollectionRuleActions.CollectGCDump; public Type FactoryType => typeof(CollectGCDumpActionFactory); public Type OptionsType => typeof(CollectGCDumpOptions); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + CollectGCDumpOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs index 4c95de29d10..26200990c76 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs @@ -6,6 +6,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; @@ -102,5 +103,12 @@ internal sealed class CollectLiveMetricsActionDescriptor : ICollectionRuleAction public string ActionName => KnownCollectionRuleActions.CollectLiveMetrics; public Type FactoryType => typeof(CollectLiveMetricsActionFactory); public Type OptionsType => typeof(CollectLiveMetricsOptions); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + CollectLiveMetricsOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs index 7e2408a3e40..c76deac2531 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs @@ -8,6 +8,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -90,5 +91,12 @@ internal sealed class CollectLogsActionDescriptor : ICollectionRuleActionDescrip public string ActionName => KnownCollectionRuleActions.CollectLogs; public Type FactoryType => typeof(CollectLogsActionFactory); public Type OptionsType => typeof(CollectLogsOptions); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + CollectLogsOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs index 0a77c7064dd..8001d0e99d7 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Configuration; using System; using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; @@ -78,5 +79,12 @@ internal sealed class CollectStacksActionDescriptor : ICollectionRuleActionDescr public string ActionName => KnownCollectionRuleActions.CollectStacks; public Type FactoryType => typeof(CollectStacksActionFactory); public Type OptionsType => typeof(CollectStacksOptions); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + CollectStacksOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs index 0f0f00613d6..92b7f9c43f4 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs @@ -8,6 +8,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Microsoft.Extensions.Configuration; using System; using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; @@ -114,5 +115,12 @@ internal sealed class CollectTraceActionDescriptor : ICollectionRuleActionDescri public string ActionName => KnownCollectionRuleActions.CollectTrace; public Type FactoryType => typeof(CollectTraceActionFactory); public Type OptionsType => typeof(CollectTraceOptions); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + CollectTraceOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs index aea65cae497..746af4f906a 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -59,13 +60,15 @@ public bool TryCreateFactory( } /// - public bool TryCreateOptions( + public bool TryBindOptions( string actionName, + IConfigurationSection actionSection, out object options) { if (_map.TryGetValue(actionName, out ICollectionRuleActionDescriptor descriptor)) { - options = Activator.CreateInstance(descriptor.OptionsType); + IConfigurationSection settingsSection = actionSection.GetSection(nameof(CollectionRuleActionOptions.Settings)); + descriptor.BindOptions(settingsSection, out options); return true; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs index f21ee2f7a9d..000120179a0 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; +using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -112,5 +113,12 @@ internal sealed class ExecuteActionDescriptor : ICollectionRuleActionDescriptor public string ActionName => KnownCollectionRuleActions.Execute; public Type FactoryType => typeof(ExecuteActionFactory); public Type OptionsType => typeof(ExecuteOptions); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + ExecuteOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs index 662cbbb6176..b7a8fe7d44f 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs @@ -6,6 +6,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -90,5 +91,12 @@ internal sealed class GetEnvironmentVariableActionDescriptor : ICollectionRuleAc public string ActionName => KnownCollectionRuleActions.GetEnvironmentVariable; public Type OptionsType => typeof(GetEnvironmentVariableOptions); public Type FactoryType => typeof(GetEnvironmentVariableActionFactory); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + GetEnvironmentVariableOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs index e6168312093..21260ebccb2 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs @@ -3,6 +3,7 @@ #nullable disable +using Microsoft.Extensions.Configuration; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -25,8 +26,9 @@ bool TryCreateFactory( /// Attempts to create an options instance of the options type /// associated with the registered action name. /// - bool TryCreateOptions( + bool TryBindOptions( string actionName, + IConfigurationSection actionSection, out object options); /// diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs index c5a0e5a384e..7f9770c9428 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs @@ -6,6 +6,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; using System; using System.ComponentModel.DataAnnotations; using System.Threading; @@ -75,5 +76,12 @@ internal sealed class LoadProfilerActionDescriptor : ICollectionRuleActionDescri public string ActionName => KnownCollectionRuleActions.LoadProfiler; public Type FactoryType => typeof(LoadProfilerActionFactory); public Type OptionsType => typeof(LoadProfilerOptions); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + LoadProfilerOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs index c64bf229317..b40b78a4041 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs @@ -6,6 +6,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; using System; using System.ComponentModel.DataAnnotations; using System.Threading; @@ -75,5 +76,12 @@ internal sealed class SetEnvironmentVariableActionDescriptor : ICollectionRuleAc public string ActionName => KnownCollectionRuleActions.SetEnvironmentVariable; public Type FactoryType => typeof(SetEnvironmentVariableActionFactory); public Type OptionsType => typeof(SetEnvironmentVariableOptions); + + public void BindOptions(IConfigurationSection settingsSection, out object settings) + { + SetEnvironmentVariableOptions options = new(); + settingsSection.Bind(options); + settings = options; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs index 548c4bd3cc6..a549120d117 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs @@ -13,12 +13,8 @@ internal static class CollectionRuleBindingHelper public static void BindActionSettings(IConfigurationSection actionSection, CollectionRuleActionOptions actionOptions, ICollectionRuleActionOperations actionOperations) { if (null != actionOptions && - actionOperations.TryCreateOptions(actionOptions.Type, out object actionSettings)) + actionOperations.TryBindOptions(actionOptions.Type, actionSection, out object actionSettings)) { - IConfigurationSection settingsSection = actionSection.GetSection(nameof(CollectionRuleActionOptions.Settings)); - - settingsSection.Bind(actionSettings); - actionOptions.Settings = actionSettings; } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/ICollectionRuleActionDescriptor.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/ICollectionRuleActionDescriptor.cs index 9f31a727d10..561c005c697 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/ICollectionRuleActionDescriptor.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/ICollectionRuleActionDescriptor.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using Microsoft.Extensions.Configuration; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration { @@ -12,5 +13,7 @@ internal interface ICollectionRuleActionDescriptor Type FactoryType { get; } Type OptionsType { get; } + + void BindOptions(IConfigurationSection settingsSection, out object settings); } } From 0792fafce093cbc0dab1864890f6d637150b3545 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 18 Apr 2025 18:45:01 +0000 Subject: [PATCH 129/174] Use separate trigger descriptor types --- .../CollectionRules/Triggers/ManualTrigger.cs | 8 ++++ .../TriggersServiceCollectionExtensions.cs | 2 +- .../CollectionRuleTriggerDescriptor.cs | 40 ------------------- .../AspNetRequestCountTriggerFactory.cs | 8 ++++ .../AspNetRequestDurationTriggerFactory.cs | 8 ++++ .../AspNetResponseStatusTriggerFactory.cs | 8 ++++ .../Triggers/EventCounterTriggerFactory.cs | 8 ++++ .../Triggers/EventMeterTriggerFactory.cs | 8 ++++ .../Triggers/StartupTriggerFactory.cs | 8 ++++ .../ServiceCollectionExtensions.cs | 30 +++++++------- 10 files changed, 72 insertions(+), 56 deletions(-) delete mode 100644 src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleTriggerDescriptor.cs diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRules/Triggers/ManualTrigger.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRules/Triggers/ManualTrigger.cs index cce2bd81f53..8401663b704 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRules/Triggers/ManualTrigger.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRules/Triggers/ManualTrigger.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Triggers; using System; using System.Threading; @@ -59,6 +60,13 @@ private void NotifyHandler(object sender, EventArgs args) } } + internal sealed class ManualTriggerDescriptor : ICollectionRuleTriggerDescriptor + { + public string TriggerName => ManualTrigger.TriggerName; + public Type FactoryType => typeof(ManualTriggerFactory); + public Type OptionsType => null; + } + internal sealed class ManualTriggerService { public event EventHandler NotifyStarted; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRules/Triggers/TriggersServiceCollectionExtensions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRules/Triggers/TriggersServiceCollectionExtensions.cs index 6511462a1c9..17c3d961270 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRules/Triggers/TriggersServiceCollectionExtensions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRules/Triggers/TriggersServiceCollectionExtensions.cs @@ -11,7 +11,7 @@ internal static class TriggersServiceCollectionExtensions public static IServiceCollection RegisterManualTrigger(this IServiceCollection services, ManualTriggerService service) { services.AddSingleton(service); - return services.RegisterCollectionRuleTrigger(ManualTrigger.TriggerName); + return services.RegisterCollectionRuleTrigger(); } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleTriggerDescriptor.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleTriggerDescriptor.cs deleted file mode 100644 index ab9b7a87a82..00000000000 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleTriggerDescriptor.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Triggers; -using System; - -namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration -{ - internal sealed class CollectionRuleTriggerDescriptor : - ICollectionRuleTriggerDescriptor - where TFactory : ICollectionRuleTriggerFactory - { - public CollectionRuleTriggerDescriptor(string triggerName) - { - TriggerName = triggerName; - } - - public Type FactoryType => typeof(TFactory); - - public Type? OptionsType => null; - - public string TriggerName { get; } - } - - internal sealed class CollectionRuleTriggerProvider : - ICollectionRuleTriggerDescriptor - where TFactory : ICollectionRuleTriggerFactory - { - public CollectionRuleTriggerProvider(string triggerName) - { - TriggerName = triggerName; - } - - public Type FactoryType => typeof(TFactory); - - public Type OptionsType => typeof(TOptions); - - public string TriggerName { get; } - } -} diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestCountTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestCountTriggerFactory.cs index 25b4aa8e0d5..d43a121427b 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestCountTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestCountTriggerFactory.cs @@ -6,6 +6,7 @@ using Microsoft.Diagnostics.Monitoring.EventPipe.Triggers.AspNet; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using System; using System.Globalization; @@ -44,4 +45,11 @@ public ICollectionRuleTrigger Create(IEndpointInfo endpointInfo, Action callback return EventPipeTriggerFactory.Create(endpointInfo, aspnetTriggerSourceConfiguration, _traceEventTriggerFactory, settings, callback); } } + + internal sealed class AspNetRequestCountTriggerDescriptor : ICollectionRuleTriggerDescriptor + { + public Type FactoryType => typeof(AspNetRequestCountTriggerFactory); + public Type? OptionsType => typeof(AspNetRequestCountOptions); + public string TriggerName => KnownCollectionRuleTriggers.AspNetRequestCount; + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestDurationTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestDurationTriggerFactory.cs index 616862cf5ed..8d3a06fe652 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestDurationTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestDurationTriggerFactory.cs @@ -6,6 +6,7 @@ using Microsoft.Diagnostics.Monitoring.EventPipe.Triggers.AspNet; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Options; using System; using System.Globalization; @@ -50,4 +51,11 @@ public ICollectionRuleTrigger Create(IEndpointInfo endpointInfo, Action callback return EventPipeTriggerFactory.Create(endpointInfo, aspnetTriggerSourceConfiguration, _traceEventTriggerFactory, settings, callback); } } + + internal sealed class AspNetRequestDurationTriggerDescriptor : ICollectionRuleTriggerDescriptor + { + public Type FactoryType => typeof(AspNetRequestDurationTriggerFactory); + public Type? OptionsType => typeof(AspNetRequestDurationOptions); + public string TriggerName => KnownCollectionRuleTriggers.AspNetRequestDuration; + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetResponseStatusTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetResponseStatusTriggerFactory.cs index 4ab82c90c34..d71c2502df8 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetResponseStatusTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetResponseStatusTriggerFactory.cs @@ -6,6 +6,7 @@ using Microsoft.Diagnostics.Monitoring.EventPipe.Triggers.AspNet; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using System; using System.Globalization; using System.Linq; @@ -59,4 +60,11 @@ private static StatusCodeRange ParseRange(string range) return new StatusCodeRange(min, max); } } + + internal sealed class AspNetResponseStatusTriggerDescriptor : ICollectionRuleTriggerDescriptor + { + public Type FactoryType => typeof(AspNetResponseStatusTriggerFactory); + public Type? OptionsType => typeof(AspNetResponseStatusOptions); + public string TriggerName => KnownCollectionRuleTriggers.AspNetResponseStatus; + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs index 309bfa90933..565d2d254db 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs @@ -6,6 +6,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Options; using System; @@ -109,4 +110,11 @@ internal static EventCounterOptions ToEventCounterOptions(IEventCounterShortcuts }; } } + + internal sealed class EventCounterTriggerDescriptor : ICollectionRuleTriggerDescriptor + { + public Type FactoryType => typeof(EventCounterTriggerFactory); + public Type? OptionsType => typeof(EventCounterOptions); + public string TriggerName => KnownCollectionRuleTriggers.EventCounter; + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventMeterTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventMeterTriggerFactory.cs index 46502ad63b5..9f813ffda64 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventMeterTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventMeterTriggerFactory.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Monitoring.EventPipe.Triggers.SystemDiagnosticsMetrics; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Options; using System; @@ -55,4 +56,11 @@ public ICollectionRuleTrigger Create(IEndpointInfo endpointInfo, Action callback callback); } } + + internal sealed class EventMeterTriggerDescriptor : ICollectionRuleTriggerDescriptor + { + public Type FactoryType => typeof(EventMeterTriggerFactory); + public Type? OptionsType => typeof(EventMeterOptions); + public string TriggerName => KnownCollectionRuleTriggers.EventMeter; + } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/StartupTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/StartupTriggerFactory.cs index c17ad90fc7c..84a0141df4a 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/StartupTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/StartupTriggerFactory.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using System; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Triggers @@ -18,4 +19,11 @@ public ICollectionRuleTrigger Create(IEndpointInfo endpointInfo, Action callback return new StartupTrigger(callback); } } + + internal sealed class StartupTriggerDescriptor : ICollectionRuleTriggerDescriptor + { + public Type FactoryType => typeof(StartupTriggerFactory); + public Type? OptionsType => null; + public string TriggerName => KnownCollectionRuleTriggers.Startup; + } } diff --git a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs index 898612024d4..233c8420bde 100644 --- a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs +++ b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs @@ -152,15 +152,15 @@ public static IServiceCollection ConfigureCollectionRules(this IServiceCollectio services.RegisterCollectionRuleAction(); services.RegisterCollectionRuleAction(); - services.RegisterCollectionRuleTrigger(KnownCollectionRuleTriggers.AspNetRequestCount); - services.RegisterCollectionRuleTrigger(KnownCollectionRuleTriggers.AspNetRequestDuration); - services.RegisterCollectionRuleTrigger(KnownCollectionRuleTriggers.AspNetResponseStatus); - services.RegisterCollectionRuleTrigger(KnownCollectionRuleTriggers.EventCounter); - services.RegisterCollectionRuleTrigger(KnownCollectionRuleTriggers.CPUUsage); - services.RegisterCollectionRuleTrigger(KnownCollectionRuleTriggers.GCHeapSize); - services.RegisterCollectionRuleTrigger(KnownCollectionRuleTriggers.ThreadpoolQueueLength); - services.RegisterCollectionRuleTrigger(KnownCollectionRuleTriggers.Startup); - services.RegisterCollectionRuleTrigger(KnownCollectionRuleTriggers.EventMeter); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); services.AddSingleton(); services.AddSingleton, Monitoring.EventPipe.Triggers.EventCounter.EventCounterTriggerFactory>(); @@ -210,24 +210,24 @@ public static IServiceCollection RegisterCollectionRuleAction(this IServiceCollection services, string triggerName) + public static IServiceCollection RegisterCollectionRuleTrigger(this IServiceCollection services) where TFactory : class, ICollectionRuleTriggerFactory + where TDescriptor : class, ICollectionRuleTriggerDescriptor, new() { services.AddSingleton(); services.AddSingleton>(); - services.AddSingleton>( - sp => new CollectionRuleTriggerDescriptor(triggerName)); + services.AddSingleton(sp => new TDescriptor()); return services; } - public static IServiceCollection RegisterCollectionRuleTrigger(this IServiceCollection services, string triggerName) + public static IServiceCollection RegisterCollectionRuleTrigger(this IServiceCollection services) where TFactory : class, ICollectionRuleTriggerFactory where TOptions : class, new() + where TDescriptor : class, ICollectionRuleTriggerDescriptor, new() { services.AddSingleton(); services.AddSingleton>(); - services.AddSingleton>( - sp => new CollectionRuleTriggerProvider(triggerName)); + services.AddSingleton(sp => new TDescriptor()); // NOTE: When opening collection rule triggers for extensibility, this should not be added for all registered triggers. // Each trigger should register its own IValidateOptions<> implementation (if it needs one). services.AddSingleton, DataAnnotationValidateOptions>(); From 9120678357b2757cc9f90d0e1b32eae8aefa98f3 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 18 Apr 2025 19:00:40 +0000 Subject: [PATCH 130/174] Move binding to trigger descriptors --- .../CollectionRules/Triggers/ManualTrigger.cs | 7 +++++++ .../Actions/ICollectionRuleActionOperations.cs | 2 +- .../Configuration/CollectionRuleBindingHelper.cs | 6 +----- .../Configuration/ICollectionRuleActionDescriptor.cs | 2 +- .../Configuration/ICollectionRuleTriggerDescriptor.cs | 3 +++ .../Triggers/AspNetRequestCountTriggerFactory.cs | 9 +++++++++ .../Triggers/AspNetRequestDurationTriggerFactory.cs | 9 +++++++++ .../Triggers/AspNetResponseStatusTriggerFactory.cs | 9 +++++++++ .../Triggers/CollectionRuleTriggerOperations.cs | 11 ++++++----- .../Triggers/EventCounterTriggerFactory.cs | 9 +++++++++ .../Triggers/EventMeterTriggerFactory.cs | 9 +++++++++ .../Triggers/ICollectionRuleTriggerOperations.cs | 6 ++++-- .../CollectionRules/Triggers/StartupTriggerFactory.cs | 7 +++++++ 13 files changed, 75 insertions(+), 14 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRules/Triggers/ManualTrigger.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRules/Triggers/ManualTrigger.cs index 8401663b704..f02a2e1cde9 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRules/Triggers/ManualTrigger.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRules/Triggers/ManualTrigger.cs @@ -4,6 +4,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Triggers; +using Microsoft.Extensions.Configuration; using System; using System.Threading; using System.Threading.Tasks; @@ -65,6 +66,12 @@ internal sealed class ManualTriggerDescriptor : ICollectionRuleTriggerDescriptor public string TriggerName => ManualTrigger.TriggerName; public Type FactoryType => typeof(ManualTriggerFactory); public Type OptionsType => null; + + public bool TryBindOptions(IConfigurationSection settingsSection, out object settings) + { + settings = null; + return false; + } } internal sealed class ManualTriggerService diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs index 21260ebccb2..075f3195f0c 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs @@ -23,7 +23,7 @@ bool TryCreateFactory( out ICollectionRuleActionFactoryProxy action); /// - /// Attempts to create an options instance of the options type + /// Attempts to bind an options instance of the options type /// associated with the registered action name. /// bool TryBindOptions( diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs index a549120d117..7e4ec3aca29 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs @@ -22,12 +22,8 @@ public static void BindActionSettings(IConfigurationSection actionSection, Colle public static void BindTriggerSettings(IConfigurationSection triggerSection, CollectionRuleTriggerOptions triggerOptions, ICollectionRuleTriggerOperations triggerOperations) { if (null != triggerOptions && - triggerOperations.TryCreateOptions(triggerOptions.Type, out object triggerSettings)) + triggerOperations.TryBindOptions(triggerOptions.Type, triggerSection, out object triggerSettings)) { - IConfigurationSection settingsSection = triggerSection.GetSection(nameof(CollectionRuleTriggerOptions.Settings)); - - settingsSection.Bind(triggerSettings); - triggerOptions.Settings = triggerSettings; } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/ICollectionRuleActionDescriptor.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/ICollectionRuleActionDescriptor.cs index 561c005c697..7003561ffc7 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/ICollectionRuleActionDescriptor.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/ICollectionRuleActionDescriptor.cs @@ -1,8 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using Microsoft.Extensions.Configuration; +using System; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration { diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/ICollectionRuleTriggerDescriptor.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/ICollectionRuleTriggerDescriptor.cs index 48846c97c29..aa167eddc2a 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/ICollectionRuleTriggerDescriptor.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/ICollectionRuleTriggerDescriptor.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.Extensions.Configuration; using System; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration @@ -12,5 +13,7 @@ interface ICollectionRuleTriggerDescriptor Type? OptionsType { get; } string TriggerName { get; } + + bool TryBindOptions(IConfigurationSection settingsSection, out object? settings); } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestCountTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestCountTriggerFactory.cs index d43a121427b..21ba4514f99 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestCountTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestCountTriggerFactory.cs @@ -7,6 +7,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; +using Microsoft.Extensions.Configuration; using System; using System.Globalization; @@ -51,5 +52,13 @@ internal sealed class AspNetRequestCountTriggerDescriptor : ICollectionRuleTrigg public Type FactoryType => typeof(AspNetRequestCountTriggerFactory); public Type? OptionsType => typeof(AspNetRequestCountOptions); public string TriggerName => KnownCollectionRuleTriggers.AspNetRequestCount; + + public bool TryBindOptions(IConfigurationSection settingsSection, out object? settings) + { + var options = new AspNetRequestCountOptions(); + settingsSection.Bind(options); + settings = options; + return true; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestDurationTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestDurationTriggerFactory.cs index 8d3a06fe652..6df9c51a904 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestDurationTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetRequestDurationTriggerFactory.cs @@ -8,6 +8,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Options; +using Microsoft.Extensions.Configuration; using System; using System.Globalization; @@ -57,5 +58,13 @@ internal sealed class AspNetRequestDurationTriggerDescriptor : ICollectionRuleTr public Type FactoryType => typeof(AspNetRequestDurationTriggerFactory); public Type? OptionsType => typeof(AspNetRequestDurationOptions); public string TriggerName => KnownCollectionRuleTriggers.AspNetRequestDuration; + + public bool TryBindOptions(IConfigurationSection settingsSection, out object? settings) + { + var options = new AspNetRequestDurationOptions(); + settingsSection.Bind(options); + settings = options; + return true; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetResponseStatusTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetResponseStatusTriggerFactory.cs index d71c2502df8..b912e7e0411 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetResponseStatusTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/AspNetResponseStatusTriggerFactory.cs @@ -7,6 +7,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; +using Microsoft.Extensions.Configuration; using System; using System.Globalization; using System.Linq; @@ -66,5 +67,13 @@ internal sealed class AspNetResponseStatusTriggerDescriptor : ICollectionRuleTri public Type FactoryType => typeof(AspNetResponseStatusTriggerFactory); public Type? OptionsType => typeof(AspNetResponseStatusOptions); public string TriggerName => KnownCollectionRuleTriggers.AspNetResponseStatus; + + public bool TryBindOptions(IConfigurationSection settingsSection, out object? settings) + { + var options = new AspNetResponseStatusOptions(); + settingsSection.Bind(options); + settings = options; + return true; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs index 1b1dfac9460..efdf694c883 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs @@ -5,6 +5,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -71,16 +72,16 @@ public bool TryCreateFactory( } /// - public bool TryCreateOptions( + public bool TryBindOptions( string triggerName, + IConfigurationSection triggerSection, out object options) { // Check that the trigger is registered and has options - if (_map.TryGetValue(triggerName, out ICollectionRuleTriggerDescriptor descriptor) && - null != descriptor.OptionsType) + if (_map.TryGetValue(triggerName, out ICollectionRuleTriggerDescriptor descriptor)) { - options = Activator.CreateInstance(descriptor.OptionsType); - return true; + IConfigurationSection settingsSection = triggerSection.GetSection(nameof(CollectionRuleTriggerOptions.Settings)); + return descriptor.TryBindOptions(settingsSection, out options); } options = null; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs index 565d2d254db..6affc5f5cf1 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs @@ -8,6 +8,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Options; +using Microsoft.Extensions.Configuration; using System; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Triggers @@ -116,5 +117,13 @@ internal sealed class EventCounterTriggerDescriptor : ICollectionRuleTriggerDesc public Type FactoryType => typeof(EventCounterTriggerFactory); public Type? OptionsType => typeof(EventCounterOptions); public string TriggerName => KnownCollectionRuleTriggers.EventCounter; + + public bool TryBindOptions(IConfigurationSection settingsSection, out object? settings) + { + var options = new EventCounterOptions(); + settingsSection.Bind(options); + settings = options; + return true; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventMeterTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventMeterTriggerFactory.cs index 9f813ffda64..3453f845ee9 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventMeterTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventMeterTriggerFactory.cs @@ -7,6 +7,7 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Options; +using Microsoft.Extensions.Configuration; using System; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Triggers @@ -62,5 +63,13 @@ internal sealed class EventMeterTriggerDescriptor : ICollectionRuleTriggerDescri public Type FactoryType => typeof(EventMeterTriggerFactory); public Type? OptionsType => typeof(EventMeterOptions); public string TriggerName => KnownCollectionRuleTriggers.EventMeter; + + public bool TryBindOptions(IConfigurationSection settingsSection, out object? settings) + { + var options = new EventMeterOptions(); + settingsSection.Bind(options); + settings = options; + return true; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/ICollectionRuleTriggerOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/ICollectionRuleTriggerOperations.cs index 083adf8dd5d..610321cde6c 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/ICollectionRuleTriggerOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/ICollectionRuleTriggerOperations.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.Extensions.Configuration; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -20,11 +21,12 @@ bool TryCreateFactory( out ICollectionRuleTriggerFactoryProxy factory); /// - /// Attempts to create an options instance of the options type + /// Attempts to bind an options instance of the options type /// associated with the registered trigger name. /// - bool TryCreateOptions( + bool TryBindOptions( string triggerName, + IConfigurationSection triggerSection, out object options); /// diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/StartupTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/StartupTriggerFactory.cs index 84a0141df4a..f28fc8dfa60 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/StartupTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/StartupTriggerFactory.cs @@ -3,6 +3,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; +using Microsoft.Extensions.Configuration; using System; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Triggers @@ -25,5 +26,11 @@ internal sealed class StartupTriggerDescriptor : ICollectionRuleTriggerDescripto public Type FactoryType => typeof(StartupTriggerFactory); public Type? OptionsType => null; public string TriggerName => KnownCollectionRuleTriggers.Startup; + + public bool TryBindOptions(IConfigurationSection settingsSection, out object? settings) + { + settings = null; + return false; + } } } From 401f162fd2a735add22fb6ec64cde89c4c12dfdb Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 18 Apr 2025 20:27:58 +0000 Subject: [PATCH 131/174] Fix EventCounter descriptors --- .../Triggers/EventCounterTriggerFactory.cs | 45 +++++++++++++++++++ .../ServiceCollectionExtensions.cs | 18 ++++---- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs index 6affc5f5cf1..778b7d60a14 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/EventCounterTriggerFactory.cs @@ -126,4 +126,49 @@ public bool TryBindOptions(IConfigurationSection settingsSection, out object? se return true; } } + + internal sealed class CPUUsageTriggerDescriptor : ICollectionRuleTriggerDescriptor + { + public Type FactoryType => typeof(EventCounterTriggerFactory); + public Type? OptionsType => typeof(CPUUsageOptions); + public string TriggerName => KnownCollectionRuleTriggers.CPUUsage; + + public bool TryBindOptions(IConfigurationSection settingsSection, out object? settings) + { + var options = new CPUUsageOptions(); + settingsSection.Bind(options); + settings = options; + return true; + } + } + + internal sealed class GCHeapSizeTriggerDescriptor : ICollectionRuleTriggerDescriptor + { + public Type FactoryType => typeof(EventCounterTriggerFactory); + public Type? OptionsType => typeof(GCHeapSizeOptions); + public string TriggerName => KnownCollectionRuleTriggers.GCHeapSize; + + public bool TryBindOptions(IConfigurationSection settingsSection, out object? settings) + { + var options = new GCHeapSizeOptions(); + settingsSection.Bind(options); + settings = options; + return true; + } + } + + internal sealed class ThreadpoolQueueLengthTriggerDescriptor : ICollectionRuleTriggerDescriptor + { + public Type FactoryType => typeof(EventCounterTriggerFactory); + public Type? OptionsType => typeof(ThreadpoolQueueLengthOptions); + public string TriggerName => KnownCollectionRuleTriggers.ThreadpoolQueueLength; + + public bool TryBindOptions(IConfigurationSection settingsSection, out object? settings) + { + var options = new ThreadpoolQueueLengthOptions(); + settingsSection.Bind(options); + settings = options; + return true; + } + } } diff --git a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs index 233c8420bde..7c14cfc747e 100644 --- a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs +++ b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs @@ -152,15 +152,15 @@ public static IServiceCollection ConfigureCollectionRules(this IServiceCollectio services.RegisterCollectionRuleAction(); services.RegisterCollectionRuleAction(); - services.RegisterCollectionRuleTrigger(); - services.RegisterCollectionRuleTrigger(); - services.RegisterCollectionRuleTrigger(); - services.RegisterCollectionRuleTrigger(); - services.RegisterCollectionRuleTrigger(); - services.RegisterCollectionRuleTrigger(); - services.RegisterCollectionRuleTrigger(); - services.RegisterCollectionRuleTrigger(); - services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); + services.RegisterCollectionRuleTrigger(); services.AddSingleton(); services.AddSingleton, Monitoring.EventPipe.Triggers.EventCounter.EventCounterTriggerFactory>(); From 7010bbc0fa32b1129f5a364f573085138beaca82 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 18 Apr 2025 22:22:36 +0000 Subject: [PATCH 132/174] Fix more tests --- .../CollectionRuleDescriptionPipelineTests.cs | 3 + ...agnostics.Monitoring.Tool.UnitTests.csproj | 7 +++ ...CollectionRulePostConfigureNamedOptions.cs | 1 + .../dotnet-monitor/CommonOptionsMapper.cs | 56 ++++++++++++++++++- 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs index 895306ea951..ef52703ebb9 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs @@ -7,6 +7,8 @@ using Microsoft.Diagnostics.Monitoring.Tool.UnitTests.CollectionRules.Triggers; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor; +using Strings = Microsoft.Diagnostics.Monitoring.WebApi.Strings; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Extensions.DependencyInjection; @@ -337,6 +339,7 @@ public Task CollectionRuleDescriptionPipeline_ReachedRuleDuration(TargetFramewor { services.RegisterManualTrigger(triggerService); services.RegisterTestAction(callbackService); + TestValidatableTypes.AddValidation(services); }); } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj index a5c69515fa1..16f07d8a328 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj @@ -3,6 +3,7 @@ $(ToolTargetFrameworks) true + true @@ -189,4 +190,10 @@ + + + + + + diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs index a6a734fe77f..ef21189106a 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs @@ -64,6 +64,7 @@ private void ResolveActionList(CollectionRuleOptions ruleOptions, IConfiguration { CollectionRuleActionOptions actionOptions = new(); + actionSection.Bind(actionOptions); CollectionRuleBindingHelper.BindActionSettings(actionSection, actionOptions, _actionOperations); diff --git a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs index 43dde3011c7..93cd66267e0 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs @@ -149,10 +149,10 @@ private void MapDictionary_String_CollectionRuleOptions(IDictionary map) { string prefix = FormattableString.Invariant($"{valueName}{separator}"); - // MapFilters(obj.Filters, FormattableString.Invariant($"{prefix}{nameof(obj.Filters)}"), separator, map); + MapFilters(obj.Filters, FormattableString.Invariant($"{prefix}{nameof(obj.Filters)}"), separator, map); MapCollectionRuleTriggerOptions(obj.Trigger, FormattableString.Invariant($"{prefix}{nameof(obj.Trigger)}"), separator, map); MapActions(obj.Actions, FormattableString.Invariant($"{prefix}{nameof(obj.Actions)}"), separator, map); - // MapLimits(obj.Limits, FormattableString.Invariant($"{prefix}{nameof(obj.Limits)}"), separator, map); + MapLimits(obj.Limits, FormattableString.Invariant($"{prefix}{nameof(obj.Limits)}"), separator, map); } private void MapActions(List obj, string valueName, string separator, IDictionary map) @@ -238,6 +238,17 @@ private void MapCollectionRuleActionOptions_Settings(string type, object? settin } } + private static void MapLimits(CollectionRuleLimitsOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapInt(obj.ActionCount, FormattableString.Invariant($"{prefix}{nameof(obj.ActionCount)}"), map); + MapTimeSpan(obj.ActionCountSlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.ActionCountSlidingWindowDuration)}"), map); + MapTimeSpan(obj.RuleDuration, FormattableString.Invariant($"{prefix}{nameof(obj.RuleDuration)}"), map); + } + } + private static void MapCollectDumpOptions(CollectDumpOptions? obj, string valueName, string separator, IDictionary map) { if (null != obj) @@ -520,6 +531,47 @@ private static void MapDumpType(DumpType? value, string valueName, IDictionary? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + for (int index = 0; index < obj.Count; index++) + { + ProcessFilterDescriptor value = obj[index]; + MapProcessFilterDescriptor(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); + } + } + } + + private static void MapProcessFilterDescriptor(ProcessFilterDescriptor obj, string valueName, string separator, IDictionary map) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapProcessFilterKey(obj.Key, FormattableString.Invariant($"{prefix}{nameof(obj.Key)}"), map); + MapString(obj.Value, FormattableString.Invariant($"{prefix}{nameof(obj.Value)}"), map); + MapProcessFilterType(obj.MatchType, FormattableString.Invariant($"{prefix}{nameof(obj.MatchType)}"), map); + MapString(obj.ProcessName, FormattableString.Invariant($"{prefix}{nameof(obj.ProcessName)}"), map); + MapString(obj.ProcessId, FormattableString.Invariant($"{prefix}{nameof(obj.ProcessId)}"), map); + MapString(obj.CommandLine, FormattableString.Invariant($"{prefix}{nameof(obj.CommandLine)}"), map); + MapString(obj.ManagedEntryPointAssemblyName, FormattableString.Invariant($"{prefix}{nameof(obj.ManagedEntryPointAssemblyName)}"), map); + } + + private static void MapProcessFilterKey(ProcessFilterKey? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + + private static void MapProcessFilterType(ProcessFilterType? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + private static void MapCollectionRuleTriggerOptions(CollectionRuleTriggerOptions? obj, string valueName, string separator, IDictionary map) { if (null != obj) From 90ccf0cda4e58636adc624418b166ebb06cd9dd4 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 18 Apr 2025 22:48:31 +0000 Subject: [PATCH 133/174] Add validation type info --- .../TestValidatableTypes.cs | 51 + .../ValidatableInfoResolver.cs | 1689 +++++++++++++++++ 2 files changed, 1740 insertions(+) create mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/TestValidatableTypes.cs create mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ValidatableInfoResolver.cs diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/TestValidatableTypes.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/TestValidatableTypes.cs new file mode 100644 index 00000000000..a5fc49619c6 --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/TestValidatableTypes.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Http.Validation; +using Microsoft.AspNetCore.Http.Validation.Generated; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; + +namespace Microsoft.Diagnostics.Tools.Monitor +{ + // The Validation source generator doesn't run for libraries that don't call AddValidation, + // so we can't generate IValidatableInfo by using [ValidatableType] directly on types defined + // in ProjectReferences. This is a workaround to force the generator running in this project to + // generate IValidatableInfo for the referenced types. The containing class is not used otherwise. + [ValidatableType] + internal sealed class TestValidatableTypes + { + public required CollectionRuleOptions CollectionRuleOptions { get; init; } + + public required ExecuteOptions ExecuteOptions { get; init; } + + public required SetEnvironmentVariableOptions SetEnvironmentVariableOptions { get; init; } + + public required GetEnvironmentVariableOptions GetEnvironmentVariableOptions { get; init; } + + public required CollectTraceOptions CollectTraceOptions { get; init; } + + public required GlobalCounterOptions GlobalCounterOptions { get; init; } + + public required CollectGCDumpOptions CollectGCDumpOptions { get; init; } + + public required CollectLiveMetricsOptions CollectLiveMetricsOptions { get; init; } + + public required RootOptions RootOptions { get; init; } + + public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } + + public required CollectDumpOptions CollectDumpOptions { get; init; } + + public required LoadProfilerOptions LoadProfilerOptions { get; init; } + + public static void AddValidation(IServiceCollection services) + { + GeneratedServiceCollectionExtensions.AddValidation(services); + // services.AddValidation(); + } + } +} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ValidatableInfoResolver.cs new file mode 100644 index 00000000000..ae0af988787 --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ValidatableInfoResolver.cs @@ -0,0 +1,1689 @@ +#nullable enable annotations +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ +#nullable enable + +namespace System.Runtime.CompilerServices +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : System.Attribute + { + public InterceptsLocationAttribute(int version, string data) + { + } + } +} + +namespace Microsoft.AspNetCore.Http.Validation.Generated +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file sealed class GeneratedValidatablePropertyInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatablePropertyInfo + { + public GeneratedValidatablePropertyInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] + global::System.Type containingType, + global::System.Type propertyType, + string name, + string displayName) : base(containingType, propertyType, name, displayName) + { + ContainingType = containingType; + Name = name; + } + + internal global::System.Type ContainingType { get; } + internal string Name { get; } + + protected override global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes() + => ValidationAttributeCache.GetValidationAttributes(ContainingType, Name); + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file sealed class GeneratedValidatableTypeInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatableTypeInfo + { + public GeneratedValidatableTypeInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.Interfaces)] + global::System.Type type, + ValidatablePropertyInfo[] members) : base(type, members) { } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file class GeneratedValidatableInfoResolver : global::Microsoft.AspNetCore.Http.Validation.IValidatableInfoResolver + { + public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) + { + validatableInfo = null; + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions)) + { + validatableInfo = CreateCollectionRuleTriggerOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions)) + { + validatableInfo = CreateCollectionRuleActionOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions)) + { + validatableInfo = CreateCollectionRuleLimitsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions)) + { + validatableInfo = CreateCollectionRuleOptions(); + return true; + } + if (type == typeof(global::System.Reflection.MethodBase)) + { + validatableInfo = CreateMethodBase(); + return true; + } + if (type == typeof(global::System.Reflection.ConstructorInfo)) + { + validatableInfo = CreateConstructorInfo(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeTypedArgument)) + { + validatableInfo = CreateCustomAttributeTypedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeNamedArgument)) + { + validatableInfo = CreateCustomAttributeNamedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeData)) + { + validatableInfo = CreateCustomAttributeData(); + return true; + } + if (type == typeof(global::System.Reflection.ParameterInfo)) + { + validatableInfo = CreateParameterInfo(); + return true; + } + if (type == typeof(global::System.Reflection.MethodInfo)) + { + validatableInfo = CreateMethodInfo(); + return true; + } + if (type == typeof(global::System.Reflection.EventInfo)) + { + validatableInfo = CreateEventInfo(); + return true; + } + if (type == typeof(global::System.Reflection.FieldInfo)) + { + validatableInfo = CreateFieldInfo(); + return true; + } + if (type == typeof(global::System.Reflection.PropertyInfo)) + { + validatableInfo = CreatePropertyInfo(); + return true; + } + if (type == typeof(global::System.Reflection.TypeInfo)) + { + validatableInfo = CreateTypeInfo(); + return true; + } + if (type == typeof(global::System.Reflection.Assembly)) + { + validatableInfo = CreateAssembly(); + return true; + } + if (type == typeof(global::System.Guid)) + { + validatableInfo = CreateGuid(); + return true; + } + if (type == typeof(global::System.Reflection.Module)) + { + validatableInfo = CreateModule(); + return true; + } + if (type == typeof(global::System.Reflection.MemberInfo)) + { + validatableInfo = CreateMemberInfo(); + return true; + } + if (type == typeof(global::System.Type)) + { + validatableInfo = CreateType(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions)) + { + validatableInfo = CreateBaseRecordOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions)) + { + validatableInfo = CreateExecuteOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions)) + { + validatableInfo = CreateSetEnvironmentVariableOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions)) + { + validatableInfo = CreateGetEnvironmentVariableOptions(); + return true; + } + if (type == typeof(global::System.Collections.Generic.IDictionary)) + { + validatableInfo = CreateIDictionary_string_string(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter)) + { + validatableInfo = CreateTraceEventFilter(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions)) + { + validatableInfo = CreateCollectTraceOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions)) + { + validatableInfo = CreateGlobalCounterOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions)) + { + validatableInfo = CreateCollectGCDumpOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions)) + { + validatableInfo = CreateCollectLiveMetricsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions)) + { + validatableInfo = CreateMonitorApiKeyOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions)) + { + validatableInfo = CreateAzureAdOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions)) + { + validatableInfo = CreateAuthenticationOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration)) + { + validatableInfo = CreateExceptionsConfiguration(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions)) + { + validatableInfo = CreateExceptionsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions)) + { + validatableInfo = CreateInProcessFeaturesOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions)) + { + validatableInfo = CreateCorsConfigurationOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions)) + { + validatableInfo = CreateEgressOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider)) + { + validatableInfo = CreateMetricProvider(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions)) + { + validatableInfo = CreateMetricsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions)) + { + validatableInfo = CreateProcessFilterOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions)) + { + validatableInfo = CreateCollectionRuleTriggerDefaultsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions)) + { + validatableInfo = CreateCollectionRuleLimitsDefaultsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions)) + { + validatableInfo = CreateCollectionRuleDefaultsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions)) + { + validatableInfo = CreateTemplateOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions)) + { + validatableInfo = CreateRootOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions)) + { + validatableInfo = CreateFileSystemEgressProviderOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions)) + { + validatableInfo = CreateCollectDumpOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions)) + { + validatableInfo = CreateLoadProfilerOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes)) + { + validatableInfo = CreateTestValidatableTypes(); + return true; + } + + return false; + } + + // No-ops, rely on runtime code for ParameterInfo-based resolution + public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterInfo parameterInfo, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) + { + validatableInfo = null; + return false; + } + + private ValidatableTypeInfo CreateCollectionRuleTriggerOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + propertyType: typeof(string), + name: "Type", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings1" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleActionOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), + propertyType: typeof(string), + name: "Type", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings2-tools.unittests" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleLimitsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(int?), + name: "ActionCount", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings3" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "ActionCountSlidingWindowDuration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings4" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RuleDuration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings5" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + name: "Trigger", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings6" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Actions", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings7" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + name: "Limits", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings8" + ), + ] + ); + } + private ValidatableTypeInfo CreateMethodBase() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodBase), + members: [] + ); + } + private ValidatableTypeInfo CreateConstructorInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ConstructorInfo), + members: [] + ); + } + private ValidatableTypeInfo CreateCustomAttributeTypedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeTypedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + propertyType: typeof(global::System.Type), + name: "ArgumentType", + displayName: "ArgumentType" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeNamedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeNamedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "MemberInfo", + displayName: "MemberInfo" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + name: "TypedValue", + displayName: "TypedValue" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeData() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeData), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Type), + name: "AttributeType", + displayName: "AttributeType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "Constructor", + displayName: "Constructor" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "ConstructorArguments", + displayName: "ConstructorArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "NamedArguments", + displayName: "NamedArguments" + ), + ] + ); + } + private ValidatableTypeInfo CreateParameterInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ParameterInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "Member", + displayName: "Member" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Type), + name: "ParameterType", + displayName: "ParameterType" + ), + ] + ); + } + private ValidatableTypeInfo CreateMethodInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.ParameterInfo), + name: "ReturnParameter", + displayName: "ReturnParameter" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Type), + name: "ReturnType", + displayName: "ReturnType" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.EventInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "AddMethod", + displayName: "AddMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Type), + name: "EventHandlerType", + displayName: "EventHandlerType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RaiseMethod", + displayName: "RaiseMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RemoveMethod", + displayName: "RemoveMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateFieldInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.FieldInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Type), + name: "FieldType", + displayName: "FieldType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + ] + ); + } + private ValidatableTypeInfo CreatePropertyInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.PropertyInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "GetMethod", + displayName: "GetMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Type), + name: "PropertyType", + displayName: "PropertyType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "SetMethod", + displayName: "SetMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateTypeInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.TypeInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredConstructors", + displayName: "DeclaredConstructors" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredEvents", + displayName: "DeclaredEvents" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredFields", + displayName: "DeclaredFields" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMembers", + displayName: "DeclaredMembers" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMethods", + displayName: "DeclaredMethods" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredNestedTypes", + displayName: "DeclaredNestedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredProperties", + displayName: "DeclaredProperties" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ImplementedInterfaces", + displayName: "ImplementedInterfaces" + ), + ] + ); + } + private ValidatableTypeInfo CreateAssembly() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Assembly), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DefinedTypes", + displayName: "DefinedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "EntryPoint", + displayName: "EntryPoint" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ExportedTypes", + displayName: "ExportedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.Module), + name: "ManifestModule", + displayName: "ManifestModule" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "Modules", + displayName: "Modules" + ), + ] + ); + } + private ValidatableTypeInfo CreateGuid() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Guid), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::System.Guid), + // propertyType: typeof(global::System.Guid), + // name: "AllBitsSet", + // displayName: "AllBitsSet" + // ), + ] + ); + } + private ValidatableTypeInfo CreateModule() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Module), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Guid), + name: "ModuleVersionId", + displayName: "ModuleVersionId" + ), + ] + ); + } + private ValidatableTypeInfo CreateMemberInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MemberInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + ] + ); + } + private ValidatableTypeInfo CreateType() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Type), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "BaseType", + displayName: "BaseType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MethodBase), + name: "DeclaringMethod", + displayName: "DeclaringMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type[]), + name: "GenericTypeArguments", + displayName: "GenericTypeArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Guid), + name: "GUID", + displayName: "GUID" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "TypeInitializer", + displayName: "TypeInitializer" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "UnderlyingSystemType", + displayName: "UnderlyingSystemType" + ), + ] + ); + } + private ValidatableTypeInfo CreateBaseRecordOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + ] + ); + } + private ValidatableTypeInfo CreateExecuteOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + propertyType: typeof(string), + name: "Path", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + propertyType: typeof(string), + name: "Name", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + propertyType: typeof(string), + name: "Name", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateIDictionary_string_string() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Collections.Generic.IDictionary), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Collections.Generic.IDictionary), + propertyType: typeof(global::System.Collections.Generic.ICollection), + name: "Values", + displayName: "Values" + ), + ] + ); + } + private ValidatableTypeInfo CreateTraceEventFilter() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(string), + name: "ProviderName", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(string), + name: "EventName", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "PayloadFilter", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectTraceOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.TraceProfile?), + name: "Profile", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(int?), + name: "BufferSizeMegabytes", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + name: "StoppingEvent", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateGlobalCounterOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(float?), + name: "IntervalSeconds", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(int?), + name: "MaxHistograms", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(int?), + name: "MaxTimeSeries", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Providers", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectGCDumpOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectLiveMetricsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateMonitorApiKeyOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + propertyType: typeof(string), + name: "Subject", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + propertyType: typeof(string), + name: "PublicKey", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateAzureAdOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "TenantId", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "ClientId", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(global::System.Uri), + name: "AppIdUri", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "RequiredRole", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateAuthenticationOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + name: "MonitorApiKey", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + name: "AzureAd", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateExceptionsConfiguration() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Exclude", + displayName: "Exclude" + ), + ] + ); + } + private ValidatableTypeInfo CreateExceptionsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + propertyType: typeof(int?), + name: "TopLevelLimit", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + name: "CollectionFilters", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateInProcessFeaturesOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + name: "Exceptions", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCorsConfigurationOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + propertyType: typeof(string), + name: "AllowedOrigins", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateEgressOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "FileSystem", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Properties", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateMetricProvider() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), + propertyType: typeof(string), + name: "ProviderName", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateMetricsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + propertyType: typeof(int?), + name: "MetricCount", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Providers", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateProcessFilterOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Filters", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleTriggerDefaultsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(int?), + name: "RequestCount", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(int?), + name: "ResponseCount", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleLimitsDefaultsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(int?), + name: "ActionCount", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "ActionCountSlidingWindowDuration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RuleDuration", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleDefaultsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + name: "Triggers", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + name: "Limits", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateTemplateOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleFilters", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleTriggers", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleActions", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleLimits", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateRootOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + name: "Authentication", + displayName: "Authentication" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRules", + displayName: "CollectionRules" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + name: "GlobalCounter", + displayName: "GlobalCounter" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + name: "InProcessFeatures", + displayName: "InProcessFeatures" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + name: "CorsConfiguration", + displayName: "CorsConfiguration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + name: "Egress", + displayName: "Egress" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + name: "Metrics", + displayName: "Metrics" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), + name: "DefaultProcess", + displayName: "DefaultProcess" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + name: "CollectionRuleDefaults", + displayName: "CollectionRuleDefaults" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + name: "Templates", + displayName: "Templates" + ), + ] + ); + } + private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + propertyType: typeof(string), + name: "DirectoryPath", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + propertyType: typeof(int?), + name: "CopyBufferSize", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectDumpOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.DumpType?), + name: "Type", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateLoadProfilerOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + propertyType: typeof(string), + name: "Path", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + propertyType: typeof(global::System.Guid), + name: "Clsid", + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + ), + ] + ); + } + private ValidatableTypeInfo CreateTestValidatableTypes() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + name: "CollectionRuleOptions", + displayName: "CollectionRuleOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + name: "ExecuteOptions", + displayName: "ExecuteOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + name: "SetEnvironmentVariableOptions", + displayName: "SetEnvironmentVariableOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + name: "GetEnvironmentVariableOptions", + displayName: "GetEnvironmentVariableOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + name: "CollectTraceOptions", + displayName: "CollectTraceOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + name: "GlobalCounterOptions", + displayName: "GlobalCounterOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + name: "CollectGCDumpOptions", + displayName: "CollectGCDumpOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + name: "CollectLiveMetricsOptions", + displayName: "CollectLiveMetricsOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + name: "RootOptions", + displayName: "RootOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + name: "FileSystemEgressProviderOptions", + displayName: "FileSystemEgressProviderOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + name: "CollectDumpOptions", + displayName: "CollectDumpOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + name: "LoadProfilerOptions", + displayName: "LoadProfilerOptions" + ), + ] + ); + } + + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + internal static class GeneratedServiceCollectionExtensions + { + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "ZwR3lEVY3JYQ5HMDMrMsqtEIAABUZXN0VmFsaWRhdGFibGVUeXBlcy5jcw==")] + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + { + // Use non-extension method to avoid infinite recursion. + return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => + { + options.Resolvers.Insert(0, new GeneratedValidatableInfoResolver()); + if (configureOptions is not null) + { + configureOptions(options); + } + }); + } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file static class ValidationAttributeCache + { + private sealed record CacheKey(global::System.Type ContainingType, string PropertyName); + private static readonly global::System.Collections.Concurrent.ConcurrentDictionary _cache = new(); + + public static global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes( + global::System.Type containingType, + string propertyName) + { + var key = new CacheKey(containingType, propertyName); + return _cache.GetOrAdd(key, static k => + { + var property = k.ContainingType.GetProperty(k.PropertyName); + if (property == null) + { + return []; + } + + return [.. global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(property, inherit: true)]; + }); + } + } +} \ No newline at end of file From f49dfbb723181f9521ab21543a752f515ec94dc6 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 21 Apr 2025 16:32:22 +0000 Subject: [PATCH 134/174] Fix DefaultEgress_Failure - Pass type info - Avoid changing OptionsValidationException message --- .../CollectionRuleDefaultsTests.cs | 2 +- src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDefaultsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDefaultsTests.cs index 7ffb6ee6611..977098235a9 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDefaultsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDefaultsTests.cs @@ -73,7 +73,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => () => ActionTestsHelper.GetActionOptions(host, DefaultRuleName)); Assert.Equal(string.Format(OptionsDisplayStrings.ErrorMessage_NoDefaultEgressProvider), invalidOptionsException.Message); - }); + }, TestValidatableTypes.AddValidation); } [Fact] diff --git a/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs b/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs index bc144fff731..1548e6a05cd 100644 --- a/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs +++ b/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs @@ -48,7 +48,7 @@ public ValidateOptionsResult Validate(string? name, TOptions options) { foreach (string memberName in memberNames) { - failures.Add($"{memberName}: {result.ErrorMessage}"); + failures.Add(result.ErrorMessage); } } else From c3ef7e37a9cc8f5c43a5e2542e31631026db4e1f Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 21 Apr 2025 19:18:52 +0000 Subject: [PATCH 135/174] Add Name to DisplayAttribute --- .../AzureBlobEgressProviderOptions.cs | 15 +++ .../S3StorageEgressProviderOptions.cs | 12 ++ .../AuthenticationOptions.cs | 2 + .../AzureAdOptions.cs | 5 + .../CallStacksOptions.cs | 1 + .../CorsConfigurationOptions.cs | 1 + .../DiagnosticPortOptions.cs | 4 + .../EgressOptions.cs | 2 + .../ExceptionsOptions.cs | 3 + .../FileSystemEgressProviderOptions.cs | 3 + .../GlobalCounterOptions.cs | 4 + .../InProcessFeaturesOptions.cs | 4 + .../MetricsOptions.cs | 10 ++ .../MonitorApiKeyOptions.cs | 3 + .../ParameterCapturingOptions.cs | 1 + .../ProcessFilterOptions.cs | 13 ++ .../StorageOptions.cs | 3 + .../ValidatableInfoResolver.cs | 124 +++++++++--------- .../Options/ConsoleFormatterOptions.cs | 3 + .../Options/ConsoleLoggerOptions.cs | 4 + .../Options/JsonConsoleFormatterOptions.cs | 4 + .../Options/LogLevelOptions.cs | 1 + .../Options/LoggingOptions.cs | 6 + .../Options/SimpleConsoleFormatterOptions.cs | 5 + .../Options/Actions/CollectDumpOptions.cs | 3 + .../Actions/CollectExceptionsOptions.cs | 4 + .../Options/Actions/CollectGCDumpOptions.cs | 2 + .../Actions/CollectLiveMetricsOptions.cs | 6 + .../Options/Actions/CollectLogsOptions.cs | 7 + .../Options/Actions/CollectStacksOptions.cs | 3 + .../Options/Actions/CollectTraceOptions.cs | 8 ++ .../Options/Actions/ExecuteOptions.cs | 2 + .../Actions/GetEnvironmentVariableOptions.cs | 1 + .../Options/Actions/LoadProfilerOptions.cs | 2 + .../Actions/SetEnvironmentVariableOptions.cs | 2 + .../Options/Actions/TraceEventFilter.cs | 3 + .../CollectionRuleActionDefaultsOptions.cs | 1 + .../Options/CollectionRuleActionOptions.cs | 4 + .../Options/CollectionRuleDefaultsOptions.cs | 3 + .../CollectionRuleLimitsDefaultsOptions.cs | 3 + .../Options/CollectionRuleLimitsOptions.cs | 3 + .../Options/CollectionRuleOptions.cs | 4 + .../CollectionRuleTriggerDefaultsOptions.cs | 3 + .../Options/CollectionRuleTriggerOptions.cs | 2 + .../Options/TemplateOptions.cs | 4 + .../Triggers/AspNetRequestCountOptions.cs | 4 + .../Triggers/AspNetRequestDurationOptions.cs | 5 + .../Triggers/AspNetResponseStatusOptions.cs | 5 + .../Options/Triggers/EventCounterOptions.cs | 5 + .../EventCounterShortcuts/CPUUsageOptions.cs | 3 + .../GCHeapSizeOptions.cs | 3 + .../ThreadpoolQueueLengthOptions.cs | 4 +- .../Options/Triggers/EventMeterOptions.cs | 6 + 53 files changed, 275 insertions(+), 63 deletions(-) diff --git a/src/Extensions/AzureBlobStorage/AzureBlobEgressProviderOptions.cs b/src/Extensions/AzureBlobStorage/AzureBlobEgressProviderOptions.cs index dcfd74a2fe2..544b4b4020b 100644 --- a/src/Extensions/AzureBlobStorage/AzureBlobEgressProviderOptions.cs +++ b/src/Extensions/AzureBlobStorage/AzureBlobEgressProviderOptions.cs @@ -11,79 +11,94 @@ namespace Microsoft.Diagnostics.Monitoring.AzureBlobStorage internal sealed partial class AzureBlobEgressProviderOptions { [Display( + Name = nameof(AccountUri), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_AccountUri))] [Required] public Uri AccountUri { get; set; } [Display( + Name = nameof(AccountKey), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_AccountKey))] public string AccountKey { get; set; } [Display( + Name = nameof(AccountKeyName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_AccountKeyName))] public string AccountKeyName { get; set; } [Display( + Name = nameof(SharedAccessSignature), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_SharedAccessSignature))] public string SharedAccessSignature { get; set; } [Display( + Name = nameof(SharedAccessSignatureName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_SharedAccessSignatureName))] public string SharedAccessSignatureName { get; set; } [Display( + Name = nameof(ManagedIdentityClientId), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_ManagedIdentityClientId))] public string ManagedIdentityClientId { get; set; } [Display( + Name = nameof(UseWorkloadIdentityFromEnvironment), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_UseWorkloadIdentityFromEnvironment))] public bool? UseWorkloadIdentityFromEnvironment { get; set; } [Display( + Name = nameof(ContainerName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_ContainerName))] [Required] public string ContainerName { get; set; } [Display( + Name = nameof(BlobPrefix), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_BlobPrefix))] public string BlobPrefix { get; set; } [Display( + Name = nameof(CopyBufferSize), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CommonEgressProviderOptions_CopyBufferSize))] [Range(1, int.MaxValue)] public int? CopyBufferSize { get; set; } [Display( + Name = nameof(QueueName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_QueueName))] public string QueueName { get; set; } [Display( + Name = nameof(QueueAccountUri), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_QueueAccountUri))] public Uri QueueAccountUri { get; set; } [Display( + Name = nameof(QueueSharedAccessSignature), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_QueueSharedAccessSignature))] public string QueueSharedAccessSignature { get; set; } [Display( + Name = nameof(QueueSharedAccessSignatureName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_QueueSharedAccessSignatureName))] public string QueueSharedAccessSignatureName { get; set; } [Display( + Name = nameof(Metadata), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_Metadata))] public IDictionary Metadata { get; set; } diff --git a/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs b/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs index 5e868364369..45b83bd316e 100644 --- a/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs +++ b/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs @@ -13,42 +13,50 @@ namespace Microsoft.Diagnostics.Monitoring.Extension.S3Storage internal sealed partial class S3StorageEgressProviderOptions { [Display( + Name = nameof(Endpoint), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_Endpoint))] public string? Endpoint { get; set; } [Display( + Name = nameof(BucketName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_BucketName))] [Required(AllowEmptyStrings = false)] public string BucketName { get; set; } = string.Empty; [Display( + Name = nameof(RegionName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_RegionName))] public string? RegionName { get; set; } [Display( + Name = nameof(AccessKeyId), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_AccessKeyId))] public string? AccessKeyId { get; set; } [Display( + Name = nameof(SecretAccessKey), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_SecretAccessKey))] public string? SecretAccessKey { get; set; } [Display( + Name = nameof(AwsProfileName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_AWSProfileName))] public string? AwsProfileName { get; set; } [Display( + Name = nameof(AwsProfilePath), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_AWSProfilePath))] public string? AwsProfilePath { get; set; } [Display( + Name = nameof(PreSignedUrlExpiry), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_PreSignedUrlExpiry))] [Range(typeof(TimeSpan), "00:01:00", "1.00:00:00")] @@ -56,22 +64,26 @@ internal sealed partial class S3StorageEgressProviderOptions public TimeSpan? PreSignedUrlExpiry { get; set; } [Display( + Name = nameof(ForcePathStyle), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_ForcePathStyle))] public bool ForcePathStyle { get; set; } [Display( + Name = nameof(CopyBufferSize), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CommonEgressProviderOptions_CopyBufferSize))] [Range(1, int.MaxValue)] public int? CopyBufferSize { get; set; } [Display( + Name = nameof(UseKmsEncryption), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_UseKmsEncryption))] public bool UseKmsEncryption { get; set; } [Display( + Name = nameof(KmsEncryptionKey), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_KmsEncryptionKey))] public string? KmsEncryptionKey { get; set; } diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.cs index 8b2b8567588..afc9d6b623c 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.cs @@ -9,11 +9,13 @@ namespace Microsoft.Diagnostics.Tools.Monitor internal sealed partial class AuthenticationOptions { [Display( + Name = nameof(MonitorApiKey), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AuthenticationOptions_MonitorApiKey))] public MonitorApiKeyOptions? MonitorApiKey { get; set; } [Display( + Name = nameof(AzureAd), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AuthenticationOptions_AzureAd))] public AzureAdOptions? AzureAd { get; set; } diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/AzureAdOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/AzureAdOptions.cs index dd8e6eecace..e5cdd5c85fd 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/AzureAdOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/AzureAdOptions.cs @@ -11,29 +11,34 @@ namespace Microsoft.Diagnostics.Tools.Monitor internal sealed partial class AzureAdOptions { [Display( + Name = nameof(Instance), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureAdOptions_Instance))] [DefaultValue(AzureAdOptionsDefaults.DefaultInstance)] public Uri? Instance { get; set; } [Display( + Name = nameof(TenantId), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureAdOptions_TenantId))] [Required] public string TenantId { get; set; } = string.Empty; [Display( + Name = nameof(ClientId), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureAdOptions_ClientId))] [Required] public string ClientId { get; set; } = string.Empty; [Display( + Name = nameof(AppIdUri), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureAdOptions_AppIdUri))] public Uri? AppIdUri { get; set; } [Display( + Name = nameof(RequiredRole), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureAdOptions_RequiredRole))] [Required] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/CallStacksOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/CallStacksOptions.cs index 7ed2b6ef532..e2c091ad9be 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/CallStacksOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/CallStacksOptions.cs @@ -11,6 +11,7 @@ public sealed class CallStacksOptions : IInProcessFeatureOptions { [Display( + Name = nameof(Enabled), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CallStacksOptions_Enabled))] [DefaultValue(CallStacksOptionsDefaults.Enabled)] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/CorsConfigurationOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/CorsConfigurationOptions.cs index c2b905fb636..d5451967e6a 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/CorsConfigurationOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/CorsConfigurationOptions.cs @@ -8,6 +8,7 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi public class CorsConfigurationOptions { [Display( + Name = nameof(AllowedOrigins), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CorsConfiguration_AllowedOrigins))] [Required] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortOptions.cs index cb6d4431ca4..f0bf626f983 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortOptions.cs @@ -9,22 +9,26 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi public class DiagnosticPortOptions { [Display( + Name = nameof(ConnectionMode), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_DiagnosticPortOptions_ConnectionMode))] [DefaultValue(DiagnosticPortOptionsDefaults.ConnectionMode)] public DiagnosticPortConnectionMode? ConnectionMode { get; set; } [Display( + Name = nameof(EndpointName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_DiagnosticPortOptions_EndpointName))] public string? EndpointName { get; set; } [Display( + Name = nameof(MaxConnections), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_DiagnosticPortOptions_MaxConnections))] public int? MaxConnections { get; set; } [Display( + Name = nameof(DeleteEndpointOnStartup), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_DiagnosticPortOptions_DeleteEndpointOnStartup))] [DefaultValue(DiagnosticPortOptionsDefaults.DeleteEndpointOnStartup)] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/EgressOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/EgressOptions.cs index b0b07ca343e..32b79b4016b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/EgressOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/EgressOptions.cs @@ -11,11 +11,13 @@ namespace Microsoft.Diagnostics.Tools.Monitor internal sealed class EgressOptions { [Display( + Name = nameof(FileSystem), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EgressOptions_FileSystem))] public IDictionary? FileSystem { get; set; } [Display( + Name = nameof(Properties), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EgressOptions_Properties))] public IDictionary? Properties { get; set; } diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/ExceptionsOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/ExceptionsOptions.cs index db816efd44e..787bc1b2d15 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/ExceptionsOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/ExceptionsOptions.cs @@ -11,12 +11,14 @@ public sealed class ExceptionsOptions : IInProcessFeatureOptions { [Display( + Name = nameof(Enabled), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ExceptionsOptions_Enabled))] [DefaultValue(ExceptionsOptionsDefaults.Enabled)] public bool? Enabled { get; set; } [Display( + Name = nameof(TopLevelLimit), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ExceptionsOptions_TopLevelLimit))] [Range(1, int.MaxValue)] @@ -24,6 +26,7 @@ public sealed class ExceptionsOptions : public int? TopLevelLimit { get; set; } [Display( + Name = nameof(CollectionFilters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ExceptionsOptions_CollectionFilters))] public ExceptionsConfiguration? CollectionFilters { get; set; } diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/FileSystemEgressProviderOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/FileSystemEgressProviderOptions.cs index 0caee405036..3dcc4953c9c 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/FileSystemEgressProviderOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/FileSystemEgressProviderOptions.cs @@ -15,17 +15,20 @@ internal sealed class FileSystemEgressProviderOptions public const int CopyBufferSize_MaxValue = int.MaxValue; [Display( + Name = nameof(DirectoryPath), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_FileSystemEgressProviderOptions_DirectoryPath))] [Required] public string DirectoryPath { get; set; } = string.Empty; [Display( + Name = nameof(IntermediateDirectoryPath), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_FileSystemEgressProviderOptions_IntermediateDirectoryPath))] public string? IntermediateDirectoryPath { get; set; } [Display( + Name = nameof(CopyBufferSize), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CommonEgressProviderOptions_CopyBufferSize))] [Range(CopyBufferSize_MinValue, CopyBufferSize_MaxValue)] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs index c360b5184d1..9dc0450e83e 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs @@ -16,6 +16,7 @@ public partial class GlobalCounterOptions public const float IntervalMaxSeconds = 60 * 60 * 24; // One day [Display( + Name = nameof(IntervalSeconds), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_GlobalCounterOptions_IntervalSeconds))] [Range(IntervalMinSeconds, IntervalMaxSeconds)] @@ -23,6 +24,7 @@ public partial class GlobalCounterOptions public float? IntervalSeconds { get; set; } [Display( + Name = nameof(MaxHistograms), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_MaxHistograms))] [DefaultValue(GlobalCounterOptionsDefaults.MaxHistograms)] @@ -30,6 +32,7 @@ public partial class GlobalCounterOptions public int? MaxHistograms { get; set; } [Display( + Name = nameof(MaxTimeSeries), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_MaxTimeSeries))] [DefaultValue(GlobalCounterOptionsDefaults.MaxTimeSeries)] @@ -37,6 +40,7 @@ public partial class GlobalCounterOptions public int? MaxTimeSeries { get; set; } [Display( + Name = nameof(Providers), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_GlobalCounterOptions_Providers))] public System.Collections.Generic.IDictionary? Providers { get; set; } = new Dictionary(StringComparer.OrdinalIgnoreCase); diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/InProcessFeaturesOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/InProcessFeaturesOptions.cs index 0d7dadbd92f..0bd7a2f8b3e 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/InProcessFeaturesOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/InProcessFeaturesOptions.cs @@ -13,22 +13,26 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class InProcessFeaturesOptions { [Display( + Name = nameof(Enabled), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_InProcessFeaturesOptions_Enabled))] [DefaultValue(InProcessFeaturesOptionsDefaults.Enabled)] public bool? Enabled { get; set; } [Display( + Name = nameof(CallStacks), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_InProcessFeaturesOptions_CallStacks))] public CallStacksOptions? CallStacks { get; set; } [Display( + Name = nameof(Exceptions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_InProcessFeaturesOptions_Exceptions))] public ExceptionsOptions? Exceptions { get; set; } [Display( + Name = nameof(ParameterCapturing), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_InProcessFeaturesOptions_ParameterCapturing))] [Experimental] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/MetricsOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/MetricsOptions.cs index faa647690f3..794ebae9843 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/MetricsOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/MetricsOptions.cs @@ -17,17 +17,20 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi public class MetricsOptions { [Display( + Name = nameof(Enabled), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_Enabled))] [DefaultValue(MetricsOptionsDefaults.Enabled)] public bool? Enabled { get; set; } [Display( + Name = nameof(Endpoints), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_Endpoints))] public string? Endpoints { get; set; } [Display( + Name = nameof(MetricCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_MetricCount))] [DefaultValue(MetricsOptionsDefaults.MetricCount)] @@ -35,17 +38,20 @@ public class MetricsOptions public int? MetricCount { get; set; } [Display( + Name = nameof(IncludeDefaultProviders), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_IncludeDefaultProviders))] [DefaultValue(MetricsOptionsDefaults.IncludeDefaultProviders)] public bool? IncludeDefaultProviders { get; set; } [Display( + Name = nameof(Providers), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_Providers))] public List Providers { get; set; } = []; [Display( + Name = nameof(Meters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_Meters))] public List Meters { get; set; } = []; @@ -54,12 +60,14 @@ public class MetricsOptions public class MetricProvider { [Display( + Name = nameof(ProviderName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricProvider_ProviderName))] [Required] public string ProviderName { get; set; } = string.Empty; [Display( + Name = nameof(CounterNames), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricProvider_CounterNames))] public List CounterNames { get; set; } = []; @@ -68,11 +76,13 @@ public class MetricProvider public class MeterConfiguration { [Display( + Name = nameof(MeterName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MeterConfiguration_MeterName))] public string? MeterName { get; set; } [Display( + Name = nameof(InstrumentNames), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MeterConfiguration_InstrumentNames))] public List InstrumentNames { get; set; } = []; diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/MonitorApiKeyOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/MonitorApiKeyOptions.cs index d37c2c6449d..c3e751c5b1b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/MonitorApiKeyOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/MonitorApiKeyOptions.cs @@ -9,12 +9,14 @@ namespace Microsoft.Diagnostics.Tools.Monitor internal sealed class MonitorApiKeyOptions { [Display( + Name = nameof(Subject), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MonitorApiKeyOptions_Subject))] [Required] public string Subject { get; set; } = string.Empty; [Display( + Name = nameof(PublicKey), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MonitorApiKeyOptions_PublicKey))] [RegularExpression("[0-9a-zA-Z_-]+")] @@ -22,6 +24,7 @@ internal sealed class MonitorApiKeyOptions public string PublicKey { get; set; } = string.Empty; [Display( + Name = nameof(Issuer), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MonitorApiKeyOptions_Issuer))] public string? Issuer { get; set; } diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/ParameterCapturingOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/ParameterCapturingOptions.cs index fe195a8f1ba..a11d9a91d4b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/ParameterCapturingOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/ParameterCapturingOptions.cs @@ -11,6 +11,7 @@ public sealed class ParameterCapturingOptions : IInProcessFeatureOptions { [Display( + Name = nameof(Enabled), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ParameterCapturingOptions_Enabled))] [DefaultValue(ParameterCapturingOptionsDefaults.Enabled)] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/ProcessFilterOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/ProcessFilterOptions.cs index 451d18a9cab..67677775b77 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/ProcessFilterOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/ProcessFilterOptions.cs @@ -10,14 +10,17 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi public enum ProcessFilterKey { [Display( + Name = nameof(ProcessId), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterKey_ProcessId))] ProcessId, [Display( + Name = nameof(ProcessName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterKey_ProcessName))] ProcessName, [Display( + Name = nameof(CommandLine), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterKey_CommandLine))] CommandLine, @@ -27,11 +30,13 @@ public enum ProcessFilterKey public enum ProcessFilterType { [Display( + Name = nameof(Exact), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterType_Exact))] Exact, [Display( + Name = nameof(Contains), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterType_Contains))] Contains, @@ -40,6 +45,7 @@ public enum ProcessFilterType public sealed class ProcessFilterOptions { [Display( + Name = nameof(Filters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterOptions_Filters))] public List Filters { get; set; } = []; @@ -48,37 +54,44 @@ public sealed class ProcessFilterOptions public sealed partial class ProcessFilterDescriptor { [Display( + Name = nameof(Key), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_Key))] public ProcessFilterKey Key { get; set; } [Display( + Name = nameof(Value), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_Value))] public string? Value { get; set; } [Display( + Name = nameof(MatchType), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_MatchType))] [DefaultValue(ProcessFilterType.Exact)] public ProcessFilterType MatchType { get; set; } = ProcessFilterType.Exact; [Display( + Name = nameof(ProcessName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_ProcessName))] public string? ProcessName { get; set; } [Display( + Name = nameof(ProcessId), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_ProcessId))] public string? ProcessId { get; set; } [Display( + Name = nameof(CommandLine), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_CommandLine))] public string? CommandLine { get; set; } [Display( + Name = nameof(ManagedEntryPointAssemblyName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_ManagedEntryPointAssemblyName))] public string? ManagedEntryPointAssemblyName { get; set; } diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/StorageOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/StorageOptions.cs index 39c925fee41..1c410810cef 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/StorageOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/StorageOptions.cs @@ -9,17 +9,20 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi public class StorageOptions { [Display( + Name = nameof(DefaultSharedPath), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_StorageOptions_DefaultSharedPath))] public string? DefaultSharedPath { get; set; } [Display( + Name = nameof(DumpTempFolder), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_StorageOptions_DumpTempFolder))] public string? DumpTempFolder { get; set; } [Experimental] [Display( + Name = nameof(SharedLibraryPath), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_StorageOptions_SharedLibraryPath))] public string? SharedLibraryPath { get; set; } diff --git a/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs b/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs index fd8af954f48..568bb83794e 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs @@ -329,7 +329,7 @@ private ValidatableTypeInfo CreateCollectionRuleTriggerOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), propertyType: typeof(string), name: "Type", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings1" ), ] ); @@ -343,7 +343,7 @@ private ValidatableTypeInfo CreateCollectionRuleActionOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), propertyType: typeof(string), name: "Type", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings2" ), ] ); @@ -357,19 +357,19 @@ private ValidatableTypeInfo CreateCollectionRuleLimitsOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), propertyType: typeof(int?), name: "ActionCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings3" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), propertyType: typeof(global::System.TimeSpan?), name: "ActionCountSlidingWindowDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings4" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), propertyType: typeof(global::System.TimeSpan?), name: "RuleDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings5" ), ] ); @@ -383,19 +383,19 @@ private ValidatableTypeInfo CreateCollectionRuleOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), name: "Trigger", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings6" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), propertyType: typeof(global::System.Collections.Generic.List), name: "Actions", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings7" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), name: "Limits", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings8" ), ] ); @@ -904,7 +904,7 @@ private ValidatableTypeInfo CreateExecuteOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), propertyType: typeof(string), name: "Path", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings9" ), ] ); @@ -924,7 +924,7 @@ private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), propertyType: typeof(string), name: "Name", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings10" ), ] ); @@ -944,7 +944,7 @@ private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), propertyType: typeof(string), name: "Name", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings11" ), ] ); @@ -978,19 +978,19 @@ private ValidatableTypeInfo CreateTraceEventFilter() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), propertyType: typeof(string), name: "ProviderName", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings12" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), propertyType: typeof(string), name: "EventName", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings13" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "PayloadFilter", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings14" ), ] ); @@ -1010,31 +1010,31 @@ private ValidatableTypeInfo CreateCollectTraceOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.TraceProfile?), name: "Profile", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings15" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), propertyType: typeof(int?), name: "BufferSizeMegabytes", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings16" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), propertyType: typeof(global::System.TimeSpan?), name: "Duration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings17" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), propertyType: typeof(string), name: "Egress", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings18" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), name: "StoppingEvent", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings19" ), ] ); @@ -1048,25 +1048,25 @@ private ValidatableTypeInfo CreateGlobalCounterOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), propertyType: typeof(float?), name: "IntervalSeconds", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings20" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), propertyType: typeof(int?), name: "MaxHistograms", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings21" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), propertyType: typeof(int?), name: "MaxTimeSeries", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings22" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "Providers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings23" ), ] ); @@ -1086,7 +1086,7 @@ private ValidatableTypeInfo CreateCollectGCDumpOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), propertyType: typeof(string), name: "Egress", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings24" ), ] ); @@ -1106,13 +1106,13 @@ private ValidatableTypeInfo CreateCollectLiveMetricsOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), propertyType: typeof(global::System.TimeSpan?), name: "Duration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings25" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), propertyType: typeof(string), name: "Egress", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings26" ), ] ); @@ -1126,13 +1126,13 @@ private ValidatableTypeInfo CreateMonitorApiKeyOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), propertyType: typeof(string), name: "Subject", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings27" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), propertyType: typeof(string), name: "PublicKey", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings28" ), ] ); @@ -1146,25 +1146,25 @@ private ValidatableTypeInfo CreateAzureAdOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), propertyType: typeof(string), name: "TenantId", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings29" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), propertyType: typeof(string), name: "ClientId", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings30" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), propertyType: typeof(global::System.Uri), name: "AppIdUri", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings31" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), propertyType: typeof(string), name: "RequiredRole", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings32" ), ] ); @@ -1178,13 +1178,13 @@ private ValidatableTypeInfo CreateAuthenticationOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), name: "MonitorApiKey", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings33" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), name: "AzureAd", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings34" ), ] ); @@ -1212,13 +1212,13 @@ private ValidatableTypeInfo CreateExceptionsOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), propertyType: typeof(int?), name: "TopLevelLimit", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings35" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), name: "CollectionFilters", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings36" ), ] ); @@ -1232,7 +1232,7 @@ private ValidatableTypeInfo CreateInProcessFeaturesOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), name: "Exceptions", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings37" ), ] ); @@ -1246,7 +1246,7 @@ private ValidatableTypeInfo CreateCorsConfigurationOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), propertyType: typeof(string), name: "AllowedOrigins", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings38" ), ] ); @@ -1260,13 +1260,13 @@ private ValidatableTypeInfo CreateEgressOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "FileSystem", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings39" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "Properties", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings40" ), ] ); @@ -1280,7 +1280,7 @@ private ValidatableTypeInfo CreateMetricProvider() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), propertyType: typeof(string), name: "ProviderName", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings41" ), ] ); @@ -1294,13 +1294,13 @@ private ValidatableTypeInfo CreateMetricsOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), propertyType: typeof(int?), name: "MetricCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings42" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), propertyType: typeof(global::System.Collections.Generic.List), name: "Providers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings43" ), ] ); @@ -1314,7 +1314,7 @@ private ValidatableTypeInfo CreateProcessFilterOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), propertyType: typeof(global::System.Collections.Generic.List), name: "Filters", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings44" ), ] ); @@ -1328,19 +1328,19 @@ private ValidatableTypeInfo CreateCollectionRuleTriggerDefaultsOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), propertyType: typeof(int?), name: "RequestCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings45" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), propertyType: typeof(int?), name: "ResponseCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings46" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), propertyType: typeof(global::System.TimeSpan?), name: "SlidingWindowDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings47" ), ] ); @@ -1354,19 +1354,19 @@ private ValidatableTypeInfo CreateCollectionRuleLimitsDefaultsOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), propertyType: typeof(int?), name: "ActionCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings48" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), propertyType: typeof(global::System.TimeSpan?), name: "ActionCountSlidingWindowDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings49" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), propertyType: typeof(global::System.TimeSpan?), name: "RuleDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings50" ), ] ); @@ -1380,13 +1380,13 @@ private ValidatableTypeInfo CreateCollectionRuleDefaultsOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), name: "Triggers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings51" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), name: "Limits", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings52" ), ] ); @@ -1400,25 +1400,25 @@ private ValidatableTypeInfo CreateTemplateOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "CollectionRuleFilters", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings53" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "CollectionRuleTriggers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings54" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "CollectionRuleActions", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings55" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "CollectionRuleLimits", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings56" ), ] ); @@ -1500,13 +1500,13 @@ private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), propertyType: typeof(string), name: "DirectoryPath", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings57" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), propertyType: typeof(int?), name: "CopyBufferSize", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings58" ), ] ); @@ -1526,13 +1526,13 @@ private ValidatableTypeInfo CreateCollectDumpOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.DumpType?), name: "Type", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings59" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), propertyType: typeof(string), name: "Egress", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings60" ), ] ); @@ -1552,13 +1552,13 @@ private ValidatableTypeInfo CreateLoadProfilerOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), propertyType: typeof(string), name: "Path", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings61" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), propertyType: typeof(global::System.Guid), name: "Clsid", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings62" ), ] ); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleFormatterOptions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleFormatterOptions.cs index 111d30c9897..a3dd2c33dbe 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleFormatterOptions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleFormatterOptions.cs @@ -10,17 +10,20 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class ConsoleFormatterOptions { [Display( + Name = nameof(IncludeScopes), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_IncludeScopes))] public bool IncludeScopes { get; set; } [Display( + Name = nameof(TimestampFormat), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_TimestampFormat))] [DefaultValue(null)] public string? TimestampFormat { get; set; } [Display( + Name = nameof(UseUtcTimestamp), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_UseUtcTimestamp))] [DefaultValue(false)] diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleLoggerOptions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleLoggerOptions.cs index 67a672fda0e..f4700cab8df 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleLoggerOptions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleLoggerOptions.cs @@ -12,22 +12,26 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class ConsoleLoggerOptions { [Display( + Name = nameof(FormatterName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleLoggerOptions_FormatterName))] [DefaultValue(ConsoleLoggerFormat.Simple)] public ConsoleLoggerFormat FormatterName { get; set; } = ConsoleLoggerFormat.Simple; [Display( + Name = nameof(LogToStandardErrorThreshold), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleLoggerOptions_LogToStandardErrorThreshold))] public LogLevel LogToStandardErrorThreshold { get; set; } [Display( + Name = nameof(FormatterOptions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleLoggerOptions_FormatterOptions))] public object? FormatterOptions { get; set; } [Display( + Name = nameof(LogLevel), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleLoggerOptions_LogLevel))] public IDictionary? LogLevel { get; set; } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/JsonConsoleFormatterOptions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/JsonConsoleFormatterOptions.cs index 340249c50ba..efea74486b2 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/JsonConsoleFormatterOptions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/JsonConsoleFormatterOptions.cs @@ -11,22 +11,26 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class JsonConsoleFormatterOptions { [Display( + Name = nameof(JsonWriterOptions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_JsonConsoleFormatterOptions_WriterOptions))] public JsonWriterOptions JsonWriterOptions { get; set; } [Display( + Name = nameof(IncludeScopes), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_IncludeScopes))] public bool IncludeScopes { get; set; } [Display( + Name = nameof(TimestampFormat), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_TimestampFormat))] [DefaultValue(null)] public string? TimestampFormat { get; set; } [Display( + Name = nameof(UseUtcTimestamp), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_UseUtcTimestamp))] [DefaultValue(false)] diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LogLevelOptions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LogLevelOptions.cs index e98f40cc06d..086065809cb 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LogLevelOptions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LogLevelOptions.cs @@ -11,6 +11,7 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class LogLevelOptions { [Display( + Name = nameof(LogLevel), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LogLevelOptions_LogLevel))] public IDictionary? LogLevel { get; set; } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LoggingOptions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LoggingOptions.cs index 87b2191428d..168ed1b79fa 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LoggingOptions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LoggingOptions.cs @@ -12,31 +12,37 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class LoggingOptions { [Display( + Name = nameof(LogLevel), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoggingOptions_LogLevel))] public IDictionary? LogLevel { get; set; } [Display( + Name = nameof(Console), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoggingOptions_Console))] public ConsoleLoggerOptions? Console { get; set; } [Display( + Name = nameof(EventLog), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoggingOptions_EventLog))] public LogLevelOptions? EventLog { get; set; } [Display( + Name = nameof(Debug), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoggingOptions_Debug))] public LogLevelOptions? Debug { get; set; } [Display( + Name = nameof(EventSource), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoggingOptions_EventSource))] public LogLevelOptions? EventSource { get; set; } [Display( + Name = nameof(CaptureScopes), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoggingOptions_CaptureScopes))] [DefaultValue(true)] diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/SimpleConsoleFormatterOptions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/SimpleConsoleFormatterOptions.cs index 5e947480b99..91accf8ef1a 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/SimpleConsoleFormatterOptions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/SimpleConsoleFormatterOptions.cs @@ -12,28 +12,33 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class SimpleConsoleFormatterOptions { [Display( + Name = nameof(ColorBehavior), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_SimpleConsoleFormatterOptions_ColorBehavior))] [JsonConverter(typeof(JsonStringEnumConverter))] public LoggerColorBehavior ColorBehavior { get; set; } [Display( + Name = nameof(SingleLine), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_SimpleConsoleFormatterOptions_SingleLine))] public bool SingleLine { get; set; } [Display( + Name = nameof(IncludeScopes), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_IncludeScopes))] public bool IncludeScopes { get; set; } [Display( + Name = nameof(TimestampFormat), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_TimestampFormat))] [DefaultValue(null)] public string? TimestampFormat { get; set; } [Display( + Name = nameof(UseUtcTimestamp), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_UseUtcTimestamp))] [DefaultValue(false)] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectDumpOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectDumpOptions.cs index cb8c950fcff..cc2db3004d4 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectDumpOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectDumpOptions.cs @@ -22,6 +22,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed partial record class CollectDumpOptions : BaseRecordOptions, IEgressProviderProperties { [Display( + Name = nameof(Type), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectDumpOptions_Type))] [EnumDataType(typeof(DumpType))] @@ -29,6 +30,7 @@ internal sealed partial record class CollectDumpOptions : BaseRecordOptions, IEg public DumpType? Type { get; set; } [Display( + Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -40,6 +42,7 @@ internal sealed partial record class CollectDumpOptions : BaseRecordOptions, IEg public string Egress { get; set; } = string.Empty; [Display( + Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs index 34ea08dc30b..e8b686159ee 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs @@ -23,6 +23,7 @@ internal sealed partial record class CollectExceptionsOptions : IEgressProviderProperties { [Display( + Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -34,17 +35,20 @@ internal sealed partial record class CollectExceptionsOptions : public string Egress { get; set; } = string.Empty; [Display( + Name = nameof(Format), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectExceptionsOptions_Format))] [DefaultValue(CollectExceptionsOptionsDefaults.Format)] public ExceptionFormat? Format { get; set; } [Display( + Name = nameof(Filters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectExceptionsOptions_Filters))] public ExceptionsConfiguration? Filters { get; set; } [Display( + Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectGCDumpOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectGCDumpOptions.cs index bdc0c61c1b2..37443fbe7a3 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectGCDumpOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectGCDumpOptions.cs @@ -20,6 +20,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed partial record class CollectGCDumpOptions : BaseRecordOptions, IEgressProviderProperties { [Display( + Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -31,6 +32,7 @@ internal sealed partial record class CollectGCDumpOptions : BaseRecordOptions, I public string Egress { get; set; } = string.Empty; [Display( + Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs index 7010eac43f3..4e78cafde04 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs @@ -24,22 +24,26 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed partial record class CollectLiveMetricsOptions : BaseRecordOptions, IEgressProviderProperties { [Display( + Name = nameof(IncludeDefaultProviders), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLiveMetricsOptions_IncludeDefaultProviders))] [DefaultValue(CollectLiveMetricsOptionsDefaults.IncludeDefaultProviders)] public bool? IncludeDefaultProviders { get; set; } [Display( + Name = nameof(Providers), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLiveMetricsOptions_Providers))] public EventMetricsProvider[]? Providers { get; set; } [Display( + Name = nameof(Meters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLiveMetricsOptions_Meters))] public EventMetricsMeter[]? Meters { get; set; } [Display( + Name = nameof(Duration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Duration))] [Range(typeof(TimeSpan), ActionOptionsConstants.Duration_MinValue, ActionOptionsConstants.Duration_MaxValue)] @@ -48,6 +52,7 @@ internal sealed partial record class CollectLiveMetricsOptions : BaseRecordOptio public TimeSpan? Duration { get; set; } [Display( + Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -59,6 +64,7 @@ internal sealed partial record class CollectLiveMetricsOptions : BaseRecordOptio public string Egress { get; set; } = string.Empty; [Display( + Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs index 147ebb29ddc..74477c54523 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs @@ -26,6 +26,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed partial record class CollectLogsOptions : BaseRecordOptions, IEgressProviderProperties { [Display( + Name = nameof(DefaultLevel), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLogsOptions_DefaultLevel))] [EnumDataType(typeof(LogLevel))] @@ -33,17 +34,20 @@ internal sealed partial record class CollectLogsOptions : BaseRecordOptions, IEg public LogLevel? DefaultLevel { get; set; } [Display( + Name = nameof(FilterSpecs), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLogsOptions_FilterSpecs))] public Dictionary? FilterSpecs { get; set; } [Display( + Name = nameof(UseAppFilters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLogsOptions_UseAppFilters))] [DefaultValue(CollectLogsOptionsDefaults.UseAppFilters)] public bool? UseAppFilters { get; set; } [Display( + Name = nameof(Duration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Duration))] [Range(typeof(TimeSpan), ActionOptionsConstants.Duration_MinValue, ActionOptionsConstants.Duration_MaxValue)] @@ -52,6 +56,7 @@ internal sealed partial record class CollectLogsOptions : BaseRecordOptions, IEg public TimeSpan? Duration { get; set; } [Display( + Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -63,6 +68,7 @@ internal sealed partial record class CollectLogsOptions : BaseRecordOptions, IEg public string Egress { get; set; } = string.Empty; [Display( + Name = nameof(Format), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLogsOptions_Format))] [DefaultValue(CollectLogsOptionsDefaults.Format)] @@ -70,6 +76,7 @@ internal sealed partial record class CollectLogsOptions : BaseRecordOptions, IEg public LogFormat? Format { get; set; } [Display( + Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.cs index e1958403170..ddb47c51ec4 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.cs @@ -25,6 +25,7 @@ internal enum CallStackFormat internal sealed partial record class CollectStacksOptions : BaseRecordOptions, IEgressProviderProperties { [Display( + Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -36,12 +37,14 @@ internal sealed partial record class CollectStacksOptions : BaseRecordOptions, I public string Egress { get; set; } = string.Empty; [Display( + Name = nameof(Format), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectStacksOptions_Format))] [DefaultValue(CallStackFormat.Json)] public CallStackFormat? Format { get; set; } [Display( + Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs index 2491c12a88b..ca40aa8cf38 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs @@ -25,23 +25,27 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed partial record class CollectTraceOptions : BaseRecordOptions, IEgressProviderProperties { [Display( + Name = nameof(Profile), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectTraceOptions_Profile))] [EnumDataType(typeof(TraceProfile))] public TraceProfile? Profile { get; set; } [Display( + Name = nameof(Providers), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectTraceOptions_Providers))] public List? Providers { get; set; } [Display( + Name = nameof(RequestRundown), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectTraceOptions_RequestRundown))] [DefaultValue(CollectTraceOptionsDefaults.RequestRundown)] public bool? RequestRundown { get; set; } [Display( + Name = nameof(BufferSizeMegabytes), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectTraceOptions_BufferSizeMegabytes))] [Range(ActionOptionsConstants.BufferSizeMegabytes_MinValue, ActionOptionsConstants.BufferSizeMegabytes_MaxValue)] @@ -49,6 +53,7 @@ internal sealed partial record class CollectTraceOptions : BaseRecordOptions, IE public int? BufferSizeMegabytes { get; set; } [Display( + Name = nameof(Duration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Duration))] [Range(typeof(TimeSpan), ActionOptionsConstants.Duration_MinValue, ActionOptionsConstants.Duration_MaxValue)] @@ -57,6 +62,7 @@ internal sealed partial record class CollectTraceOptions : BaseRecordOptions, IE public TimeSpan? Duration { get; set; } [Display( + Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -68,11 +74,13 @@ internal sealed partial record class CollectTraceOptions : BaseRecordOptions, IE public string Egress { get; set; } = string.Empty; [Display( + Name = nameof(StoppingEvent), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectTraceOptions_StoppingEvent))] public TraceEventFilter? StoppingEvent { get; set; } [Display( + Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ExecuteOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ExecuteOptions.cs index f62f665430f..1d67e15d7fd 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ExecuteOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ExecuteOptions.cs @@ -20,12 +20,14 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed record class ExecuteOptions : BaseRecordOptions { [Display( + Name = nameof(Path), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ExecuteOptions_Path))] [Required] public string Path { get; set; } = string.Empty; [Display( + Name = nameof(Arguments), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ExecuteOptions_Arguments))] [ActionOptionsDependencyProperty] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/GetEnvironmentVariableOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/GetEnvironmentVariableOptions.cs index 67da644add3..887111c62b5 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/GetEnvironmentVariableOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/GetEnvironmentVariableOptions.cs @@ -17,6 +17,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed record class GetEnvironmentVariableOptions : BaseRecordOptions { [Display( + Name = nameof(Name), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_GetEnvironmentVariableOptions_Name))] [Required] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/LoadProfilerOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/LoadProfilerOptions.cs index d3f2fadba13..1ec2f24ee63 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/LoadProfilerOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/LoadProfilerOptions.cs @@ -18,12 +18,14 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed record class LoadProfilerOptions : BaseRecordOptions { [Display( + Name = nameof(Path), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoadProfilerOptions_Path))] [Required] public string Path { get; set; } = string.Empty; [Display( + Name = nameof(Clsid), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoadProfilerOptions_Clsid))] [Required] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/SetEnvironmentVariableOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/SetEnvironmentVariableOptions.cs index d9323b29bcc..88f9ff26aac 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/SetEnvironmentVariableOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/SetEnvironmentVariableOptions.cs @@ -19,12 +19,14 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed record class SetEnvironmentVariableOptions : BaseRecordOptions { [Display( + Name = nameof(Name), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_SetEnvironmentVariableOptions_Name))] [Required] public string Name { get; set; } = string.Empty; [Display( + Name = nameof(Value), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_SetEnvironmentVariableOptions_Value))] public string? Value { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/TraceEventFilter.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/TraceEventFilter.cs index ab7e874fc9f..6371fb113ab 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/TraceEventFilter.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/TraceEventFilter.cs @@ -20,18 +20,21 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed record class TraceEventFilter : BaseRecordOptions { [Display( + Name = nameof(ProviderName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_TraceEventFilter_ProviderName))] [Required] public string ProviderName { get; set; } = string.Empty; [Display( + Name = nameof(EventName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_TraceEventFilter_EventName))] [Required] public string EventName { get; set; } = string.Empty; [Display( + Name = nameof(PayloadFilter), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_TraceEventFilter_PayloadFilter))] public IDictionary? PayloadFilter { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionDefaultsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionDefaultsOptions.cs index f9978705d0b..9e4410b9737 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionDefaultsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionDefaultsOptions.cs @@ -11,6 +11,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed class CollectionRuleActionDefaultsOptions { [Display( + Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleActionDefaultsOptions_Egress))] public string? Egress { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.cs index 66e29494f0a..39199158033 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.cs @@ -17,22 +17,26 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed partial class CollectionRuleActionOptions { [Display( + Name = nameof(Name), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleActionOptions_Name))] public string? Name { get; set; } [Display( + Name = nameof(Type), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleActionOptions_Type))] [Required] public string Type { get; set; } = string.Empty; [Display( + Name = nameof(Settings), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleActionOptions_Settings))] public object? Settings { get; internal set; } [Display( + Name = nameof(WaitForCompletion), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleActionOptions_WaitForCompletion))] [DefaultValue(CollectionRuleActionOptionsDefaults.WaitForCompletion)] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleDefaultsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleDefaultsOptions.cs index 064d4ab8f9b..c3ac776599f 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleDefaultsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleDefaultsOptions.cs @@ -11,16 +11,19 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed class CollectionRuleDefaultsOptions { [Display( + Name = nameof(Triggers), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleDefaultsOptions_Triggers))] public CollectionRuleTriggerDefaultsOptions? Triggers { get; set; } [Display( + Name = nameof(Actions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleDefaultsOptions_Actions))] public CollectionRuleActionDefaultsOptions? Actions { get; set; } [Display( + Name = nameof(Limits), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleDefaultsOptions_Limits))] public CollectionRuleLimitsDefaultsOptions? Limits { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs index 64096acc700..50cc9392817 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs @@ -11,12 +11,14 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed class CollectionRuleLimitsDefaultsOptions { [Display( + Name = nameof(ActionCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsDefaultsOptions_ActionCount))] [Range(1, int.MaxValue)] public int? ActionCount { get; set; } [Display( + Name = nameof(ActionCountSlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsDefaultsOptions_ActionCountSlidingWindowDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MinValue, CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MaxValue)] @@ -24,6 +26,7 @@ internal sealed class CollectionRuleLimitsDefaultsOptions public TimeSpan? ActionCountSlidingWindowDuration { get; set; } [Display( + Name = nameof(RuleDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsDefaultsOptions_RuleDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.RuleDuration_MinValue, CollectionRuleOptionsConstants.RuleDuration_MaxValue)] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs index 74d657ce290..2d3318aff40 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs @@ -15,6 +15,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed class CollectionRuleLimitsOptions { [Display( + Name = nameof(ActionCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsOptions_ActionCount))] [DefaultValue(CollectionRuleLimitsOptionsDefaults.ActionCount)] @@ -22,6 +23,7 @@ internal sealed class CollectionRuleLimitsOptions public int? ActionCount { get; set; } [Display( + Name = nameof(ActionCountSlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsOptions_ActionCountSlidingWindowDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MinValue, CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MaxValue)] @@ -29,6 +31,7 @@ internal sealed class CollectionRuleLimitsOptions public TimeSpan? ActionCountSlidingWindowDuration { get; set; } [Display( + Name = nameof(RuleDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsOptions_RuleDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.RuleDuration_MinValue, CollectionRuleOptionsConstants.RuleDuration_MaxValue)] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs index 1f549d13b00..1debff00e3c 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs @@ -15,12 +15,14 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed partial class CollectionRuleOptions { [Display( + Name = nameof(Filters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Filters))] public List Filters { get; set; } = []; #nullable disable [Display( + Name = nameof(Trigger), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Trigger))] [Required] @@ -28,11 +30,13 @@ internal sealed partial class CollectionRuleOptions #nullable enable [Display( + Name = nameof(Actions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Actions))] public List Actions { get; set; } = []; [Display( + Name = nameof(Limits), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Limits))] public CollectionRuleLimitsOptions? Limits { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs index 59b4b5e4ebc..e466695de75 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs @@ -12,18 +12,21 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed class CollectionRuleTriggerDefaultsOptions { [Display( + Name = nameof(RequestCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleTriggerDefaultsOptions_RequestCount))] [Range(1, int.MaxValue)] public int? RequestCount { get; set; } [Display( + Name = nameof(ResponseCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleTriggerDefaultsOptions_ResponseCount))] [Range(1, int.MaxValue)] public int? ResponseCount { get; set; } [Display( + Name = nameof(SlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleTriggerDefaultsOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerOptions.cs index 6abf18ab2d0..3117a0bf5bf 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerOptions.cs @@ -16,12 +16,14 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed partial class CollectionRuleTriggerOptions { [Display( + Name = nameof(Type), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleTriggerOptions_Type))] [Required] public string Type { get; set; } = string.Empty; [Display( + Name = nameof(Settings), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleTriggerOptions_Settings))] public object? Settings { get; internal set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/TemplateOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/TemplateOptions.cs index 40b91ff4282..a634188271d 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/TemplateOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/TemplateOptions.cs @@ -15,21 +15,25 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed partial class TemplateOptions { [Display( + Name = nameof(CollectionRuleFilters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Filters))] public IDictionary? CollectionRuleFilters { get; set; } = new Dictionary(); [Display( + Name = nameof(CollectionRuleTriggers), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Trigger))] public IDictionary? CollectionRuleTriggers { get; set; } = new Dictionary(); [Display( + Name = nameof(CollectionRuleActions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Actions))] public IDictionary? CollectionRuleActions { get; set; } = new Dictionary(); [Display( + Name = nameof(CollectionRuleLimits), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Limits))] public IDictionary? CollectionRuleLimits { get; set; } = new Dictionary(); diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs index 973795d5bf7..bd6f59bb3d6 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs @@ -21,6 +21,7 @@ internal sealed partial class AspNetRequestCountOptions : IValidateOptions { [Display( + Name = nameof(RequestCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestCountOptions_RequestCount))] @@ -31,6 +32,7 @@ internal sealed partial class AspNetRequestCountOptions : public int RequestCount { get; set; } [Display( + Name = nameof(SlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestCountOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] @@ -40,6 +42,7 @@ internal sealed partial class AspNetRequestCountOptions : // CONSIDER: Currently described that paths have to exactly match one item in the list. // Consider allowing for wildcard/globbing to simplify list of matchable paths. [Display( + Name = nameof(IncludePaths), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestCountOptions_IncludePaths))] public string[]? IncludePaths { get; set; } @@ -47,6 +50,7 @@ internal sealed partial class AspNetRequestCountOptions : // CONSIDER: Currently described that paths have to exactly match one item in the list. // Consider allowing for wildcard/globbing to simplify list of matchable paths. [Display( + Name = nameof(ExcludePaths), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestCountOptions_ExcludePaths))] public string[]? ExcludePaths { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs index 3009fd19fd5..e796c1b639a 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs @@ -25,6 +25,7 @@ internal sealed partial class AspNetRequestDurationOptions : public const string RequestDuration_MinValue = "00:00:00"; [Display( + Name = nameof(RequestCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_RequestCount))] @@ -35,6 +36,7 @@ internal sealed partial class AspNetRequestDurationOptions : public int RequestCount { get; set; } [Display( + Name = nameof(RequestDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_RequestDuration))] [DefaultValue(AspNetRequestDurationOptionsDefaults.RequestDuration)] @@ -43,6 +45,7 @@ internal sealed partial class AspNetRequestDurationOptions : public TimeSpan? RequestDuration { get; set; } [Display( + Name = nameof(SlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] @@ -52,6 +55,7 @@ internal sealed partial class AspNetRequestDurationOptions : // CONSIDER: Currently described that paths have to exactly match one item in the list. // Consider allowing for wildcard/globbing to simplify list of matchable paths. [Display( + Name = nameof(IncludePaths), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_IncludePaths))] public string[]? IncludePaths { get; set; } @@ -59,6 +63,7 @@ internal sealed partial class AspNetRequestDurationOptions : // CONSIDER: Currently described that paths have to exactly match one item in the list. // Consider allowing for wildcard/globbing to simplify list of matchable paths. [Display( + Name = nameof(ExcludePaths), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_ExcludePaths))] public string[]? ExcludePaths { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs index abeb51e0e87..0feb7ca228b 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs @@ -25,6 +25,7 @@ internal sealed partial class AspNetResponseStatusOptions : #nullable disable [Display( + Name = nameof(StatusCodes), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_StatusCodes))] [Required] @@ -37,6 +38,7 @@ internal sealed partial class AspNetResponseStatusOptions : #nullable enable [Display( + Name = nameof(ResponseCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_ResponseCount))] @@ -47,6 +49,7 @@ internal sealed partial class AspNetResponseStatusOptions : public int ResponseCount { get; set; } [Display( + Name = nameof(SlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] @@ -56,6 +59,7 @@ internal sealed partial class AspNetResponseStatusOptions : // CONSIDER: Currently described that paths have to exactly match one item in the list. // Consider allowing for wildcard/globbing to simplify list of matchable paths. [Display( + Name = nameof(IncludePaths), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_IncludePaths))] public string[]? IncludePaths { get; set; } @@ -63,6 +67,7 @@ internal sealed partial class AspNetResponseStatusOptions : // CONSIDER: Currently described that paths have to exactly match one item in the list. // Consider allowing for wildcard/globbing to simplify list of matchable paths. [Display( + Name = nameof(ExcludePaths), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_ExcludePaths))] public string[]? ExcludePaths { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs index 6b68b783c7e..c31304a1f82 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs @@ -17,28 +17,33 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers internal sealed partial class EventCounterOptions : IValidateOptions, ISlidingWindowDurationProperties { [Display( + Name = nameof(ProviderName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_ProviderName))] [Required] public string ProviderName { get; set; } = string.Empty; [Display( + Name = nameof(CounterName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_CounterName))] [Required] public string CounterName { get; set; } = string.Empty; [Display( + Name = nameof(GreaterThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_GreaterThan))] public double? GreaterThan { get; set; } [Display( + Name = nameof(LessThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_LessThan))] public double? LessThan { get; set; } [Display( + Name = nameof(SlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs index d67f7c8edac..fe048c53d0e 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs @@ -18,6 +18,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.E internal sealed partial class CPUUsageOptions : IValidateOptions, IEventCounterShortcuts, ISlidingWindowDurationProperties { [Display( + Name = nameof(GreaterThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CPUUsageOptions_GreaterThan))] [DefaultValue(CPUUsageOptionsDefaults.GreaterThan)] @@ -25,12 +26,14 @@ internal sealed partial class CPUUsageOptions : IValidateOptions, IEventCounterShortcuts, ISlidingWindowDurationProperties { [Display( + Name = nameof(GreaterThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_GCHeapSizeOptions_GreaterThan))] [DefaultValue(GCHeapSizeOptionsDefaults.GreaterThan)] @@ -25,12 +26,14 @@ internal sealed partial class GCHeapSizeOptions : IValidateOptions, IEventCounterShortcuts, ISlidingWindowDurationProperties { [Display( + Name = nameof(GreaterThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ThreadpoolQueueLengthOptions_GreaterThan))] [DefaultValue(ThreadpoolQueueLengthOptionsDefaults.GreaterThan)] @@ -25,13 +26,14 @@ internal sealed partial class ThreadpoolQueueLengthOptions : IValidateOptions, ISlidingWindowDurationProperties { [Display( + Name = nameof(MeterName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventMeterOptions_MeterName))] [Required] public string MeterName { get; set; } = string.Empty; [Display( + Name = nameof(InstrumentName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventMeterOptions_InstrumentName))] [Required] public string InstrumentName { get; set; } = string.Empty; [Display( + Name = nameof(GreaterThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventMeterOptions_GreaterThan))] public double? GreaterThan { get; set; } [Display( + Name = nameof(LessThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventMeterOptions_LessThan))] public double? LessThan { get; set; } [Display( + Name = nameof(SlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventMeterOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] @@ -46,6 +51,7 @@ internal sealed partial class EventMeterOptions : IValidateOptions Date: Mon, 21 Apr 2025 23:05:28 +0000 Subject: [PATCH 136/174] Fix more failures - Move type info to UnitTestsCommon - Handle registered action options in ActionDependencyAnalyzer --- .../TestHostHelper.cs | 1 + .../TestValidatableType.cs | 17 +- .../ValidatableInfoResolver.cs | 388 +++- .../ActionDependencyAnalyzerTests.cs | 18 +- .../CollectionRuleDescriptionPipelineTests.cs | 3 + .../CollectionRulePipelineTests.cs | 5 + .../TestValidatableTypes.cs | 51 - .../ValidatableInfoResolver.cs | 1689 ----------------- ...ics.Monitoring.Tool.UnitTestsSample.csproj | 20 + .../ValidatableInfoResolver.cs | 790 ++++++++ .../CollectionRules/ActionListExecutor.cs | 2 +- .../ActionOptionsDependencyAnalyzer.cs | 19 +- .../Actions/CollectionRuleActionOperations.cs | 15 + .../ICollectionRuleActionOperations.cs | 9 + .../CollectionRuleActionOptions.Validate.cs | 2 +- .../dotnet-monitor/CommonOptionsMapper.cs | 88 +- 16 files changed, 1280 insertions(+), 1837 deletions(-) rename src/Tests/{CollectionRuleActions.UnitTests => Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon}/TestValidatableType.cs (71%) rename src/Tests/{CollectionRuleActions.UnitTests => Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon}/ValidatableInfoResolver.cs (82%) delete mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/TestValidatableTypes.cs delete mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ValidatableInfoResolver.cs create mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs index bef5038156b..98d65a2919e 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs @@ -127,6 +127,7 @@ public static IHost CreateHost( services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + TestValidatableTypes.AddValidation(services); servicesCallback?.Invoke(services); }) .Build(); diff --git a/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs similarity index 71% rename from src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs index bf2e597118b..7093325e55c 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/TestValidatableType.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs @@ -4,12 +4,14 @@ using Microsoft.AspNetCore.Http.Validation; using Microsoft.AspNetCore.Http.Validation.Generated; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; -namespace Microsoft.Diagnostics.Tools.Monitor +namespace Microsoft.Diagnostics.Monitoring.TestCommon { // The Validation source generator doesn't run for libraries that don't call AddValidation, // so we can't generate IValidatableInfo by using [ValidatableType] directly on types defined @@ -34,6 +36,8 @@ internal sealed class TestValidatableTypes public required CollectLiveMetricsOptions CollectLiveMetricsOptions { get; init; } + public required CollectStacksOptions CollectStacksOptions { get; init; } + public required RootOptions RootOptions { get; init; } public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } @@ -42,6 +46,17 @@ internal sealed class TestValidatableTypes public required LoadProfilerOptions LoadProfilerOptions { get; init; } + public required CollectExceptionsOptions CollectExceptionsOptions { get; init; } + + // Triggers... + public required AspNetRequestDurationOptions AspNetRequestDurationOptions { get; init; } + public required AspNetRequestCountOptions AspNetRequestCountOptions { get; init; } + public required AspNetResponseStatusOptions AspNetResponseStatusOptions { get; init; } + + // TODO: only one resolver per project? Generate this for tests, for now. Maybe want to separate this one out + // by test later. + public required PassThroughOptions PassThroughOptions { get; init; } + public static void AddValidation(IServiceCollection services) { GeneratedServiceCollectionExtensions.AddValidation(services); diff --git a/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs similarity index 82% rename from src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs rename to src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs index 568bb83794e..5e89d3cf931 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ValidatableInfoResolver.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs @@ -209,6 +209,11 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateCollectLiveMetricsOptions(); return true; } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions)) + { + validatableInfo = CreateCollectStacksOptions(); + return true; + } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions)) { validatableInfo = CreateMonitorApiKeyOptions(); @@ -304,7 +309,32 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateLoadProfilerOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions)) + { + validatableInfo = CreateCollectExceptionsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions)) + { + validatableInfo = CreateAspNetRequestDurationOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions)) + { + validatableInfo = CreateAspNetRequestCountOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions)) + { + validatableInfo = CreateAspNetResponseStatusOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions)) + { + validatableInfo = CreatePassThroughOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes)) { validatableInfo = CreateTestValidatableTypes(); return true; @@ -329,7 +359,7 @@ private ValidatableTypeInfo CreateCollectionRuleTriggerOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), propertyType: typeof(string), name: "Type", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings1" + displayName: "Type" ), ] ); @@ -343,7 +373,7 @@ private ValidatableTypeInfo CreateCollectionRuleActionOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), propertyType: typeof(string), name: "Type", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings2" + displayName: "Type" ), ] ); @@ -357,19 +387,19 @@ private ValidatableTypeInfo CreateCollectionRuleLimitsOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), propertyType: typeof(int?), name: "ActionCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings3" + displayName: "ActionCount" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), propertyType: typeof(global::System.TimeSpan?), name: "ActionCountSlidingWindowDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings4" + displayName: "ActionCountSlidingWindowDuration" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), propertyType: typeof(global::System.TimeSpan?), name: "RuleDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings5" + displayName: "RuleDuration" ), ] ); @@ -383,19 +413,19 @@ private ValidatableTypeInfo CreateCollectionRuleOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), name: "Trigger", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings6" + displayName: "Trigger" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), propertyType: typeof(global::System.Collections.Generic.List), name: "Actions", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings7" + displayName: "Actions" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), name: "Limits", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings8" + displayName: "Limits" ), ] ); @@ -904,7 +934,7 @@ private ValidatableTypeInfo CreateExecuteOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), propertyType: typeof(string), name: "Path", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings9" + displayName: "Path" ), ] ); @@ -924,7 +954,7 @@ private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), propertyType: typeof(string), name: "Name", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings10" + displayName: "Name" ), ] ); @@ -944,7 +974,7 @@ private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), propertyType: typeof(string), name: "Name", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings11" + displayName: "Name" ), ] ); @@ -978,19 +1008,19 @@ private ValidatableTypeInfo CreateTraceEventFilter() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), propertyType: typeof(string), name: "ProviderName", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings12" + displayName: "ProviderName" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), propertyType: typeof(string), name: "EventName", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings13" + displayName: "EventName" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "PayloadFilter", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings14" + displayName: "PayloadFilter" ), ] ); @@ -1010,31 +1040,31 @@ private ValidatableTypeInfo CreateCollectTraceOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.TraceProfile?), name: "Profile", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings15" + displayName: "Profile" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), propertyType: typeof(int?), name: "BufferSizeMegabytes", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings16" + displayName: "BufferSizeMegabytes" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), propertyType: typeof(global::System.TimeSpan?), name: "Duration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings17" + displayName: "Duration" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), propertyType: typeof(string), name: "Egress", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings18" + displayName: "Egress" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), name: "StoppingEvent", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings19" + displayName: "StoppingEvent" ), ] ); @@ -1048,25 +1078,25 @@ private ValidatableTypeInfo CreateGlobalCounterOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), propertyType: typeof(float?), name: "IntervalSeconds", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings20" + displayName: "IntervalSeconds" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), propertyType: typeof(int?), name: "MaxHistograms", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings21" + displayName: "MaxHistograms" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), propertyType: typeof(int?), name: "MaxTimeSeries", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings22" + displayName: "MaxTimeSeries" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "Providers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings23" + displayName: "Providers" ), ] ); @@ -1086,7 +1116,7 @@ private ValidatableTypeInfo CreateCollectGCDumpOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), propertyType: typeof(string), name: "Egress", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings24" + displayName: "Egress" ), ] ); @@ -1106,13 +1136,33 @@ private ValidatableTypeInfo CreateCollectLiveMetricsOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), propertyType: typeof(global::System.TimeSpan?), name: "Duration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings25" + displayName: "Duration" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), propertyType: typeof(string), name: "Egress", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings26" + displayName: "Egress" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectStacksOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" ), ] ); @@ -1126,13 +1176,13 @@ private ValidatableTypeInfo CreateMonitorApiKeyOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), propertyType: typeof(string), name: "Subject", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings27" + displayName: "Subject" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), propertyType: typeof(string), name: "PublicKey", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings28" + displayName: "PublicKey" ), ] ); @@ -1146,25 +1196,25 @@ private ValidatableTypeInfo CreateAzureAdOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), propertyType: typeof(string), name: "TenantId", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings29" + displayName: "TenantId" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), propertyType: typeof(string), name: "ClientId", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings30" + displayName: "ClientId" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), propertyType: typeof(global::System.Uri), name: "AppIdUri", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings31" + displayName: "AppIdUri" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), propertyType: typeof(string), name: "RequiredRole", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings32" + displayName: "RequiredRole" ), ] ); @@ -1178,13 +1228,13 @@ private ValidatableTypeInfo CreateAuthenticationOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), name: "MonitorApiKey", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings33" + displayName: "MonitorApiKey" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), name: "AzureAd", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings34" + displayName: "AzureAd" ), ] ); @@ -1212,13 +1262,13 @@ private ValidatableTypeInfo CreateExceptionsOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), propertyType: typeof(int?), name: "TopLevelLimit", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings35" + displayName: "TopLevelLimit" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), name: "CollectionFilters", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings36" + displayName: "CollectionFilters" ), ] ); @@ -1232,7 +1282,7 @@ private ValidatableTypeInfo CreateInProcessFeaturesOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), name: "Exceptions", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings37" + displayName: "Exceptions" ), ] ); @@ -1246,7 +1296,7 @@ private ValidatableTypeInfo CreateCorsConfigurationOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), propertyType: typeof(string), name: "AllowedOrigins", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings38" + displayName: "AllowedOrigins" ), ] ); @@ -1260,13 +1310,13 @@ private ValidatableTypeInfo CreateEgressOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "FileSystem", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings39" + displayName: "FileSystem" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "Properties", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings40" + displayName: "Properties" ), ] ); @@ -1280,7 +1330,7 @@ private ValidatableTypeInfo CreateMetricProvider() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), propertyType: typeof(string), name: "ProviderName", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings41" + displayName: "ProviderName" ), ] ); @@ -1294,13 +1344,13 @@ private ValidatableTypeInfo CreateMetricsOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), propertyType: typeof(int?), name: "MetricCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings42" + displayName: "MetricCount" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), propertyType: typeof(global::System.Collections.Generic.List), name: "Providers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings43" + displayName: "Providers" ), ] ); @@ -1314,7 +1364,7 @@ private ValidatableTypeInfo CreateProcessFilterOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), propertyType: typeof(global::System.Collections.Generic.List), name: "Filters", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings44" + displayName: "Filters" ), ] ); @@ -1328,19 +1378,19 @@ private ValidatableTypeInfo CreateCollectionRuleTriggerDefaultsOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), propertyType: typeof(int?), name: "RequestCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings45" + displayName: "RequestCount" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), propertyType: typeof(int?), name: "ResponseCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings46" + displayName: "ResponseCount" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), propertyType: typeof(global::System.TimeSpan?), name: "SlidingWindowDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings47" + displayName: "SlidingWindowDuration" ), ] ); @@ -1354,19 +1404,19 @@ private ValidatableTypeInfo CreateCollectionRuleLimitsDefaultsOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), propertyType: typeof(int?), name: "ActionCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings48" + displayName: "ActionCount" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), propertyType: typeof(global::System.TimeSpan?), name: "ActionCountSlidingWindowDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings49" + displayName: "ActionCountSlidingWindowDuration" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), propertyType: typeof(global::System.TimeSpan?), name: "RuleDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings50" + displayName: "RuleDuration" ), ] ); @@ -1380,13 +1430,13 @@ private ValidatableTypeInfo CreateCollectionRuleDefaultsOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), name: "Triggers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings51" + displayName: "Triggers" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), name: "Limits", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings52" + displayName: "Limits" ), ] ); @@ -1400,25 +1450,25 @@ private ValidatableTypeInfo CreateTemplateOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "CollectionRuleFilters", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings53" + displayName: "CollectionRuleFilters" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "CollectionRuleTriggers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings54" + displayName: "CollectionRuleTriggers" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "CollectionRuleActions", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings55" + displayName: "CollectionRuleActions" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), propertyType: typeof(global::System.Collections.Generic.IDictionary), name: "CollectionRuleLimits", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings56" + displayName: "CollectionRuleLimits" ), ] ); @@ -1500,13 +1550,13 @@ private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), propertyType: typeof(string), name: "DirectoryPath", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings57" + displayName: "DirectoryPath" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), propertyType: typeof(int?), name: "CopyBufferSize", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings58" + displayName: "CopyBufferSize" ), ] ); @@ -1526,13 +1576,13 @@ private ValidatableTypeInfo CreateCollectDumpOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.DumpType?), name: "Type", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings59" + displayName: "Type" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), propertyType: typeof(string), name: "Egress", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings60" + displayName: "Egress" ), ] ); @@ -1552,94 +1602,278 @@ private ValidatableTypeInfo CreateLoadProfilerOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), propertyType: typeof(string), name: "Path", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings61" + displayName: "Path" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), propertyType: typeof(global::System.Guid), name: "Clsid", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings62" + displayName: "Clsid" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectExceptionsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + name: "Filters", + displayName: "Filters" ), ] ); } + private ValidatableTypeInfo CreateAspNetRequestDurationOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(int), + name: "RequestCount", + displayName: "RequestCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RequestDuration", + displayName: "RequestDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(string[]), + name: "IncludePaths", + displayName: "IncludePaths" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(string[]), + name: "ExcludePaths", + displayName: "ExcludePaths" + ), + ] + ); + } + private ValidatableTypeInfo CreateAspNetRequestCountOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + propertyType: typeof(int), + name: "RequestCount", + displayName: "RequestCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + propertyType: typeof(string[]), + name: "IncludePaths", + displayName: "IncludePaths" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + propertyType: typeof(string[]), + name: "ExcludePaths", + displayName: "ExcludePaths" + ), + ] + ); + } + private ValidatableTypeInfo CreateAspNetResponseStatusOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(string[]), + name: "StatusCodes", + displayName: "StatusCodes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(int), + name: "ResponseCount", + displayName: "ResponseCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(string[]), + name: "IncludePaths", + displayName: "IncludePaths" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(string[]), + name: "ExcludePaths", + displayName: "ExcludePaths" + ), + ] + ); + } + private ValidatableTypeInfo CreatePassThroughOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + ] + ); + } private ValidatableTypeInfo CreateTestValidatableTypes() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + type: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), name: "CollectionRuleOptions", displayName: "CollectionRuleOptions" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), name: "ExecuteOptions", displayName: "ExecuteOptions" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), name: "SetEnvironmentVariableOptions", displayName: "SetEnvironmentVariableOptions" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), name: "GetEnvironmentVariableOptions", displayName: "GetEnvironmentVariableOptions" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), name: "CollectTraceOptions", displayName: "CollectTraceOptions" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), name: "GlobalCounterOptions", displayName: "GlobalCounterOptions" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), name: "CollectGCDumpOptions", displayName: "CollectGCDumpOptions" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), name: "CollectLiveMetricsOptions", displayName: "CollectLiveMetricsOptions" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + name: "CollectStacksOptions", + displayName: "CollectStacksOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), name: "RootOptions", displayName: "RootOptions" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), name: "FileSystemEgressProviderOptions", displayName: "FileSystemEgressProviderOptions" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), name: "CollectDumpOptions", displayName: "CollectDumpOptions" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), name: "LoadProfilerOptions", displayName: "LoadProfilerOptions" ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + name: "CollectExceptionsOptions", + displayName: "CollectExceptionsOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + name: "AspNetRequestDurationOptions", + displayName: "AspNetRequestDurationOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + name: "AspNetRequestCountOptions", + displayName: "AspNetRequestCountOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + name: "AspNetResponseStatusOptions", + displayName: "AspNetResponseStatusOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), + name: "PassThroughOptions", + displayName: "PassThroughOptions" + ), ] ); } @@ -1649,7 +1883,7 @@ private ValidatableTypeInfo CreateTestValidatableTypes() [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] internal static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "tmDjl/scvJBp7h4Jis0nT+NkAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "tJYY5rjIqR+TnT4DExGdC8ipAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs index 41da3de3ff7..d27e9847ac9 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs @@ -136,6 +136,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(); + TestValidatableTypes.AddValidation(serviceCollection); }); } @@ -157,6 +158,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => CollectionRuleOptions ruleOptions = host.Services.GetRequiredService>().Get(DefaultRuleName); ILogger logger = host.Services.GetRequiredService>(); TimeProvider timeProvider = host.Services.GetRequiredService(); + ICollectionRuleActionOperations actionOperations = host.Services.GetRequiredService(); const string processName = "actionProcess"; const int processId = 123; @@ -165,7 +167,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => Guid instanceId = Guid.NewGuid(); CollectionRuleContext context = new(DefaultRuleName, ruleOptions, new TestProcessInfo(instanceId, processId: processId, commandLine: commandLine), HostInfo.GetCurrent(timeProvider), logger); - ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); + ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context, actionOperations); PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, actionOptions); Assert.Equal(processName, newSettings.Input1); @@ -175,6 +177,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(); + TestValidatableTypes.AddValidation(serviceCollection); }); } @@ -196,13 +199,14 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => CollectionRuleOptions ruleOptions = host.Services.GetRequiredService>().Get(DefaultRuleName); ILogger logger = host.Services.GetRequiredService>(); MockTimeProvider timeProvider = host.Services.GetRequiredService() as MockTimeProvider; + ICollectionRuleActionOperations actionOperations = host.Services.GetRequiredService(); const string hostName = "exampleHost"; Guid instanceId = Guid.NewGuid(); HostInfo hostInfo = new HostInfo(hostName, timeProvider); CollectionRuleContext context = new(DefaultRuleName, ruleOptions, new TestProcessInfo(instanceId), hostInfo, logger); - ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); + ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context, actionOperations); PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, actionOptions); Assert.Equal(hostName, newSettings.Input1); @@ -212,6 +216,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { serviceCollection.AddSingleton(); serviceCollection.RegisterCollectionRuleAction(); + TestValidatableTypes.AddValidation(serviceCollection); }); } @@ -239,11 +244,12 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => CollectionRuleOptions ruleOptions = host.Services.GetRequiredService>().Get(DefaultRuleName); ILogger logger = host.Services.GetRequiredService>(); TimeProvider timeProvider = host.Services.GetRequiredService(); + ICollectionRuleActionOperations actionOperations = host.Services.GetRequiredService(); Guid instanceId = Guid.NewGuid(); CollectionRuleContext context = new(DefaultRuleName, ruleOptions, new TestProcessInfo(instanceId), HostInfo.GetCurrent(timeProvider), logger); - ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); + ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context, actionOperations); analyzer.GetActionDependencies(1); analyzer.SubstituteOptionValues(new Dictionary(), 1, actionOptions); @@ -255,6 +261,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(); + TestValidatableTypes.AddValidation(serviceCollection); }, loggingBuilder => { loggingBuilder.AddProvider(new TestLoggerProvider(record)); @@ -279,11 +286,12 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => CollectionRuleOptions ruleOptions = host.Services.GetRequiredService>().Get(DefaultRuleName); ILogger logger = host.Services.GetRequiredService>(); TimeProvider timeProvider = host.Services.GetRequiredService(); + ICollectionRuleActionOperations actionOperations = host.Services.GetRequiredService(); Guid instanceId = Guid.NewGuid(); CollectionRuleContext context = new(DefaultRuleName, ruleOptions, new TestProcessInfo(instanceId), HostInfo.GetCurrent(timeProvider), logger); - ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); + ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context, actionOperations); PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, actionOptions); Assert.Equal(instanceId.ToString("D"), newSettings.Input1); @@ -291,6 +299,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(); + TestValidatableTypes.AddValidation(serviceCollection); }); } @@ -353,6 +362,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(); + TestValidatableTypes.AddValidation(serviceCollection); }); } } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs index ef52703ebb9..d799d54325c 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs @@ -92,6 +92,7 @@ public Task CollectionRuleDescriptionPipeline_StartupTriggerTest(TargetFramework services => { services.RegisterTestAction(callbackService); + TestValidatableTypes.AddValidation(services); }); } @@ -292,6 +293,7 @@ await CollectionRulePipelineTestsHelper.ManualTriggerAsync( services.AddSingleton(timeProvider); services.RegisterManualTrigger(triggerService); services.RegisterTestAction(callbackService); + TestValidatableTypes.AddValidation(services); }); } @@ -408,6 +410,7 @@ await CollectionRulePipelineTestsHelper.ManualTriggerAsync( services.AddSingleton(timeProvider); services.RegisterManualTrigger(triggerService); services.RegisterTestAction(callbackService); + TestValidatableTypes.AddValidation(services); }); } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs index 75ca11aca3d..2f2b8a276c0 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs @@ -6,6 +6,7 @@ using Microsoft.Diagnostics.Monitoring.TestCommon.Runners; using Microsoft.Diagnostics.Monitoring.Tool.UnitTests.CollectionRules.Triggers; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; @@ -94,6 +95,7 @@ public Task CollectionRulePipeline_StartupTriggerTest(TargetFrameworkMoniker app services => { services.RegisterTestAction(callbackService); + TestValidatableTypes.AddValidation(services); }); } @@ -223,6 +225,7 @@ public Task CollectionRulePipeline_EventMeterTriggerTest_Gauge(TargetFrameworkMo services => { services.RegisterTestAction(callbackService); + TestValidatableTypes.AddValidation(services); }); } @@ -398,6 +401,7 @@ public Task CollectionRulePipeline_DurationLimitTest(TargetFrameworkMoniker appT { services.RegisterManualTrigger(triggerService); services.RegisterTestAction(callbackService); + TestValidatableTypes.AddValidation(services); }); } @@ -461,6 +465,7 @@ await CollectionRulePipelineTestsHelper.ManualTriggerAsync( services.AddSingleton(timeProvider); services.RegisterManualTrigger(triggerService); services.RegisterTestAction(callbackService); + TestValidatableTypes.AddValidation(services); }); } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/TestValidatableTypes.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/TestValidatableTypes.cs deleted file mode 100644 index a5fc49619c6..00000000000 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/TestValidatableTypes.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.AspNetCore.Http.Validation; -using Microsoft.AspNetCore.Http.Validation.Generated; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; -using Microsoft.Diagnostics.Monitoring.WebApi; -using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; - -namespace Microsoft.Diagnostics.Tools.Monitor -{ - // The Validation source generator doesn't run for libraries that don't call AddValidation, - // so we can't generate IValidatableInfo by using [ValidatableType] directly on types defined - // in ProjectReferences. This is a workaround to force the generator running in this project to - // generate IValidatableInfo for the referenced types. The containing class is not used otherwise. - [ValidatableType] - internal sealed class TestValidatableTypes - { - public required CollectionRuleOptions CollectionRuleOptions { get; init; } - - public required ExecuteOptions ExecuteOptions { get; init; } - - public required SetEnvironmentVariableOptions SetEnvironmentVariableOptions { get; init; } - - public required GetEnvironmentVariableOptions GetEnvironmentVariableOptions { get; init; } - - public required CollectTraceOptions CollectTraceOptions { get; init; } - - public required GlobalCounterOptions GlobalCounterOptions { get; init; } - - public required CollectGCDumpOptions CollectGCDumpOptions { get; init; } - - public required CollectLiveMetricsOptions CollectLiveMetricsOptions { get; init; } - - public required RootOptions RootOptions { get; init; } - - public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } - - public required CollectDumpOptions CollectDumpOptions { get; init; } - - public required LoadProfilerOptions LoadProfilerOptions { get; init; } - - public static void AddValidation(IServiceCollection services) - { - GeneratedServiceCollectionExtensions.AddValidation(services); - // services.AddValidation(); - } - } -} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ValidatableInfoResolver.cs deleted file mode 100644 index ae0af988787..00000000000 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ValidatableInfoResolver.cs +++ /dev/null @@ -1,1689 +0,0 @@ -#nullable enable annotations -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ -#nullable enable - -namespace System.Runtime.CompilerServices -{ - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] - file sealed class InterceptsLocationAttribute : System.Attribute - { - public InterceptsLocationAttribute(int version, string data) - { - } - } -} - -namespace Microsoft.AspNetCore.Http.Validation.Generated -{ - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - file sealed class GeneratedValidatablePropertyInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatablePropertyInfo - { - public GeneratedValidatablePropertyInfo( - [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] - global::System.Type containingType, - global::System.Type propertyType, - string name, - string displayName) : base(containingType, propertyType, name, displayName) - { - ContainingType = containingType; - Name = name; - } - - internal global::System.Type ContainingType { get; } - internal string Name { get; } - - protected override global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes() - => ValidationAttributeCache.GetValidationAttributes(ContainingType, Name); - } - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - file sealed class GeneratedValidatableTypeInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatableTypeInfo - { - public GeneratedValidatableTypeInfo( - [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.Interfaces)] - global::System.Type type, - ValidatablePropertyInfo[] members) : base(type, members) { } - } - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - file class GeneratedValidatableInfoResolver : global::Microsoft.AspNetCore.Http.Validation.IValidatableInfoResolver - { - public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) - { - validatableInfo = null; - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions)) - { - validatableInfo = CreateCollectionRuleTriggerOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions)) - { - validatableInfo = CreateCollectionRuleActionOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions)) - { - validatableInfo = CreateCollectionRuleLimitsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions)) - { - validatableInfo = CreateCollectionRuleOptions(); - return true; - } - if (type == typeof(global::System.Reflection.MethodBase)) - { - validatableInfo = CreateMethodBase(); - return true; - } - if (type == typeof(global::System.Reflection.ConstructorInfo)) - { - validatableInfo = CreateConstructorInfo(); - return true; - } - if (type == typeof(global::System.Reflection.CustomAttributeTypedArgument)) - { - validatableInfo = CreateCustomAttributeTypedArgument(); - return true; - } - if (type == typeof(global::System.Reflection.CustomAttributeNamedArgument)) - { - validatableInfo = CreateCustomAttributeNamedArgument(); - return true; - } - if (type == typeof(global::System.Reflection.CustomAttributeData)) - { - validatableInfo = CreateCustomAttributeData(); - return true; - } - if (type == typeof(global::System.Reflection.ParameterInfo)) - { - validatableInfo = CreateParameterInfo(); - return true; - } - if (type == typeof(global::System.Reflection.MethodInfo)) - { - validatableInfo = CreateMethodInfo(); - return true; - } - if (type == typeof(global::System.Reflection.EventInfo)) - { - validatableInfo = CreateEventInfo(); - return true; - } - if (type == typeof(global::System.Reflection.FieldInfo)) - { - validatableInfo = CreateFieldInfo(); - return true; - } - if (type == typeof(global::System.Reflection.PropertyInfo)) - { - validatableInfo = CreatePropertyInfo(); - return true; - } - if (type == typeof(global::System.Reflection.TypeInfo)) - { - validatableInfo = CreateTypeInfo(); - return true; - } - if (type == typeof(global::System.Reflection.Assembly)) - { - validatableInfo = CreateAssembly(); - return true; - } - if (type == typeof(global::System.Guid)) - { - validatableInfo = CreateGuid(); - return true; - } - if (type == typeof(global::System.Reflection.Module)) - { - validatableInfo = CreateModule(); - return true; - } - if (type == typeof(global::System.Reflection.MemberInfo)) - { - validatableInfo = CreateMemberInfo(); - return true; - } - if (type == typeof(global::System.Type)) - { - validatableInfo = CreateType(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions)) - { - validatableInfo = CreateBaseRecordOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions)) - { - validatableInfo = CreateExecuteOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions)) - { - validatableInfo = CreateSetEnvironmentVariableOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions)) - { - validatableInfo = CreateGetEnvironmentVariableOptions(); - return true; - } - if (type == typeof(global::System.Collections.Generic.IDictionary)) - { - validatableInfo = CreateIDictionary_string_string(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter)) - { - validatableInfo = CreateTraceEventFilter(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions)) - { - validatableInfo = CreateCollectTraceOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions)) - { - validatableInfo = CreateGlobalCounterOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions)) - { - validatableInfo = CreateCollectGCDumpOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions)) - { - validatableInfo = CreateCollectLiveMetricsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions)) - { - validatableInfo = CreateMonitorApiKeyOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions)) - { - validatableInfo = CreateAzureAdOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions)) - { - validatableInfo = CreateAuthenticationOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration)) - { - validatableInfo = CreateExceptionsConfiguration(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions)) - { - validatableInfo = CreateExceptionsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions)) - { - validatableInfo = CreateInProcessFeaturesOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions)) - { - validatableInfo = CreateCorsConfigurationOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions)) - { - validatableInfo = CreateEgressOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider)) - { - validatableInfo = CreateMetricProvider(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions)) - { - validatableInfo = CreateMetricsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions)) - { - validatableInfo = CreateProcessFilterOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions)) - { - validatableInfo = CreateCollectionRuleTriggerDefaultsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions)) - { - validatableInfo = CreateCollectionRuleLimitsDefaultsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions)) - { - validatableInfo = CreateCollectionRuleDefaultsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions)) - { - validatableInfo = CreateTemplateOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions)) - { - validatableInfo = CreateRootOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions)) - { - validatableInfo = CreateFileSystemEgressProviderOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions)) - { - validatableInfo = CreateCollectDumpOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions)) - { - validatableInfo = CreateLoadProfilerOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes)) - { - validatableInfo = CreateTestValidatableTypes(); - return true; - } - - return false; - } - - // No-ops, rely on runtime code for ParameterInfo-based resolution - public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterInfo parameterInfo, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) - { - validatableInfo = null; - return false; - } - - private ValidatableTypeInfo CreateCollectionRuleTriggerOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), - propertyType: typeof(string), - name: "Type", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings1" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectionRuleActionOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), - propertyType: typeof(string), - name: "Type", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings2-tools.unittests" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectionRuleLimitsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - propertyType: typeof(int?), - name: "ActionCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings3" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "ActionCountSlidingWindowDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings4" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "RuleDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings5" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectionRuleOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), - name: "Trigger", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings6" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - propertyType: typeof(global::System.Collections.Generic.List), - name: "Actions", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings7" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - name: "Limits", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings8" - ), - ] - ); - } - private ValidatableTypeInfo CreateMethodBase() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.MethodBase), - members: [] - ); - } - private ValidatableTypeInfo CreateConstructorInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.ConstructorInfo), - members: [] - ); - } - private ValidatableTypeInfo CreateCustomAttributeTypedArgument() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.CustomAttributeTypedArgument), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeTypedArgument), - propertyType: typeof(global::System.Type), - name: "ArgumentType", - displayName: "ArgumentType" - ), - ] - ); - } - private ValidatableTypeInfo CreateCustomAttributeNamedArgument() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.CustomAttributeNamedArgument), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), - propertyType: typeof(global::System.Reflection.MemberInfo), - name: "MemberInfo", - displayName: "MemberInfo" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), - propertyType: typeof(global::System.Reflection.CustomAttributeTypedArgument), - name: "TypedValue", - displayName: "TypedValue" - ), - ] - ); - } - private ValidatableTypeInfo CreateCustomAttributeData() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.CustomAttributeData), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeData), - propertyType: typeof(global::System.Type), - name: "AttributeType", - displayName: "AttributeType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeData), - propertyType: typeof(global::System.Reflection.ConstructorInfo), - name: "Constructor", - displayName: "Constructor" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeData), - propertyType: typeof(global::System.Collections.Generic.IList), - name: "ConstructorArguments", - displayName: "ConstructorArguments" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeData), - propertyType: typeof(global::System.Collections.Generic.IList), - name: "NamedArguments", - displayName: "NamedArguments" - ), - ] - ); - } - private ValidatableTypeInfo CreateParameterInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.ParameterInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.ParameterInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "CustomAttributes", - displayName: "CustomAttributes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.ParameterInfo), - propertyType: typeof(global::System.Reflection.MemberInfo), - name: "Member", - displayName: "Member" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.ParameterInfo), - propertyType: typeof(global::System.Type), - name: "ParameterType", - displayName: "ParameterType" - ), - ] - ); - } - private ValidatableTypeInfo CreateMethodInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.MethodInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MethodInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MethodInfo), - propertyType: typeof(global::System.Reflection.ParameterInfo), - name: "ReturnParameter", - displayName: "ReturnParameter" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MethodInfo), - propertyType: typeof(global::System.Type), - name: "ReturnType", - displayName: "ReturnType" - ), - ] - ); - } - private ValidatableTypeInfo CreateEventInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.EventInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "AddMethod", - displayName: "AddMethod" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Type), - name: "EventHandlerType", - displayName: "EventHandlerType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "RaiseMethod", - displayName: "RaiseMethod" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "RemoveMethod", - displayName: "RemoveMethod" - ), - ] - ); - } - private ValidatableTypeInfo CreateFieldInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.FieldInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.FieldInfo), - propertyType: typeof(global::System.Type), - name: "FieldType", - displayName: "FieldType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.FieldInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - ] - ); - } - private ValidatableTypeInfo CreatePropertyInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.PropertyInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.PropertyInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "GetMethod", - displayName: "GetMethod" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.PropertyInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.PropertyInfo), - propertyType: typeof(global::System.Type), - name: "PropertyType", - displayName: "PropertyType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.PropertyInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "SetMethod", - displayName: "SetMethod" - ), - ] - ); - } - private ValidatableTypeInfo CreateTypeInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.TypeInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredConstructors", - displayName: "DeclaredConstructors" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredEvents", - displayName: "DeclaredEvents" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredFields", - displayName: "DeclaredFields" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredMembers", - displayName: "DeclaredMembers" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredMethods", - displayName: "DeclaredMethods" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredNestedTypes", - displayName: "DeclaredNestedTypes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredProperties", - displayName: "DeclaredProperties" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "ImplementedInterfaces", - displayName: "ImplementedInterfaces" - ), - ] - ); - } - private ValidatableTypeInfo CreateAssembly() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.Assembly), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "CustomAttributes", - displayName: "CustomAttributes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DefinedTypes", - displayName: "DefinedTypes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "EntryPoint", - displayName: "EntryPoint" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "ExportedTypes", - displayName: "ExportedTypes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Reflection.Module), - name: "ManifestModule", - displayName: "ManifestModule" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "Modules", - displayName: "Modules" - ), - ] - ); - } - private ValidatableTypeInfo CreateGuid() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Guid), - members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::System.Guid), - // propertyType: typeof(global::System.Guid), - // name: "AllBitsSet", - // displayName: "AllBitsSet" - // ), - ] - ); - } - private ValidatableTypeInfo CreateModule() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.Module), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Module), - propertyType: typeof(global::System.Reflection.Assembly), - name: "Assembly", - displayName: "Assembly" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Module), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "CustomAttributes", - displayName: "CustomAttributes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Module), - propertyType: typeof(global::System.Guid), - name: "ModuleVersionId", - displayName: "ModuleVersionId" - ), - ] - ); - } - private ValidatableTypeInfo CreateMemberInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.MemberInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "CustomAttributes", - displayName: "CustomAttributes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Type), - name: "DeclaringType", - displayName: "DeclaringType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Reflection.Module), - name: "Module", - displayName: "Module" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Type), - name: "ReflectedType", - displayName: "ReflectedType" - ), - ] - ); - } - private ValidatableTypeInfo CreateType() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Type), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.Assembly), - name: "Assembly", - displayName: "Assembly" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type), - name: "BaseType", - displayName: "BaseType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.MethodBase), - name: "DeclaringMethod", - displayName: "DeclaringMethod" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type), - name: "DeclaringType", - displayName: "DeclaringType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type[]), - name: "GenericTypeArguments", - displayName: "GenericTypeArguments" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Guid), - name: "GUID", - displayName: "GUID" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.Module), - name: "Module", - displayName: "Module" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type), - name: "ReflectedType", - displayName: "ReflectedType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.ConstructorInfo), - name: "TypeInitializer", - displayName: "TypeInitializer" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type), - name: "UnderlyingSystemType", - displayName: "UnderlyingSystemType" - ), - ] - ); - } - private ValidatableTypeInfo CreateBaseRecordOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), - members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), - ] - ); - } - private ValidatableTypeInfo CreateExecuteOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - propertyType: typeof(string), - name: "Path", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), - members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), - propertyType: typeof(string), - name: "Name", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), - members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), - propertyType: typeof(string), - name: "Name", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateIDictionary_string_string() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Collections.Generic.IDictionary), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Collections.Generic.IDictionary), - propertyType: typeof(global::System.Collections.Generic.ICollection), - name: "Values", - displayName: "Values" - ), - ] - ); - } - private ValidatableTypeInfo CreateTraceEventFilter() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - propertyType: typeof(string), - name: "ProviderName", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - propertyType: typeof(string), - name: "EventName", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "PayloadFilter", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectTraceOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.TraceProfile?), - name: "Profile", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(int?), - name: "BufferSizeMegabytes", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "Duration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - name: "StoppingEvent", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateGlobalCounterOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - propertyType: typeof(float?), - name: "IntervalSeconds", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - propertyType: typeof(int?), - name: "MaxHistograms", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - propertyType: typeof(int?), - name: "MaxTimeSeries", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "Providers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectGCDumpOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), - members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectLiveMetricsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), - members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "Duration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateMonitorApiKeyOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), - propertyType: typeof(string), - name: "Subject", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), - propertyType: typeof(string), - name: "PublicKey", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateAzureAdOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - propertyType: typeof(string), - name: "TenantId", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - propertyType: typeof(string), - name: "ClientId", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - propertyType: typeof(global::System.Uri), - name: "AppIdUri", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - propertyType: typeof(string), - name: "RequiredRole", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateAuthenticationOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), - name: "MonitorApiKey", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - name: "AzureAd", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateExceptionsConfiguration() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), - propertyType: typeof(global::System.Collections.Generic.List), - name: "Exclude", - displayName: "Exclude" - ), - ] - ); - } - private ValidatableTypeInfo CreateExceptionsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), - propertyType: typeof(int?), - name: "TopLevelLimit", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), - name: "CollectionFilters", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateInProcessFeaturesOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), - name: "Exceptions", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateCorsConfigurationOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), - propertyType: typeof(string), - name: "AllowedOrigins", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateEgressOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "FileSystem", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "Properties", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateMetricProvider() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), - propertyType: typeof(string), - name: "ProviderName", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateMetricsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - propertyType: typeof(int?), - name: "MetricCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - propertyType: typeof(global::System.Collections.Generic.List), - name: "Providers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateProcessFilterOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), - propertyType: typeof(global::System.Collections.Generic.List), - name: "Filters", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectionRuleTriggerDefaultsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - propertyType: typeof(int?), - name: "RequestCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - propertyType: typeof(int?), - name: "ResponseCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectionRuleLimitsDefaultsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - propertyType: typeof(int?), - name: "ActionCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "ActionCountSlidingWindowDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "RuleDuration", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectionRuleDefaultsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - name: "Triggers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - name: "Limits", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateTemplateOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRuleFilters", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRuleTriggers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRuleActions", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRuleLimits", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateRootOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), - name: "Authentication", - displayName: "Authentication" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRules", - displayName: "CollectionRules" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - name: "GlobalCounter", - displayName: "GlobalCounter" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), - name: "InProcessFeatures", - displayName: "InProcessFeatures" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), - name: "CorsConfiguration", - displayName: "CorsConfiguration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), - name: "Egress", - displayName: "Egress" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - name: "Metrics", - displayName: "Metrics" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), - name: "DefaultProcess", - displayName: "DefaultProcess" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), - name: "CollectionRuleDefaults", - displayName: "CollectionRuleDefaults" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - name: "Templates", - displayName: "Templates" - ), - ] - ); - } - private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - propertyType: typeof(string), - name: "DirectoryPath", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - propertyType: typeof(int?), - name: "CopyBufferSize", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectDumpOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), - members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.DumpType?), - name: "Type", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateLoadProfilerOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), - members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), - propertyType: typeof(string), - name: "Path", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), - propertyType: typeof(global::System.Guid), - name: "Clsid", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" - ), - ] - ); - } - private ValidatableTypeInfo CreateTestValidatableTypes() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - name: "CollectionRuleOptions", - displayName: "CollectionRuleOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - name: "ExecuteOptions", - displayName: "ExecuteOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), - name: "SetEnvironmentVariableOptions", - displayName: "SetEnvironmentVariableOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), - name: "GetEnvironmentVariableOptions", - displayName: "GetEnvironmentVariableOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - name: "CollectTraceOptions", - displayName: "CollectTraceOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - name: "GlobalCounterOptions", - displayName: "GlobalCounterOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), - name: "CollectGCDumpOptions", - displayName: "CollectGCDumpOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), - name: "CollectLiveMetricsOptions", - displayName: "CollectLiveMetricsOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - name: "RootOptions", - displayName: "RootOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - name: "FileSystemEgressProviderOptions", - displayName: "FileSystemEgressProviderOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), - name: "CollectDumpOptions", - displayName: "CollectDumpOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), - name: "LoadProfilerOptions", - displayName: "LoadProfilerOptions" - ), - ] - ); - } - - } - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - internal static class GeneratedServiceCollectionExtensions - { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "ZwR3lEVY3JYQ5HMDMrMsqtEIAABUZXN0VmFsaWRhdGFibGVUeXBlcy5jcw==")] - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) - { - // Use non-extension method to avoid infinite recursion. - return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => - { - options.Resolvers.Insert(0, new GeneratedValidatableInfoResolver()); - if (configureOptions is not null) - { - configureOptions(options); - } - }); - } - } - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - file static class ValidationAttributeCache - { - private sealed record CacheKey(global::System.Type ContainingType, string PropertyName); - private static readonly global::System.Collections.Concurrent.ConcurrentDictionary _cache = new(); - - public static global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes( - global::System.Type containingType, - string propertyName) - { - var key = new CacheKey(containingType, propertyName); - return _cache.GetOrAdd(key, static k => - { - var property = k.ContainingType.GetProperty(k.PropertyName); - if (property == null) - { - return []; - } - - return [.. global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(property, inherit: true)]; - }); - } - } -} \ No newline at end of file diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj index d6e2b1a4fb4..280248c3757 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj @@ -17,4 +17,24 @@ + + + + + + + + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs new file mode 100644 index 00000000000..e7b240c2fca --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs @@ -0,0 +1,790 @@ +#nullable enable annotations +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ +#nullable enable + +namespace System.Runtime.CompilerServices +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : System.Attribute + { + public InterceptsLocationAttribute(int version, string data) + { + } + } +} + +namespace Microsoft.AspNetCore.Http.Validation.Generated +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file sealed class GeneratedValidatablePropertyInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatablePropertyInfo + { + public GeneratedValidatablePropertyInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] + global::System.Type containingType, + global::System.Type propertyType, + string name, + string displayName) : base(containingType, propertyType, name, displayName) + { + ContainingType = containingType; + Name = name; + } + + internal global::System.Type ContainingType { get; } + internal string Name { get; } + + protected override global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes() + => ValidationAttributeCache.GetValidationAttributes(ContainingType, Name); + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file sealed class GeneratedValidatableTypeInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatableTypeInfo + { + public GeneratedValidatableTypeInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.Interfaces)] + global::System.Type type, + ValidatablePropertyInfo[] members) : base(type, members) { } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file class GeneratedValidatableInfoResolver : global::Microsoft.AspNetCore.Http.Validation.IValidatableInfoResolver + { + public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) + { + validatableInfo = null; + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest)) + { + validatableInfo = CreateExtensionManifest(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions)) + { + validatableInfo = CreateFileSystemEgressProviderOptions(); + return true; + } + if (type == typeof(global::System.Reflection.MethodBase)) + { + validatableInfo = CreateMethodBase(); + return true; + } + if (type == typeof(global::System.Reflection.ConstructorInfo)) + { + validatableInfo = CreateConstructorInfo(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeTypedArgument)) + { + validatableInfo = CreateCustomAttributeTypedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeNamedArgument)) + { + validatableInfo = CreateCustomAttributeNamedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeData)) + { + validatableInfo = CreateCustomAttributeData(); + return true; + } + if (type == typeof(global::System.Reflection.ParameterInfo)) + { + validatableInfo = CreateParameterInfo(); + return true; + } + if (type == typeof(global::System.Reflection.MethodInfo)) + { + validatableInfo = CreateMethodInfo(); + return true; + } + if (type == typeof(global::System.Reflection.EventInfo)) + { + validatableInfo = CreateEventInfo(); + return true; + } + if (type == typeof(global::System.Reflection.FieldInfo)) + { + validatableInfo = CreateFieldInfo(); + return true; + } + if (type == typeof(global::System.Reflection.PropertyInfo)) + { + validatableInfo = CreatePropertyInfo(); + return true; + } + if (type == typeof(global::System.Reflection.TypeInfo)) + { + validatableInfo = CreateTypeInfo(); + return true; + } + if (type == typeof(global::System.Reflection.Assembly)) + { + validatableInfo = CreateAssembly(); + return true; + } + if (type == typeof(global::System.Guid)) + { + validatableInfo = CreateGuid(); + return true; + } + if (type == typeof(global::System.Reflection.Module)) + { + validatableInfo = CreateModule(); + return true; + } + if (type == typeof(global::System.Reflection.MemberInfo)) + { + validatableInfo = CreateMemberInfo(); + return true; + } + if (type == typeof(global::System.Type)) + { + validatableInfo = CreateType(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions)) + { + validatableInfo = CreateBaseRecordOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions)) + { + validatableInfo = CreateExecuteOptions(); + return true; + } + if (type == typeof(global::TestValidatableType)) + { + validatableInfo = CreateTestValidatableType(); + return true; + } + + return false; + } + + // No-ops, rely on runtime code for ParameterInfo-based resolution + public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterInfo parameterInfo, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) + { + validatableInfo = null; + return false; + } + + private ValidatableTypeInfo CreateExtensionManifest() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), + propertyType: typeof(string), + name: "Name", + displayName: "Name" + ), + ] + ); + } + private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + propertyType: typeof(string), + name: "DirectoryPath", + displayName: "DirectoryPath" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + propertyType: typeof(int?), + name: "CopyBufferSize", + displayName: "CopyBufferSize" + ), + ] + ); + } + private ValidatableTypeInfo CreateMethodBase() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodBase), + members: [] + ); + } + private ValidatableTypeInfo CreateConstructorInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ConstructorInfo), + members: [] + ); + } + private ValidatableTypeInfo CreateCustomAttributeTypedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeTypedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + propertyType: typeof(global::System.Type), + name: "ArgumentType", + displayName: "ArgumentType" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeNamedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeNamedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "MemberInfo", + displayName: "MemberInfo" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + name: "TypedValue", + displayName: "TypedValue" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeData() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeData), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Type), + name: "AttributeType", + displayName: "AttributeType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "Constructor", + displayName: "Constructor" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "ConstructorArguments", + displayName: "ConstructorArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "NamedArguments", + displayName: "NamedArguments" + ), + ] + ); + } + private ValidatableTypeInfo CreateParameterInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ParameterInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "Member", + displayName: "Member" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Type), + name: "ParameterType", + displayName: "ParameterType" + ), + ] + ); + } + private ValidatableTypeInfo CreateMethodInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.ParameterInfo), + name: "ReturnParameter", + displayName: "ReturnParameter" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Type), + name: "ReturnType", + displayName: "ReturnType" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.EventInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "AddMethod", + displayName: "AddMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Type), + name: "EventHandlerType", + displayName: "EventHandlerType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RaiseMethod", + displayName: "RaiseMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RemoveMethod", + displayName: "RemoveMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateFieldInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.FieldInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Type), + name: "FieldType", + displayName: "FieldType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + ] + ); + } + private ValidatableTypeInfo CreatePropertyInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.PropertyInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "GetMethod", + displayName: "GetMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Type), + name: "PropertyType", + displayName: "PropertyType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "SetMethod", + displayName: "SetMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateTypeInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.TypeInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredConstructors", + displayName: "DeclaredConstructors" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredEvents", + displayName: "DeclaredEvents" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredFields", + displayName: "DeclaredFields" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMembers", + displayName: "DeclaredMembers" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMethods", + displayName: "DeclaredMethods" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredNestedTypes", + displayName: "DeclaredNestedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredProperties", + displayName: "DeclaredProperties" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ImplementedInterfaces", + displayName: "ImplementedInterfaces" + ), + ] + ); + } + private ValidatableTypeInfo CreateAssembly() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Assembly), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DefinedTypes", + displayName: "DefinedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "EntryPoint", + displayName: "EntryPoint" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ExportedTypes", + displayName: "ExportedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.Module), + name: "ManifestModule", + displayName: "ManifestModule" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "Modules", + displayName: "Modules" + ), + ] + ); + } + private ValidatableTypeInfo CreateGuid() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Guid), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Guid), + propertyType: typeof(global::System.Guid), + name: "AllBitsSet", + displayName: "AllBitsSet" + ), + ] + ); + } + private ValidatableTypeInfo CreateModule() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Module), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Guid), + name: "ModuleVersionId", + displayName: "ModuleVersionId" + ), + ] + ); + } + private ValidatableTypeInfo CreateMemberInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MemberInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + ] + ); + } + private ValidatableTypeInfo CreateType() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Type), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "BaseType", + displayName: "BaseType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MethodBase), + name: "DeclaringMethod", + displayName: "DeclaringMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type[]), + name: "GenericTypeArguments", + displayName: "GenericTypeArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Guid), + name: "GUID", + displayName: "GUID" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "TypeInitializer", + displayName: "TypeInitializer" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "UnderlyingSystemType", + displayName: "UnderlyingSystemType" + ), + ] + ); + } + private ValidatableTypeInfo CreateBaseRecordOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + ] + ); + } + private ValidatableTypeInfo CreateExecuteOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + propertyType: typeof(string), + name: "Path", + displayName: "Path" + ), + ] + ); + } + private ValidatableTypeInfo CreateTestValidatableType() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::TestValidatableType), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::TestValidatableType), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), + name: "ExtensionManifest", + displayName: "ExtensionManifest" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::TestValidatableType), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + name: "FileSystemEgressProviderOptions", + displayName: "FileSystemEgressProviderOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::TestValidatableType), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + name: "ExecuteOptions", + displayName: "ExecuteOptions" + ), + ] + ); + } + + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file static class GeneratedServiceCollectionExtensions + { + [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "nMLdYxVpxyjXwof6UabUh7sBAABQcm9ncmFtLmNz")] + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + { + // Use non-extension method to avoid infinite recursion. + return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => + { + options.Resolvers.Insert(0, new GeneratedValidatableInfoResolver()); + if (configureOptions is not null) + { + configureOptions(options); + } + }); + } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file static class ValidationAttributeCache + { + private sealed record CacheKey(global::System.Type ContainingType, string PropertyName); + private static readonly global::System.Collections.Concurrent.ConcurrentDictionary _cache = new(); + + public static global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes( + global::System.Type containingType, + string propertyName) + { + var key = new CacheKey(containingType, propertyName); + return _cache.GetOrAdd(key, static k => + { + var property = k.ContainingType.GetProperty(k.PropertyName); + if (property == null) + { + return []; + } + + return [.. global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(property, inherit: true)]; + }); + } + } +} \ No newline at end of file diff --git a/src/Tools/dotnet-monitor/CollectionRules/ActionListExecutor.cs b/src/Tools/dotnet-monitor/CollectionRules/ActionListExecutor.cs index 438c4c2cc13..00ed55d906c 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/ActionListExecutor.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/ActionListExecutor.cs @@ -49,7 +49,7 @@ public async Task> ExecuteAction List deferredCompletions = new(context.Options.Actions.Count); var actionResults = new Dictionary(StringComparer.Ordinal); - var dependencyAnalyzer = ActionOptionsDependencyAnalyzer.Create(context); + var dependencyAnalyzer = ActionOptionsDependencyAnalyzer.Create(context, _actionOperations); try { diff --git a/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs b/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs index 5e30eeb561a..57e7f8ecfb5 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.Linq; using System.Reflection; using System.Text; @@ -34,6 +35,7 @@ internal sealed class ActionOptionsDependencyAnalyzer private readonly CollectionRuleContext _ruleContext; private readonly ConfigurationTokenParser _tokenParser; + private readonly ICollectionRuleActionOperations _actionOperations; //Use action index instead of name, since it's possible for an unnamed action to have named dependencies. #nullable disable @@ -77,17 +79,18 @@ public string GetActionResultToken() => string.Concat(ActionReferencePrefix, Action.Name, ConfigurationTokenParser.Separator, ResultName, ConfigurationTokenParser.SubstitutionSuffix); } - public static ActionOptionsDependencyAnalyzer Create(CollectionRuleContext context) + public static ActionOptionsDependencyAnalyzer Create(CollectionRuleContext context, ICollectionRuleActionOperations actionOperations) { - var analyzer = new ActionOptionsDependencyAnalyzer(context, new ConfigurationTokenParser(context.Logger)); + var analyzer = new ActionOptionsDependencyAnalyzer(context, new ConfigurationTokenParser(context.Logger, actionOperations), actionOperations); analyzer.EnsureDependencies(); return analyzer; } - private ActionOptionsDependencyAnalyzer(CollectionRuleContext context, ConfigurationTokenParser tokenParser) + private ActionOptionsDependencyAnalyzer(CollectionRuleContext context, ConfigurationTokenParser tokenParser, ICollectionRuleActionOperations actionOperations) { _ruleContext = context ?? throw new ArgumentNullException(nameof(context)); _tokenParser = tokenParser ?? throw new ArgumentNullException(nameof(tokenParser)); + _actionOperations = actionOperations ?? throw new ArgumentNullException(nameof(actionOperations)); } #nullable disable @@ -192,7 +195,11 @@ private void EnsureDependencies() private void EnsureDependencies(CollectionRuleActionOptions options, int actionIndex) { - foreach (PropertyInfo property in GetDependencyPropertiesFromSettings(options)) + if (!_actionOperations.TryGetOptionsType(options.Type, out Type optionsType)) + { + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownActionType, options.Name)); + } + foreach (PropertyInfo property in GetDependencyPropertiesFromSettings(optionsType)) { string? originalValue = (string?)property.GetValue(options.Settings); if (string.IsNullOrEmpty(originalValue)) @@ -288,9 +295,9 @@ private bool GetActionResultReference(string actionReference, int actionIndex, return true; } - private static IEnumerable GetDependencyPropertiesFromSettings(CollectionRuleActionOptions options) + private static IEnumerable GetDependencyPropertiesFromSettings([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type optionsType) { - return ConfigurationTokenParser.GetPropertiesFromSettings(options, p => p.GetCustomAttributes(typeof(ActionOptionsDependencyPropertyAttribute), inherit: true).Any()); + return ConfigurationTokenParser.GetPropertiesFromSettings(optionsType, p => p.GetCustomAttributes(typeof(ActionOptionsDependencyPropertyAttribute), inherit: true).Any()); } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs index e92f1510ff9..813d37c38d2 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs @@ -93,5 +93,20 @@ public bool TryValidateOptions( return false; } } + + /// + public bool TryGetOptionsType( + string actionName, + out Type optionsType) + { + if (_map.TryGetValue(actionName, out ICollectionRuleActionDescriptor descriptor)) + { + optionsType = descriptor.OptionsType; + return true; + } + + optionsType = null; + return false; + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs index 075f3195f0c..405939ef02f 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs @@ -4,6 +4,7 @@ #nullable disable using Microsoft.Extensions.Configuration; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -40,5 +41,13 @@ bool TryValidateOptions( object options, ValidationContext validationContext, ICollection results); + + /// + /// Attempts to get the type of the options instance + /// associated with the registered action name. + /// + bool TryGetOptionsType( + string actionName, + out Type optionsType); } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.Validate.cs index 904c8ff6366..ede73aff565 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.Validate.cs @@ -18,7 +18,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali if (!string.IsNullOrEmpty(Type)) { - validationContext = new ValidationContext(this, displayName: Type, validationContext, items: null) + validationContext = new ValidationContext(this, displayName: nameof(Settings), validationContext, items: null) { MemberName = nameof(Settings) }; diff --git a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs index 93cd66267e0..8b7d75f1fe7 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs @@ -112,7 +112,7 @@ private void MapRootOptions(RootOptions obj, string prefix, string separator, ID // MetricsOptions MapStorageOptions(obj.Storage, FormattableString.Invariant($"{prefix}{nameof(obj.Storage)}"), separator, map); // ProcessFilterOptions - // CollectionRuleDefaultsOptions + MapCollectionRuleDefaultsOptions(obj.CollectionRuleDefaults, FormattableString.Invariant($"{prefix}{nameof(obj.CollectionRuleDefaults)}"), separator, map); // Templates // DotnetMonitorDebugOptions // FOR TESTS: Logging? @@ -206,9 +206,9 @@ private void MapCollectionRuleActionOptions_Settings(string type, object? settin // case KnownCollectionRuleActions.CollectLogs: // MapCollectLogsOptions(settings as CollectLogsOptions, valueName, separator, map); // break; - // case KnownCollectionRuleActions.CollectStacks: - // MapCollectStacksOptions(settings as CollectStacksOptions, valueName, separator, map); - // break; + case KnownCollectionRuleActions.CollectStacks: + MapCollectStacksOptions(settings as CollectStacksOptions, valueName, separator, map); + break; case KnownCollectionRuleActions.CollectTrace: MapCollectTraceOptions(settings as CollectTraceOptions, valueName, separator, map); break; @@ -389,6 +389,25 @@ private static void MapEventMetricsMeter(EventMetricsMeter obj, string valueName MapArray_String(obj.InstrumentNames, FormattableString.Invariant($"{prefix}{nameof(obj.InstrumentNames)}"), separator, map); } + private static void MapCollectStacksOptions(CollectStacksOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); + MapCallStackFormat(obj.Format, FormattableString.Invariant($"{prefix}{nameof(obj.Format)}"), map); + MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); + } + } + + private static void MapCallStackFormat(CallStackFormat? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + private static void MapCollectTraceOptions(CollectTraceOptions? obj, string valueName, string separator, IDictionary map) { if (null != obj) @@ -591,9 +610,9 @@ private static void MapCollectionRuleTriggerOptions_Settings(string type, object // case KnownCollectionRuleTriggers.AspNetRequestCount: // MapAspNetRequestCountOptions(settings as AspNetRequestCountOptions, valueName, separator, map); // break; - // case KnownCollectionRuleTriggers.AspNetRequestDuration: - // MapAspNetRequestDurationOptions(settings as AspNetRequestDurationOptions, valueName, separator, map); - // break; + case KnownCollectionRuleTriggers.AspNetRequestDuration: + MapAspNetRequestDurationOptions(settings as AspNetRequestDurationOptions, valueName, separator, map); + break; // case KnownCollectionRuleTriggers.AspNetResponseStatus: // MapAspNetResponseStatusOptions(settings as AspNetResponseStatusOptions, valueName, separator, map); // break; @@ -618,6 +637,19 @@ private static void MapCollectionRuleTriggerOptions_Settings(string type, object } } + private static void MapAspNetRequestDurationOptions(AspNetRequestDurationOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapInt(obj.RequestCount, FormattableString.Invariant($"{prefix}{nameof(obj.RequestCount)}"), map); + MapTimeSpan(obj.RequestDuration, FormattableString.Invariant($"{prefix}{nameof(obj.RequestDuration)}"), map); + MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); + MapArray_String(obj.IncludePaths, FormattableString.Invariant($"{prefix}{nameof(obj.IncludePaths)}"), separator, map); + MapArray_String(obj.ExcludePaths, FormattableString.Invariant($"{prefix}{nameof(obj.ExcludePaths)}"), separator, map); + } + } + private static void MapAuthenticationOptions(AuthenticationOptions? obj, string valueName, string separator, IDictionary map) { if (null != obj) @@ -760,6 +792,48 @@ private static void MapStorageOptions(StorageOptions? obj, string valueName, str } } + private static void MapCollectionRuleDefaultsOptions(CollectionRuleDefaultsOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapCollectionRuleTriggerDefaultsOptions(obj.Triggers, FormattableString.Invariant($"{prefix}{nameof(obj.Triggers)}"), separator, map); + MapCollectionRuleActionDefaultsOptions(obj.Actions, FormattableString.Invariant($"{prefix}{nameof(obj.Actions)}"), separator, map); + MapCollectionRuleLimitsDefaultsOptions(obj.Limits, FormattableString.Invariant($"{prefix}{nameof(obj.Limits)}"), separator, map); + } + } + + private static void MapCollectionRuleTriggerDefaultsOptions(CollectionRuleTriggerDefaultsOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapInt(obj.RequestCount, FormattableString.Invariant($"{prefix}{nameof(obj.RequestCount)}"), map); + MapInt(obj.ResponseCount, FormattableString.Invariant($"{prefix}{nameof(obj.ResponseCount)}"), map); + MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); + } + } + + private static void MapCollectionRuleActionDefaultsOptions(CollectionRuleActionDefaultsOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); + } + } + + private static void MapCollectionRuleLimitsDefaultsOptions(CollectionRuleLimitsDefaultsOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapInt(obj.ActionCount, FormattableString.Invariant($"{prefix}{nameof(obj.ActionCount)}"), map); + MapTimeSpan(obj.ActionCountSlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.ActionCountSlidingWindowDuration)}"), map); + MapTimeSpan(obj.RuleDuration, FormattableString.Invariant($"{prefix}{nameof(obj.RuleDuration)}"), map); + } + } + private static void MapString(string? value, string valueName, IDictionary map) { if (null != value) From a48071eeef91d1dbc3ed44c28bed1d610940549e Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 21 Apr 2025 23:15:32 +0000 Subject: [PATCH 137/174] Add ConfigurationTokenParser, UnitTestsCommon changes --- ...tics.Monitoring.Tool.UnitTestCommon.csproj | 12 ++++++ ...ics.Monitoring.Tool.UnitTestsSample.csproj | 4 +- .../ConfigurationTokenParser.cs | 42 +++++++------------ 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj index d8db2356aea..57a98113d2d 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj @@ -3,6 +3,7 @@ $(ToolTargetFrameworks) true + true @@ -28,4 +29,15 @@ + + + + + + + + + + + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj index 280248c3757..b361489a992 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj @@ -31,10 +31,10 @@ LatestRuntimeFrameworkVersion="$(AspNetCoreAppVersion)" /> - + diff --git a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs index 03f03e1d2a0..b6df62ec79a 100644 --- a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs +++ b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.Logging; @@ -36,6 +37,7 @@ internal sealed class TokenContext internal sealed class ConfigurationTokenParser { private readonly ILogger _logger; + private readonly ICollectionRuleActionOperations _actionOperations; public const string SubstitutionPrefix = "$("; public const string SubstitutionSuffix = ")"; @@ -58,9 +60,10 @@ internal sealed class ConfigurationTokenParser public static readonly string HostNameReference = CreateTokenReference(MonitorInfoReference, HostName); public static readonly string UnixTimeReference = CreateTokenReference(MonitorInfoReference, UnixTime); - public ConfigurationTokenParser(ILogger logger) + public ConfigurationTokenParser(ILogger logger, ICollectionRuleActionOperations actionOperations) { _logger = logger; + _actionOperations = actionOperations; } public object? SubstituteOptionValues(CollectionRuleActionOptions actionOptions, TokenContext context) @@ -68,7 +71,12 @@ public ConfigurationTokenParser(ILogger logger) var originalSettings = actionOptions.Settings; object? settings = originalSettings; - foreach (PropertyInfo propertyInfo in GetPropertiesFromSettings(actionOptions)) + if (!_actionOperations.TryGetOptionsType(actionOptions.Type, out Type optionsType)) + { + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownActionType, actionOptions.Type)); + } + + foreach (PropertyInfo propertyInfo in GetPropertiesFromSettings(optionsType)) { string? originalPropertyValue = (string?)propertyInfo.GetValue(settings); if (string.IsNullOrEmpty(originalPropertyValue)) @@ -123,33 +131,11 @@ public bool TryCloneSettings(object? originalSettings, ref object? settings) return true; } - public static IEnumerable GetPropertiesFromSettings(CollectionRuleActionOptions actionOptions, Predicate? predicate = null) + public static IEnumerable GetPropertiesFromSettings([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type, Predicate? predicate = null) { - object? settings = actionOptions.Settings; - return actionOptions.Type switch { - KnownCollectionRuleActions.CollectDump => GetPropertiesFromSettings(typeof(CollectDumpOptions), predicate), - KnownCollectionRuleActions.CollectExceptions => GetPropertiesFromSettings(typeof(CollectExceptionsOptions), predicate), - KnownCollectionRuleActions.CollectGCDump => GetPropertiesFromSettings(typeof(CollectGCDumpOptions), predicate), - KnownCollectionRuleActions.CollectLogs => GetPropertiesFromSettings(typeof(CollectLogsOptions), predicate), - KnownCollectionRuleActions.CollectStacks => GetPropertiesFromSettings(typeof(CollectStacksOptions), predicate), - KnownCollectionRuleActions.CollectTrace => GetPropertiesFromSettings(typeof(CollectTraceOptions), predicate), - KnownCollectionRuleActions.CollectLiveMetrics => GetPropertiesFromSettings(typeof(CollectLiveMetricsOptions), predicate), - KnownCollectionRuleActions.Execute => GetPropertiesFromSettings(typeof(ExecuteOptions), predicate), - KnownCollectionRuleActions.LoadProfiler => GetPropertiesFromSettings(typeof(LoadProfilerOptions), predicate), - KnownCollectionRuleActions.SetEnvironmentVariable => GetPropertiesFromSettings(typeof(SetEnvironmentVariableOptions), predicate), - KnownCollectionRuleActions.GetEnvironmentVariable => GetPropertiesFromSettings(typeof(GetEnvironmentVariableOptions), predicate), - _ => throw new ArgumentException(string.Format( - CultureInfo.InvariantCulture, - "Unknown action type: {0}", - actionOptions.Type)) - }; - - static IEnumerable GetPropertiesFromSettings([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type, Predicate? predicate = null) - { - return type.GetProperties(BindingFlags.Public | BindingFlags.Instance) - .Where(p => p.PropertyType == typeof(string) && (predicate?.Invoke(p) ?? true)) - .ToArray(); - } + return type.GetProperties(BindingFlags.Public | BindingFlags.Instance) + .Where(p => p.PropertyType == typeof(string) && (predicate?.Invoke(p) ?? true)) + .ToArray(); } private static string CreateTokenReference(string category, string token) => From 45f2147113d53207a77c0db1312ec2581fcddde4 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 21 Apr 2025 23:22:36 +0000 Subject: [PATCH 138/174] Fix usings --- .../CollectionRuleActions.UnitTests/CollectDumpActionTests.cs | 1 - .../CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs | 1 - .../CollectLiveMetricsActionTests.cs | 1 - .../CollectionRuleActions.UnitTests/CollectTraceActionTests.cs | 1 - .../CollectionRuleDescriptionPipelineTests.cs | 1 - .../CollectionRulePipelineTests.cs | 1 - 6 files changed, 6 deletions(-) diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs index bac44584bdd..0253279e99f 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs @@ -6,7 +6,6 @@ using Microsoft.Diagnostics.Monitoring.TestCommon.Runners; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; -using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs index c76621a0dd6..9d791a01aff 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs @@ -5,7 +5,6 @@ using Microsoft.Diagnostics.Monitoring.TestCommon.Options; using Microsoft.Diagnostics.Monitoring.TestCommon.Runners; using Microsoft.Diagnostics.Monitoring.WebApi; -using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Exceptions; diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectLiveMetricsActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectLiveMetricsActionTests.cs index f172d62e9bc..1dfaf9b9ab5 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectLiveMetricsActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectLiveMetricsActionTests.cs @@ -7,7 +7,6 @@ using Microsoft.Diagnostics.Monitoring.TestCommon.Runners; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; -using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs index 143bea859bb..e3b7902cf88 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs @@ -6,7 +6,6 @@ using Microsoft.Diagnostics.Monitoring.TestCommon.Runners; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; -using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs index d799d54325c..032ac057a62 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs @@ -7,7 +7,6 @@ using Microsoft.Diagnostics.Monitoring.Tool.UnitTests.CollectionRules.Triggers; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; -using Microsoft.Diagnostics.Tools.Monitor; using Strings = Microsoft.Diagnostics.Monitoring.WebApi.Strings; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs index 2f2b8a276c0..c6335074318 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs @@ -6,7 +6,6 @@ using Microsoft.Diagnostics.Monitoring.TestCommon.Runners; using Microsoft.Diagnostics.Monitoring.Tool.UnitTests.CollectionRules.Triggers; using Microsoft.Diagnostics.Monitoring.WebApi; -using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; From 6fc94ef2a00622352302dc047289e4d840b30205 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 22 Apr 2025 17:34:45 +0000 Subject: [PATCH 139/174] Replace interceptor --- .../Program.cs | 2 +- .../ValidatableInfoResolver.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs index 4ff488c8d8a..a34cca569e7 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs @@ -7,7 +7,7 @@ using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; var builder = WebApplication.CreateBuilder(args); -builder.Services.AddValidation(); +Microsoft.AspNetCore.Http.Validation.Generated.GeneratedServiceCollectionExtensions.AddValidation(builder.Services); builder.Build(); public partial class Program {} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs index e7b240c2fca..70fe3cdb292 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs @@ -747,9 +747,9 @@ private ValidatableTypeInfo CreateTestValidatableType() } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - file static class GeneratedServiceCollectionExtensions + internal static class GeneratedServiceCollectionExtensions { - [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "nMLdYxVpxyjXwof6UabUh7sBAABQcm9ncmFtLmNz")] + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "nMLdYxVpxyjXwof6UabUh7sBAABQcm9ncmFtLmNz")] public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. From e94a372d8d6e8fa453c1cd9325d474ab57b8ebea Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 22 Apr 2025 22:55:08 +0000 Subject: [PATCH 140/174] Fix more test failures - Map more types - Fix dependency analyzer bug --- .../TestValidatableType.cs | 11 +- .../ValidatableInfoResolver.cs | 416 +++++++++++++----- .../CollectionRuleOptionsTests.cs | 1 + .../ActionOptionsDependencyAnalyzer.cs | 8 +- .../dotnet-monitor/CommonOptionsMapper.cs | 187 +++++++- .../ConfigurationTokenParser.cs | 13 +- 6 files changed, 485 insertions(+), 151 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs index 7093325e55c..94d1e5dad6f 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs @@ -7,6 +7,7 @@ using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; @@ -38,6 +39,8 @@ internal sealed class TestValidatableTypes public required CollectStacksOptions CollectStacksOptions { get; init; } + public required CollectLogsOptions CollectLogsOptions { get; init; } + public required RootOptions RootOptions { get; init; } public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } @@ -49,9 +52,15 @@ internal sealed class TestValidatableTypes public required CollectExceptionsOptions CollectExceptionsOptions { get; init; } // Triggers... - public required AspNetRequestDurationOptions AspNetRequestDurationOptions { get; init; } public required AspNetRequestCountOptions AspNetRequestCountOptions { get; init; } + public required AspNetRequestDurationOptions AspNetRequestDurationOptions { get; init; } public required AspNetResponseStatusOptions AspNetResponseStatusOptions { get; init; } + public required EventCounterOptions EventCounterOptions { get; init; } + public required CPUUsageOptions CPUUsageOptions { get; init; } + public required GCHeapSizeOptions GCHeapSizeOptions { get; init; } + public required ThreadpoolQueueLengthOptions ThreadpoolQueueLengthOptions { get; init; } + public required EventMeterOptions EventMeterOptions { get; init; } + // TODO: only one resolver per project? Generate this for tests, for now. Maybe want to separate this one out // by test later. diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs index 5e89d3cf931..33cfe868ecc 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs @@ -214,6 +214,11 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateCollectStacksOptions(); return true; } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions)) + { + validatableInfo = CreateCollectLogsOptions(); + return true; + } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions)) { validatableInfo = CreateMonitorApiKeyOptions(); @@ -314,14 +319,14 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateCollectExceptionsOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions)) { - validatableInfo = CreateAspNetRequestDurationOptions(); + validatableInfo = CreateAspNetRequestCountOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions)) { - validatableInfo = CreateAspNetRequestCountOptions(); + validatableInfo = CreateAspNetRequestDurationOptions(); return true; } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions)) @@ -329,6 +334,31 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateAspNetResponseStatusOptions(); return true; } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions)) + { + validatableInfo = CreateEventCounterOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions)) + { + validatableInfo = CreateCPUUsageOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions)) + { + validatableInfo = CreateGCHeapSizeOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions)) + { + validatableInfo = CreateThreadpoolQueueLengthOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions)) + { + validatableInfo = CreateEventMeterOptions(); + return true; + } if (type == typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions)) { validatableInfo = CreatePassThroughOptions(); @@ -910,12 +940,6 @@ private ValidatableTypeInfo CreateBaseRecordOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), ] ); } @@ -924,12 +948,6 @@ private ValidatableTypeInfo CreateExecuteOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), propertyType: typeof(string), @@ -944,12 +962,6 @@ private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), propertyType: typeof(string), @@ -964,12 +976,6 @@ private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), propertyType: typeof(string), @@ -998,12 +1004,6 @@ private ValidatableTypeInfo CreateTraceEventFilter() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), propertyType: typeof(string), @@ -1030,12 +1030,6 @@ private ValidatableTypeInfo CreateCollectTraceOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.TraceProfile?), @@ -1106,12 +1100,6 @@ private ValidatableTypeInfo CreateCollectGCDumpOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), propertyType: typeof(string), @@ -1126,12 +1114,6 @@ private ValidatableTypeInfo CreateCollectLiveMetricsOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), propertyType: typeof(global::System.TimeSpan?), @@ -1152,12 +1134,6 @@ private ValidatableTypeInfo CreateCollectStacksOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), propertyType: typeof(string), @@ -1167,6 +1143,45 @@ private ValidatableTypeInfo CreateCollectStacksOptions() ] ); } + + private ValidatableTypeInfo CreateCollectLogsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::Microsoft.Extensions.Logging.LogLevel?), + name: "DefaultLevel", + displayName: "DefaultLevel" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::System.Collections.Generic.Dictionary), + name: "FilterSpecs", + displayName: "FilterSpecs" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Duration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.LogFormat?), + name: "Format", + displayName: "Format" + ), + ] + ); + } private ValidatableTypeInfo CreateMonitorApiKeyOptions() { return new GeneratedValidatableTypeInfo( @@ -1566,12 +1581,6 @@ private ValidatableTypeInfo CreateCollectDumpOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.DumpType?), @@ -1592,12 +1601,6 @@ private ValidatableTypeInfo CreateLoadProfilerOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), propertyType: typeof(string), @@ -1618,12 +1621,6 @@ private ValidatableTypeInfo CreateCollectExceptionsOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), propertyType: typeof(string), @@ -1639,37 +1636,31 @@ private ValidatableTypeInfo CreateCollectExceptionsOptions() ] ); } - private ValidatableTypeInfo CreateAspNetRequestDurationOptions() + private ValidatableTypeInfo CreateAspNetRequestCountOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), propertyType: typeof(int), name: "RequestCount", displayName: "RequestCount" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "RequestDuration", - displayName: "RequestDuration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), propertyType: typeof(global::System.TimeSpan?), name: "SlidingWindowDuration", displayName: "SlidingWindowDuration" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), propertyType: typeof(string[]), name: "IncludePaths", displayName: "IncludePaths" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), propertyType: typeof(string[]), name: "ExcludePaths", displayName: "ExcludePaths" @@ -1677,31 +1668,37 @@ private ValidatableTypeInfo CreateAspNetRequestDurationOptions() ] ); } - private ValidatableTypeInfo CreateAspNetRequestCountOptions() + private ValidatableTypeInfo CreateAspNetRequestDurationOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), propertyType: typeof(int), name: "RequestCount", displayName: "RequestCount" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RequestDuration", + displayName: "RequestDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), propertyType: typeof(global::System.TimeSpan?), name: "SlidingWindowDuration", displayName: "SlidingWindowDuration" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), propertyType: typeof(string[]), name: "IncludePaths", displayName: "IncludePaths" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), propertyType: typeof(string[]), name: "ExcludePaths", displayName: "ExcludePaths" @@ -1747,20 +1744,149 @@ private ValidatableTypeInfo CreateAspNetResponseStatusOptions() ] ); } - private ValidatableTypeInfo CreatePassThroughOptions() + private ValidatableTypeInfo CreateEventCounterOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + propertyType: typeof(string), + name: "ProviderName", + displayName: "ProviderName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + propertyType: typeof(string), + name: "CounterName", + displayName: "CounterName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateCPUUsageOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + propertyType: typeof(double?), + name: "GreaterThan", + displayName: "GreaterThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + propertyType: typeof(double?), + name: "LessThan", + displayName: "LessThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateGCHeapSizeOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + propertyType: typeof(double?), + name: "GreaterThan", + displayName: "GreaterThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + propertyType: typeof(double?), + name: "LessThan", + displayName: "LessThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateThreadpoolQueueLengthOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + propertyType: typeof(double?), + name: "GreaterThan", + displayName: "GreaterThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + propertyType: typeof(double?), + name: "LessThan", + displayName: "LessThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), ] ); } + private ValidatableTypeInfo CreateEventMeterOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + propertyType: typeof(string), + name: "MeterName", + displayName: "MeterName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + propertyType: typeof(string), + name: "InstrumentName", + displayName: "InstrumentName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + propertyType: typeof(int?), + name: "HistogramPercentile", + displayName: "HistogramPercentile" + ), + ] + ); + } + private ValidatableTypeInfo CreatePassThroughOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), + members: [] + ); + } private ValidatableTypeInfo CreateTestValidatableTypes() { return new GeneratedValidatableTypeInfo( @@ -1820,6 +1946,12 @@ private ValidatableTypeInfo CreateTestValidatableTypes() name: "CollectStacksOptions", displayName: "CollectStacksOptions" ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + name: "CollectLogsOptions", + displayName: "CollectLogsOptions" + ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), @@ -1850,24 +1982,54 @@ private ValidatableTypeInfo CreateTestValidatableTypes() name: "CollectExceptionsOptions", displayName: "CollectExceptionsOptions" ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), - name: "AspNetRequestDurationOptions", - displayName: "AspNetRequestDurationOptions" - ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), name: "AspNetRequestCountOptions", displayName: "AspNetRequestCountOptions" ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + name: "AspNetRequestDurationOptions", + displayName: "AspNetRequestDurationOptions" + ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), name: "AspNetResponseStatusOptions", displayName: "AspNetResponseStatusOptions" ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + name: "EventCounterOptions", + displayName: "EventCounterOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + name: "CPUUsageOptions", + displayName: "CPUUsageOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + name: "GCHeapSizeOptions", + displayName: "GCHeapSizeOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + name: "ThreadpoolQueueLengthOptions", + displayName: "ThreadpoolQueueLengthOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + name: "EventMeterOptions", + displayName: "EventMeterOptions" + ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), @@ -1883,8 +2045,8 @@ private ValidatableTypeInfo CreateTestValidatableTypes() [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] internal static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "tJYY5rjIqR+TnT4DExGdC8ipAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "YaPWBCMaf/YiusWOmOTnNE6zAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => @@ -1911,14 +2073,40 @@ private sealed record CacheKey(global::System.Type ContainingType, string Proper var key = new CacheKey(containingType, propertyName); return _cache.GetOrAdd(key, static k => { + var results = new global::System.Collections.Generic.List(); + + // Get attributes from the property var property = k.ContainingType.GetProperty(k.PropertyName); - if (property == null) + if (property != null) + { + var propertyAttributes = global::System.Reflection.CustomAttributeExtensions + .GetCustomAttributes(property, inherit: true); + + results.AddRange(propertyAttributes); + } + + // Check constructors for parameters that match the property name + // to handle record scenarios + foreach (var constructor in k.ContainingType.GetConstructors()) + { + // Look for parameter with matching name (case insensitive) + var parameter = global::System.Linq.Enumerable.FirstOrDefault( + constructor.GetParameters(), + p => string.Equals(p.Name, k.PropertyName, global::System.StringComparison.OrdinalIgnoreCase)); + + if (parameter != null) { - return []; + var paramAttributes = global::System.Reflection.CustomAttributeExtensions + .GetCustomAttributes(parameter, inherit: true); + + results.AddRange(paramAttributes); + + break; } + } - return [.. global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(property, inherit: true)]; + return results.ToArray(); }); } } -} \ No newline at end of file +} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs index 31cbb996d67..7bf58757e2c 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs @@ -203,6 +203,7 @@ public Task CollectionRuleOptions_EventCounterTrigger_PropertyValidation() VerifyRequiredMessage(failures, 1, nameof(EventCounterOptions.CounterName)); VerifyRangeMessage(failures, 2, nameof(EventCounterOptions.SlidingWindowDuration), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue); + VerifyEitherRequiredMessage(failures, 3, nameof(EventCounterOptions.GreaterThan), nameof(EventCounterOptions.LessThan)); }); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs b/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs index 57e7f8ecfb5..6198469c77e 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs @@ -81,7 +81,7 @@ public string GetActionResultToken() => string.Concat(ActionReferencePrefix, public static ActionOptionsDependencyAnalyzer Create(CollectionRuleContext context, ICollectionRuleActionOperations actionOperations) { - var analyzer = new ActionOptionsDependencyAnalyzer(context, new ConfigurationTokenParser(context.Logger, actionOperations), actionOperations); + var analyzer = new ActionOptionsDependencyAnalyzer(context, new ConfigurationTokenParser(context.Logger), actionOperations); analyzer.EnsureDependencies(); return analyzer; } @@ -164,7 +164,11 @@ public IList GetActionDependencies(int actionIndex) } string? commandLine = _ruleContext.EndpointInfo.CommandLine; - settings = _tokenParser.SubstituteOptionValues(actionOptions, new TokenContext + if (!_actionOperations.TryGetOptionsType(actionOptions.Type, out Type settingsType)) + { + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownActionType, actionOptions.Name)); + } + settings = _tokenParser.SubstituteOptionValues(settings, settingsType, new TokenContext { CloneOnSubstitution = ReferenceEquals(originalSettings, settings), RuntimeId = _ruleContext.EndpointInfo.RuntimeInstanceCookie, diff --git a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs index 295a16057d6..be0fd9d8629 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs @@ -13,8 +13,10 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts; using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Diagnostics.Tracing; @@ -204,9 +206,9 @@ private void MapCollectionRuleActionOptions_Settings(string type, object? settin case KnownCollectionRuleActions.CollectLiveMetrics: MapCollectLiveMetricsOptions(settings as CollectLiveMetricsOptions, valueName, separator, map); break; - // case KnownCollectionRuleActions.CollectLogs: - // MapCollectLogsOptions(settings as CollectLogsOptions, valueName, separator, map); - // break; + case KnownCollectionRuleActions.CollectLogs: + MapCollectLogsOptions(settings as CollectLogsOptions, valueName, separator, map); + break; case KnownCollectionRuleActions.CollectStacks: MapCollectStacksOptions(settings as CollectStacksOptions, valueName, separator, map); break; @@ -357,6 +359,50 @@ private static void MapEventMetricsProvider(EventMetricsProvider obj, string val MapArray_String(obj.CounterNames, FormattableString.Invariant($"{prefix}{nameof(obj.CounterNames)}"), separator, map); } + static void MapCollectLogsOptions(CollectLogsOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapLogLevel(obj.DefaultLevel, FormattableString.Invariant($"{prefix}{nameof(obj.DefaultLevel)}"), map); + MapDictionary_String_LogLevel(obj.FilterSpecs, FormattableString.Invariant($"{prefix}{nameof(obj.FilterSpecs)}"), separator, map); + MapBool(obj.UseAppFilters, FormattableString.Invariant($"{prefix}{nameof(obj.UseAppFilters)}"), map); + MapTimeSpan(obj.Duration, FormattableString.Invariant($"{prefix}{nameof(obj.Duration)}"), map); + MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); + MapLogFormat(obj.Format, FormattableString.Invariant($"{prefix}{nameof(obj.Format)}"), map); + MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); + } + } + + static void MapLogLevel(LogLevel? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + + static void MapDictionary_String_LogLevel(IDictionary? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + foreach ((string key, LogLevel? value) in obj) + { + string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); + MapLogLevel(value, FormattableString.Invariant($"{prefix}{keyString}"), map); + } + } + } + + static void MapLogFormat(LogFormat? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + private static void MapArray_String(string[]? obj, string valueName, string separator, IDictionary map) { if (null != obj) @@ -608,36 +654,48 @@ private static void MapCollectionRuleTriggerOptions_Settings(string type, object { switch (type) { - // case KnownCollectionRuleTriggers.AspNetRequestCount: - // MapAspNetRequestCountOptions(settings as AspNetRequestCountOptions, valueName, separator, map); - // break; + case KnownCollectionRuleTriggers.AspNetRequestCount: + MapAspNetRequestCountOptions(settings as AspNetRequestCountOptions, valueName, separator, map); + break; case KnownCollectionRuleTriggers.AspNetRequestDuration: MapAspNetRequestDurationOptions(settings as AspNetRequestDurationOptions, valueName, separator, map); break; - // case KnownCollectionRuleTriggers.AspNetResponseStatus: - // MapAspNetResponseStatusOptions(settings as AspNetResponseStatusOptions, valueName, separator, map); - // break; - // case KnownCollectionRuleTriggers.EventCounter: - // MapEventCounterOptions(settings as EventCounterOptions, valueName, separator, map); - // break; - // case KnownCollectionRuleTriggers.CPUUsage: - // MapCPUUsageOptions(settings as CPUUsageOptions, valueName, separator, map); - // break; - // case KnownCollectionRuleTriggers.GCHeapSize: - // MapGCHeapSizeOptions(settings as GCHeapSizeOptions, valueName, separator, map); - // break; - // case KnownCollectionRuleTriggers.ThreadpoolQueueLength: - // MapThreadpoolQueueLengthOptions(settings as ThreadpoolQueueLengthOptions, valueName, separator, map); - // break; - // case KnownCollectionRuleTriggers.EventMeter: - // MapEventMeterOptions(settings as EventMeterOptions, valueName, separator, map); - // break; + case KnownCollectionRuleTriggers.AspNetResponseStatus: + MapAspNetResponseStatusOptions(settings as AspNetResponseStatusOptions, valueName, separator, map); + break; + case KnownCollectionRuleTriggers.EventCounter: + MapEventCounterOptions(settings as EventCounterOptions, valueName, separator, map); + break; + case KnownCollectionRuleTriggers.CPUUsage: + MapCPUUsageOptions(settings as CPUUsageOptions, valueName, separator, map); + break; + case KnownCollectionRuleTriggers.GCHeapSize: + MapGCHeapSizeOptions(settings as GCHeapSizeOptions, valueName, separator, map); + break; + case KnownCollectionRuleTriggers.ThreadpoolQueueLength: + MapThreadpoolQueueLengthOptions(settings as ThreadpoolQueueLengthOptions, valueName, separator, map); + break; + case KnownCollectionRuleTriggers.EventMeter: + MapEventMeterOptions(settings as EventMeterOptions, valueName, separator, map); + break; default: throw new NotSupportedException($"Unknown trigger type: {type}"); } } } + private static void MapAspNetRequestCountOptions(AspNetRequestCountOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapInt(obj.RequestCount, FormattableString.Invariant($"{prefix}{nameof(obj.RequestCount)}"), map); + MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); + MapArray_String(obj.IncludePaths, FormattableString.Invariant($"{prefix}{nameof(obj.IncludePaths)}"), separator, map); + MapArray_String(obj.ExcludePaths, FormattableString.Invariant($"{prefix}{nameof(obj.ExcludePaths)}"), separator, map); + } + } + private static void MapAspNetRequestDurationOptions(AspNetRequestDurationOptions? obj, string valueName, string separator, IDictionary map) { if (null != obj) @@ -651,6 +709,87 @@ private static void MapAspNetRequestDurationOptions(AspNetRequestDurationOptions } } + private static void MapAspNetResponseStatusOptions(AspNetResponseStatusOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapArray_String(obj.StatusCodes, FormattableString.Invariant($"{prefix}{nameof(obj.StatusCodes)}"), separator, map); + MapInt(obj.ResponseCount, FormattableString.Invariant($"{prefix}{nameof(obj.ResponseCount)}"), map); + MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); + MapArray_String(obj.IncludePaths, FormattableString.Invariant($"{prefix}{nameof(obj.IncludePaths)}"), separator, map); + MapArray_String(obj.ExcludePaths, FormattableString.Invariant($"{prefix}{nameof(obj.ExcludePaths)}"), separator, map); + } + } + + private static void MapEventCounterOptions(EventCounterOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.ProviderName, FormattableString.Invariant($"{prefix}{nameof(obj.ProviderName)}"), map); + MapString(obj.CounterName, FormattableString.Invariant($"{prefix}{nameof(obj.CounterName)}"), map); + MapDouble(obj.GreaterThan, FormattableString.Invariant($"{prefix}{nameof(obj.GreaterThan)}"), map); + MapDouble(obj.LessThan, FormattableString.Invariant($"{prefix}{nameof(obj.LessThan)}"), map); + MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); + } + } + + private static void MapCPUUsageOptions(CPUUsageOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapDouble(obj.GreaterThan, FormattableString.Invariant($"{prefix}{nameof(obj.GreaterThan)}"), map); + MapDouble(obj.LessThan, FormattableString.Invariant($"{prefix}{nameof(obj.LessThan)}"), map); + MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); + } + } + + private static void MapGCHeapSizeOptions(GCHeapSizeOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapDouble(obj.GreaterThan, FormattableString.Invariant($"{prefix}{nameof(obj.GreaterThan)}"), map); + MapDouble(obj.LessThan, FormattableString.Invariant($"{prefix}{nameof(obj.LessThan)}"), map); + MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); + } + } + + private static void MapThreadpoolQueueLengthOptions(ThreadpoolQueueLengthOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapDouble(obj.GreaterThan, FormattableString.Invariant($"{prefix}{nameof(obj.GreaterThan)}"), map); + MapDouble(obj.LessThan, FormattableString.Invariant($"{prefix}{nameof(obj.LessThan)}"), map); + MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); + } + } + + private static void MapEventMeterOptions(EventMeterOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.MeterName, FormattableString.Invariant($"{prefix}{nameof(obj.MeterName)}"), map); + MapString(obj.InstrumentName, FormattableString.Invariant($"{prefix}{nameof(obj.InstrumentName)}"), map); + MapDouble(obj.GreaterThan, FormattableString.Invariant($"{prefix}{nameof(obj.GreaterThan)}"), map); + MapDouble(obj.LessThan, FormattableString.Invariant($"{prefix}{nameof(obj.LessThan)}"), map); + MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); + MapInt(obj.HistogramPercentile, FormattableString.Invariant($"{prefix}{nameof(obj.HistogramPercentile)}"), map); + } + } + + private static void MapDouble(double? value, string valueName, IDictionary map) + { + if (null != value) + { + map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + } + private static void MapAuthenticationOptions(AuthenticationOptions? obj, string valueName, string separator, IDictionary map) { if (null != obj) diff --git a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs index b6df62ec79a..281369b94d1 100644 --- a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs +++ b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs @@ -37,7 +37,6 @@ internal sealed class TokenContext internal sealed class ConfigurationTokenParser { private readonly ILogger _logger; - private readonly ICollectionRuleActionOperations _actionOperations; public const string SubstitutionPrefix = "$("; public const string SubstitutionSuffix = ")"; @@ -60,23 +59,17 @@ internal sealed class ConfigurationTokenParser public static readonly string HostNameReference = CreateTokenReference(MonitorInfoReference, HostName); public static readonly string UnixTimeReference = CreateTokenReference(MonitorInfoReference, UnixTime); - public ConfigurationTokenParser(ILogger logger, ICollectionRuleActionOperations actionOperations) + public ConfigurationTokenParser(ILogger logger) { _logger = logger; - _actionOperations = actionOperations; } - public object? SubstituteOptionValues(CollectionRuleActionOptions actionOptions, TokenContext context) + public object? SubstituteOptionValues(object? originalSettings, Type settingsType, TokenContext context) { - var originalSettings = actionOptions.Settings; object? settings = originalSettings; - if (!_actionOperations.TryGetOptionsType(actionOptions.Type, out Type optionsType)) - { - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownActionType, actionOptions.Type)); - } - foreach (PropertyInfo propertyInfo in GetPropertiesFromSettings(optionsType)) + foreach (PropertyInfo propertyInfo in GetPropertiesFromSettings(settingsType)) { string? originalPropertyValue = (string?)propertyInfo.GetValue(settings); if (string.IsNullOrEmpty(originalPropertyValue)) From 9747391f615b33e288bd16a0ce01d49da5099afe Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 23 Apr 2025 23:16:03 +0000 Subject: [PATCH 141/174] Fix more failures - Pass type info to AzureAdOptionsTests - Propagate template lookup errors - Add custom validation to short-circuit when template lookup fails --- .../CustomValidationInfo.cs | 307 ++++++++++++++++++ .../TestValidatableType.cs | 3 + .../ValidatableInfoResolver.cs | 106 ++++-- .../CollectionRuleOptionsTests.cs | 5 +- .../Options/AzureAdOptionsTests.cs | 27 +- ...CollectionRulePostConfigureNamedOptions.cs | 13 +- .../Actions/CollectLogsOptions.Validate.cs | 49 +++ .../Actions/CollectTraceOptions.Validate.cs | 21 ++ .../Options/CollectionRuleOptions.cs | 4 +- .../dotnet-monitor/CommonOptionsMapper.cs | 68 +++- 10 files changed, 552 insertions(+), 51 deletions(-) create mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CustomValidationInfo.cs create mode 100644 src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CustomValidationInfo.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CustomValidationInfo.cs new file mode 100644 index 00000000000..098d33d9f66 --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CustomValidationInfo.cs @@ -0,0 +1,307 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Http.Validation; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using System.Threading; + +#nullable enable + +namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options +{ + public class CustomValidatableInfoResolver : IValidatableInfoResolver + { + public bool TryGetValidatableTypeInfo(Type type, [NotNullWhen(true)] out IValidatableInfo? validatableInfo) + { + if (type == typeof(CollectionRuleOptions)) + { + validatableInfo = CreateCollectionRuleOptions(); + return true; + } + + validatableInfo = null; + return false; + } + + public bool TryGetValidatableParameterInfo(ParameterInfo parameterInfo, [NotNullWhen(true)] out IValidatableInfo? validatableInfo) + { + validatableInfo = null; + return false; + } + + private static ValidatableTypeInfo CreateCollectionRuleOptions() + { + return new ShortCircuitingValidatableTypeInfo( + type: typeof(CollectionRuleOptions), + members: [ + new CustomValidatablePropertyInfo( + containingType: typeof(CollectionRuleOptions), + propertyType: typeof(CollectionRuleTriggerOptions), + name: "Trigger", + displayName: "Trigger" + ), + new CustomValidatablePropertyInfo( + containingType: typeof(CollectionRuleOptions), + propertyType: typeof(List), + name: "Actions", + displayName: "Actions" + ), + new CustomValidatablePropertyInfo( + containingType: typeof(CollectionRuleOptions), + propertyType: typeof(CollectionRuleLimitsOptions), + name: "Limits", + displayName: "Limits" + ), + ] + ); + } + + sealed class ShortCircuitingValidatableTypeInfo : ValidatableTypeInfo + { + public ShortCircuitingValidatableTypeInfo( + [param: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] + Type type, + ValidatablePropertyInfo[] members) : base(type, members) { + Type = type; + Members = members; + _membersCount = members.Length; + _subTypes = type.GetAllImplementedTypes(); + } + + private readonly int _membersCount; + private readonly List _subTypes; + + internal Type Type { get; } + internal IReadOnlyList Members { get; } + + public override async Task ValidateAsync(object? value, ValidateContext context, CancellationToken cancellationToken) + { + Debug.Assert(context.ValidationContext is not null); + if (value == null) + { + return; + } + + // Check if we've exceeded the maximum depth + if (context.CurrentDepth >= context.ValidationOptions.MaxDepth) + { + throw new InvalidOperationException( + $"Maximum validation depth of {context.ValidationOptions.MaxDepth} exceeded at '{context.CurrentValidationPath}' in '{Type.Name}'. " + + "This is likely caused by a circular reference in the object graph. " + + "Consider increasing the MaxDepth in ValidationOptions if deeper validation is required."); + } + + var originalPrefix = context.CurrentValidationPath; + + try + { + // Finally validate IValidatableObject if implemented + if (Type.ImplementsInterface(typeof(IValidatableObject)) && value is IValidatableObject validatable) + { + // Important: Set the DisplayName to the type name for top-level validations + // and restore the original validation context properties + var originalDisplayName = context.ValidationContext.DisplayName; + var originalMemberName = context.ValidationContext.MemberName; + + // Set the display name to the class name for IValidatableObject validation + context.ValidationContext.DisplayName = Type.Name; + context.ValidationContext.MemberName = null; + + var validationResults = validatable.Validate(context.ValidationContext); + bool hasErrors = false; + foreach (var validationResult in validationResults) + { + if (validationResult != ValidationResult.Success && validationResult.ErrorMessage is not null) + { + var memberName = validationResult.MemberNames.First(); + var key = string.IsNullOrEmpty(originalPrefix) ? + memberName : + $"{originalPrefix}.{memberName}"; + + context.AddOrExtendValidationError(key, validationResult.ErrorMessage); + hasErrors = true; + } + } + + // Restore the original validation context properties + context.ValidationContext.DisplayName = originalDisplayName; + context.ValidationContext.MemberName = originalMemberName; + if (hasErrors) + { + return; + } + } + + var actualType = value.GetType(); + + // First validate members + for (var i = 0; i < _membersCount; i++) + { + await Members[i].ValidateAsync(value, context, cancellationToken); + context.CurrentValidationPath = originalPrefix; + } + + // Then validate sub-types if any + foreach (var subType in _subTypes) + { + // Check if the actual type is assignable to the sub-type + // and validate it if it is + if (subType.IsAssignableFrom(actualType)) + { + if (context.ValidationOptions.TryGetValidatableTypeInfo(subType, out var subTypeInfo)) + { + await subTypeInfo.ValidateAsync(value, context, cancellationToken); + context.CurrentValidationPath = originalPrefix; + } + } + } + } + finally + { + context.CurrentValidationPath = originalPrefix; + } + } + } + + + sealed class CustomValidatableTypeInfo : ValidatableTypeInfo + { + public CustomValidatableTypeInfo( + [param: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] + Type type, + ValidatablePropertyInfo[] members) : base(type, members) { } + } + + sealed class CustomValidatablePropertyInfo : ValidatablePropertyInfo + { + public CustomValidatablePropertyInfo( + [param: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] + Type containingType, + Type propertyType, + string name, + string displayName) : base(containingType, propertyType, name, displayName) + { + ContainingType = containingType; + Name = name; + } + + internal Type ContainingType { get; } + internal string Name { get; } + + protected override ValidationAttribute[] GetValidationAttributes() + => ValidationAttributeCache.GetValidationAttributes(ContainingType, Name); + } + + static class ValidationAttributeCache + { + private sealed record CacheKey(Type ContainingType, string PropertyName); + private static readonly ConcurrentDictionary _cache = new(); + + public static ValidationAttribute[] GetValidationAttributes( + Type containingType, + string propertyName) + { + var key = new CacheKey(containingType, propertyName); + return _cache.GetOrAdd(key, static k => + { + var results = new List(); + + // Get attributes from the property + var property = k.ContainingType.GetProperty(k.PropertyName); + if (property != null) + { + var propertyAttributes = CustomAttributeExtensions.GetCustomAttributes(property, inherit: true); + + results.AddRange(propertyAttributes); + } + + // Check constructors for parameters that match the property name + // to handle record scenarios + foreach (var constructor in k.ContainingType.GetConstructors()) + { + // Look for parameter with matching name (case insensitive) + var parameter = Enumerable.FirstOrDefault( + constructor.GetParameters(), + p => string.Equals(p.Name, k.PropertyName, global::System.StringComparison.OrdinalIgnoreCase)); + + if (parameter != null) + { + var paramAttributes = CustomAttributeExtensions.GetCustomAttributes(parameter, inherit: true); + + results.AddRange(paramAttributes); + + break; + } + } + + return results.ToArray(); + }); + } + } + } + + internal static class TypeExtensions + { + public static List GetAllImplementedTypes([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] this Type type) + { + ArgumentNullException.ThrowIfNull(type); + + var implementedTypes = new List(); + + // Yield all interfaces directly and indirectly implemented by this type + foreach (var interfaceType in type.GetInterfaces()) + { + implementedTypes.Add(interfaceType); + } + + // Finally, walk up the inheritance chain + var baseType = type.BaseType; + while (baseType != null && baseType != typeof(object)) + { + implementedTypes.Add(baseType); + baseType = baseType.BaseType; + } + + return implementedTypes; + } + + public static bool ImplementsInterface(this Type type, Type interfaceType) + { + ArgumentNullException.ThrowIfNull(type); + ArgumentNullException.ThrowIfNull(interfaceType); + + // Check if interfaceType is actually an interface + if (!interfaceType.IsInterface) + { + throw new ArgumentException($"Type {interfaceType.FullName} is not an interface.", nameof(interfaceType)); + } + + return interfaceType.IsAssignableFrom(type); + } + } + + internal static class ValidateContextExtensions + { + internal static void AddOrExtendValidationError(this ValidateContext context, string key, string error) + { + context.ValidationErrors ??= []; + + if (context.ValidationErrors.TryGetValue(key, out var existingErrors) && !existingErrors.Contains(error)) + { + context.ValidationErrors[key] = [.. existingErrors, error]; + } + else + { + context.ValidationErrors[key] = [error]; + } + } + } +} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs index 94d1e5dad6f..dce48d1ce2c 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Http.Validation.Generated; using Microsoft.Extensions.DependencyInjection; using Microsoft.Diagnostics.Tools.Monitor; +using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts; @@ -61,6 +62,8 @@ internal sealed class TestValidatableTypes public required ThreadpoolQueueLengthOptions ThreadpoolQueueLengthOptions { get; init; } public required EventMeterOptions EventMeterOptions { get; init; } + // Nested member + public required EventPipeProvider EventPipeProvider { get; init; } // TODO: only one resolver per project? Generate this for tests, for now. Maybe want to separate this one out // by test later. diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs index 33cfe868ecc..4e11e02a0b7 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs @@ -9,6 +9,8 @@ //------------------------------------------------------------------------------ #nullable enable +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; + namespace System.Runtime.CompilerServices { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] @@ -74,11 +76,11 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateCollectionRuleLimitsOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions)) - { - validatableInfo = CreateCollectionRuleOptions(); - return true; - } + // if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions)) + // { + // validatableInfo = CreateCollectionRuleOptions(); + // return true; + // } if (type == typeof(global::System.Reflection.MethodBase)) { validatableInfo = CreateMethodBase(); @@ -359,6 +361,11 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateEventMeterOptions(); return true; } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider)) + { + validatableInfo = CreateEventPipeProvider(); + return true; + } if (type == typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions)) { validatableInfo = CreatePassThroughOptions(); @@ -434,32 +441,32 @@ private ValidatableTypeInfo CreateCollectionRuleLimitsOptions() ] ); } - private ValidatableTypeInfo CreateCollectionRuleOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), - name: "Trigger", - displayName: "Trigger" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - propertyType: typeof(global::System.Collections.Generic.List), - name: "Actions", - displayName: "Actions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - name: "Limits", - displayName: "Limits" - ), - ] - ); - } + // private ValidatableTypeInfo CreateCollectionRuleOptions() + // { + // return new GeneratedValidatableTypeInfo( + // type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + // members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + // propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + // name: "Trigger", + // displayName: "Trigger" + // ), + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + // propertyType: typeof(global::System.Collections.Generic.List), + // name: "Actions", + // displayName: "Actions" + // ), + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + // propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + // name: "Limits", + // displayName: "Limits" + // ), + // ] + // ); + // } private ValidatableTypeInfo CreateMethodBase() { return new GeneratedValidatableTypeInfo( @@ -1880,6 +1887,38 @@ private ValidatableTypeInfo CreateEventMeterOptions() ] ); } + private ValidatableTypeInfo CreateEventPipeProvider() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(string), + name: "Name", + displayName: "Name" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(string), + name: "Keywords", + displayName: "Keywords" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(global::System.Diagnostics.Tracing.EventLevel), + name: "EventLevel", + displayName: "EventLevel" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Arguments", + displayName: "Arguments" + ), + ] + ); + } private ValidatableTypeInfo CreatePassThroughOptions() { return new GeneratedValidatableTypeInfo( @@ -2045,13 +2084,14 @@ private ValidatableTypeInfo CreateTestValidatableTypes() [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] internal static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "YaPWBCMaf/YiusWOmOTnNE6zAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "9oH9pfUMx0r35bT1qr89ily/AQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => { options.Resolvers.Insert(0, new GeneratedValidatableInfoResolver()); + options.Resolvers.Add(new CustomValidatableInfoResolver()); if (configureOptions is not null) { configureOptions(options); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs index 7bf58757e2c..e695d9c827b 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs @@ -363,13 +363,12 @@ public Task CollectionRuleOptions_EventMeterTrigger_PropertyValidation() ex => { string[] failures = ex.Failures.ToArray(); - // Property validation failures will short-circuit the remainder of the validation - // rules, thus only observe 3 errors when one might expect 4 (GreaterThan or LessThan should be specified). - Assert.Equal(3, failures.Length); + Assert.Equal(4, failures.Length); VerifyRequiredMessage(failures, 0, nameof(EventMeterOptions.MeterName)); VerifyRequiredMessage(failures, 1, nameof(EventMeterOptions.InstrumentName)); VerifyRangeMessage(failures, 2, nameof(EventMeterOptions.SlidingWindowDuration), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue); + VerifyEitherRequiredMessage(failures, 3, nameof(EventMeterOptions.GreaterThan), nameof(EventMeterOptions.LessThan)); }); } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Options/AzureAdOptionsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Options/AzureAdOptionsTests.cs index 95966d09f04..3ab0b08d058 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Options/AzureAdOptionsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Options/AzureAdOptionsTests.cs @@ -1,8 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; +using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Tools.Monitor; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -10,9 +15,20 @@ namespace Microsoft.Diagnostics.Monitoring.Tool.UnitTests.Options { + public class AzureAdOptionsTestsFixture : WebApplicationFactory + { + } + [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] - public class AzureAdOptionsTests + public class AzureAdOptionsTests : IClassFixture { + private readonly AzureAdOptionsTestsFixture _fixture; + + public AzureAdOptionsTests(AzureAdOptionsTestsFixture fixture) + { + _fixture = fixture; + } + private static AzureAdOptions GetDefaultOptions() { return new AzureAdOptions @@ -32,9 +48,10 @@ public void AzureAdOptions_Requires_Role() options.RequiredRole = null; List results = new(); + var validationOptions = _fixture.Services.GetRequiredService>().Value; // Act - bool isValid = Validator.TryValidateObject(options, new(options), results, validateAllProperties: true); + bool isValid = ValidationHelper.TryValidateObject(options, typeof(AzureAdOptions), validationOptions, _fixture.Services, results); // Assert Assert.False(isValid); @@ -50,9 +67,10 @@ public void AzureAdOptions_Requires_TenantId() options.TenantId = null; List results = new(); + var validationOptions = _fixture.Services.GetRequiredService>().Value; // Act - bool isValid = Validator.TryValidateObject(options, new(options), results, validateAllProperties: true); + bool isValid = ValidationHelper.TryValidateObject(options, typeof(AzureAdOptions), validationOptions, _fixture.Services, results); // Assert Assert.False(isValid); @@ -68,9 +86,10 @@ public void AzureAdOptions_Requires_ClientId() options.ClientId = null; List results = new(); + var validationOptions = _fixture.Services.GetRequiredService>().Value; // Act - bool isValid = Validator.TryValidateObject(options, new(options), results, validateAllProperties: true); + bool isValid = ValidationHelper.TryValidateObject(options, typeof(AzureAdOptions), validationOptions, _fixture.Services, results); // Assert Assert.False(isValid); diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs index ef21189106a..6cdda996dde 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs @@ -56,7 +56,8 @@ private void ResolveActionList(CollectionRuleOptions ruleOptions, IConfiguration // The Section Key is the action index; the value (if present) is the name of the template if (SectionHasValue(actionSection)) { - TryGetTemplate(ruleOptions, _templateOptions.CollectionRuleActions, actionSection.Value, out CollectionRuleActionOptions templateActionOptions); + var memberName = nameof(ruleOptions.Actions) + "[" + ruleOptions.Actions.Count.ToString(CultureInfo.InvariantCulture) + "]"; + TryGetTemplate(ruleOptions, memberName, _templateOptions.CollectionRuleActions, actionSection.Value, out CollectionRuleActionOptions templateActionOptions); ruleOptions.Actions.Add(templateActionOptions); } @@ -79,7 +80,7 @@ private void ResolveTrigger(CollectionRuleOptions ruleOptions, IConfigurationSec if (SectionHasValue(section)) { - TryGetTemplate(ruleOptions, _templateOptions.CollectionRuleTriggers, section.Value, out CollectionRuleTriggerOptions triggerOptions); + TryGetTemplate(ruleOptions, nameof(ruleOptions.Trigger), _templateOptions.CollectionRuleTriggers, section.Value, out CollectionRuleTriggerOptions triggerOptions); ruleOptions.Trigger = triggerOptions; } @@ -100,7 +101,7 @@ private void ResolveFilterList(CollectionRuleOptions ruleOptions, IConfiguration // The Section Key is the filter index; the value (if present) is the name of the template if (SectionHasValue(filterSection)) { - TryGetTemplate(ruleOptions, _templateOptions.CollectionRuleFilters, filterSection.Value, out ProcessFilterDescriptor templateFilterOptions); + TryGetTemplate(ruleOptions, nameof(ruleOptions.Filters), _templateOptions.CollectionRuleFilters, filterSection.Value, out ProcessFilterDescriptor templateFilterOptions); ruleOptions.Filters.Add(templateFilterOptions); } @@ -121,18 +122,18 @@ private void ResolveLimits(CollectionRuleOptions ruleOptions, IConfigurationSect if (SectionHasValue(section)) { - TryGetTemplate(ruleOptions, _templateOptions.CollectionRuleLimits, section.Value, out CollectionRuleLimitsOptions limitsOptions); + TryGetTemplate(ruleOptions, nameof(ruleOptions.Limits), _templateOptions.CollectionRuleLimits, section.Value, out CollectionRuleLimitsOptions limitsOptions); ruleOptions.Limits = limitsOptions; } } - private static bool TryGetTemplate(CollectionRuleOptions ruleOptions, IDictionary templatesOptions, string templateKey, out T templatesValue) where T : new() + private static bool TryGetTemplate(CollectionRuleOptions ruleOptions, string memberName, IDictionary templatesOptions, string templateKey, out T templatesValue) where T : new() { if (!templatesOptions.TryGetValue(templateKey, out templatesValue)) { templatesValue = new(); - ruleOptions.ErrorList.Add(string.Format(CultureInfo.CurrentCulture, Strings.ErrorMessage_TemplateNotFound, templateKey)); + ruleOptions.ErrorList.Add((string.Format(CultureInfo.CurrentCulture, Strings.ErrorMessage_TemplateNotFound, templateKey), memberName)); return false; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs new file mode 100644 index 00000000000..e650ea7bbd1 --- /dev/null +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Extensions.Logging; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +#if UNITTEST +namespace Microsoft.Diagnostics.Monitoring.TestCommon.Options +#else +namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions +#endif +{ + partial record class CollectLogsOptions : + IValidatableObject + { + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + List results = new(); + + if (null != FilterSpecs) + { + RequiredAttribute requiredAttribute = new(); + EnumDataTypeAttribute enumValidationAttribute = new(typeof(LogLevel)); + + ValidationContext filterSpecsContext = new(FilterSpecs, validationContext, validationContext.Items); + filterSpecsContext.MemberName = nameof(FilterSpecs); + + // Validate that the category is not null and that the level is a valid level value. + foreach ((string category, LogLevel? level) in FilterSpecs) + { + ValidationResult? result = requiredAttribute.GetValidationResult(category, filterSpecsContext); + if (!result.IsSuccess()) + { + results.Add(result); + } + + result = enumValidationAttribute.GetValidationResult(level, filterSpecsContext); + if (!result.IsSuccess()) + { + results.Add(result); + } + } + } + + return results; + } + } +} diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs index 278547f7958..5db027f7bab 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Monitoring.WebApi.Validation; @@ -82,6 +83,26 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali { results.AddRange(e.Failures.Select((string failure) => new ValidationResult(e.Message))); } + + // Validate that each provider is valid. + int index = 0; + foreach (EventPipeProvider provider in Providers) + { + ValidationContext providerContext = new(provider, validationContext, validationContext.Items); + providerContext.MemberName = nameof(Providers) + "[" + index.ToString(CultureInfo.InvariantCulture) + "]"; + + // Note: generated validation logic doesn't recurse into members of T for List, when List is not required. + // Need to do the recursion ourselves. + var validationOptions = validationContext.GetRequiredService>().Value; + ValidationHelper.TryValidateObject(provider, typeof(EventPipeProvider), validationOptions, providerContext, results); + + if (counterOptions != null && !CounterValidator.ValidateProvider(counterOptions, provider, out string? errorMessage)) + { + results.Add(new ValidationResult(errorMessage, new[] { nameof(EventPipeProvider.Arguments) })); + } + + index++; + } } else { diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs index 1debff00e3c..b61dfb52836 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs @@ -30,7 +30,7 @@ internal sealed partial class CollectionRuleOptions #nullable enable [Display( - Name = nameof(Actions), + Name = nameof(Actions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Actions))] public List Actions { get; set; } = []; @@ -41,6 +41,6 @@ internal sealed partial class CollectionRuleOptions Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Limits))] public CollectionRuleLimitsOptions? Limits { get; set; } - internal List ErrorList { get; } = new List(); + internal List<(string Error, string MemberName)> ErrorList { get; } = new List<(string Error, string MemberName)>(); } } diff --git a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs index be0fd9d8629..6eed2682591 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs @@ -106,9 +106,8 @@ private void MapRootOptions(RootOptions obj, string prefix, string separator, ID // TODO: in Tests, it has an additional property. Weird. MapAuthenticationOptions(obj.Authentication, FormattableString.Invariant($"{prefix}{nameof(obj.Authentication)}"), separator, map); MapDictionary_String_CollectionRuleOptions(obj.CollectionRules, FormattableString.Invariant($"{prefix}{nameof(obj.CollectionRules)}"), separator, map); - // GlobalCounterOptions MapGlobalCounterOptions(obj.GlobalCounter, FormattableString.Invariant($"{prefix}{nameof(obj.GlobalCounter)}"), separator, map); - // InProcessFeaturesOptions + MapInProcessFeaturesOptions(obj.InProcessFeatures, FormattableString.Invariant($"{prefix}{nameof(obj.InProcessFeatures)}"), separator, map); // CorsConfigurationOptions MapDiagnosticPortOptions(obj.DiagnosticPort, FormattableString.Invariant($"{prefix}{nameof(obj.DiagnosticPort)}"), separator, map); MapEgressOptions(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), separator, map); @@ -863,7 +862,70 @@ private static void MapGlobalCounterOptions(GlobalCounterOptions? obj, string va MapFloat(obj.IntervalSeconds, FormattableString.Invariant($"{prefix}{nameof(obj.IntervalSeconds)}"), map); MapInt(obj.MaxHistograms, FormattableString.Invariant($"{prefix}{nameof(obj.MaxHistograms)}"), map); MapInt(obj.MaxTimeSeries, FormattableString.Invariant($"{prefix}{nameof(obj.MaxTimeSeries)}"), map); - // MapDictionary(obj.Providers, prefix, separator, map); + MapDictionary_String_GlobalProviderOptions(obj.Providers, FormattableString.Invariant($"{prefix}{nameof(obj.Providers)}"), separator, map); + } + } + + private static void MapDictionary_String_GlobalProviderOptions(IDictionary? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + foreach ((string key, GlobalProviderOptions value) in obj) + { + string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); + MapGlobalProviderOptions(value, FormattableString.Invariant($"{prefix}{keyString}"), separator, map); + } + } + } + + private static void MapGlobalProviderOptions(GlobalProviderOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapFloat(obj.IntervalSeconds, FormattableString.Invariant($"{prefix}{nameof(obj.IntervalSeconds)}"), map); + } + } + + private static void MapInProcessFeaturesOptions(InProcessFeaturesOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapBool(obj.Enabled, FormattableString.Invariant($"{prefix}{nameof(obj.Enabled)}"), map); + MapCallStacksOptions(obj.CallStacks, FormattableString.Invariant($"{prefix}{nameof(obj.CallStacks)}"), separator, map); + MapExceptionsOptions(obj.Exceptions, FormattableString.Invariant($"{prefix}{nameof(obj.Exceptions)}"), separator, map); + MapParameterCapturingOptions(obj.ParameterCapturing, FormattableString.Invariant($"{prefix}{nameof(obj.ParameterCapturing)}"), separator, map); + } + } + + private static void MapCallStacksOptions(CallStacksOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapBool(obj.Enabled, FormattableString.Invariant($"{prefix}{nameof(obj.Enabled)}"), map); + } + } + + private static void MapExceptionsOptions(ExceptionsOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapBool(obj.Enabled, FormattableString.Invariant($"{prefix}{nameof(obj.Enabled)}"), map); + MapInt(obj.TopLevelLimit, FormattableString.Invariant($"{prefix}{nameof(obj.TopLevelLimit)}"), map); + MapExceptionsConfiguration(obj.CollectionFilters, FormattableString.Invariant($"{prefix}{nameof(obj.CollectionFilters)}"), separator, map); + } + } + + private static void MapParameterCapturingOptions(ParameterCapturingOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapBool(obj.Enabled, FormattableString.Invariant($"{prefix}{nameof(obj.Enabled)}"), map); } } From ef7b701021a18c73773237e613503c07bee2818e Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Thu, 24 Apr 2025 17:08:00 +0000 Subject: [PATCH 142/174] Add back CollectionRuleOptions custom validation --- .../Options/CollectionRuleOptions.Validate.cs | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs new file mode 100644 index 00000000000..010f745ece2 --- /dev/null +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable disable + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Globalization; + +namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options +{ + partial class CollectionRuleOptions : IValidatableObject + { + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + List results = new(); + + // ErrorList is populated by incorrectly using templates - this will be empty if all templates names can be resolved or if templates are not used. + // results.AddRange(ErrorList); + foreach (var error in ErrorList) + { + results.Add(new ValidationResult(error.Error, [error.MemberName])); + } + + if (results.Count > 0) + { + return results; + } + + // ValidationContext filtersContext = new(Filters, validationContext, validationContext.Items); + // filtersContext.MemberName = nameof(Filters); + // ValidationHelper.TryValidateItems(Filters, filtersContext, results); + + // if (null != Trigger) + // { + // ValidationContext triggerContext = new(Trigger, validationContext, validationContext.Items); + // triggerContext.MemberName = nameof(Trigger); + // Validator.TryValidateObject(Trigger, triggerContext, results); + // } + + // ValidationContext actionsContext = new(Actions, validationContext, validationContext.Items); + // actionsContext.MemberName = nameof(Actions); + // ValidationHelper.TryValidateItems(Actions, actionsContext, results); + + var actionNames = new HashSet(StringComparer.Ordinal); + foreach (CollectionRuleActionOptions option in Actions) + { + if (!string.IsNullOrEmpty(option.Name) && !actionNames.Add(option.Name)) + { + results.Add(new ValidationResult( + string.Format(CultureInfo.CurrentCulture, Strings.ErrorMessage_DuplicateActionName, option.Name), + new[] { nameof(option.Name) })); + } + } + + return results; + } + } +} \ No newline at end of file From 8a7275384d3c77dae256bbfb69899682a4da002a Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Thu, 24 Apr 2025 18:32:57 +0000 Subject: [PATCH 143/174] Fix short-circuit test --- .../CollectionRuleOptionsTests.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs index e695d9c827b..ed3ba328fda 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs @@ -195,10 +195,7 @@ public Task CollectionRuleOptions_EventCounterTrigger_PropertyValidation() ex => { string[] failures = ex.Failures.ToArray(); - // Property validation failures will short-circuit the remainder of the validation - // rules, thus only observe 3 errors when one might expect 4 (the fourth being that - // either GreaterThan or LessThan should be specified). - Assert.Equal(3, failures.Length); + Assert.Equal(4, failures.Length); VerifyRequiredMessage(failures, 0, nameof(EventCounterOptions.ProviderName)); VerifyRequiredMessage(failures, 1, nameof(EventCounterOptions.CounterName)); VerifyRangeMessage(failures, 2, nameof(EventCounterOptions.SlidingWindowDuration), From 16422abb60e6d4a06185a884c103d2ce3588d107 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 25 Apr 2025 17:16:39 +0000 Subject: [PATCH 144/174] Revert "Add Name to DisplayAttribute" This reverts commit c3ef7e37a9cc8f5c43a5e2542e31631026db4e1f. --- .../AzureBlobEgressProviderOptions.cs | 15 --------------- .../S3Storage/S3StorageEgressProviderOptions.cs | 12 ------------ .../AuthenticationOptions.cs | 2 -- .../AzureAdOptions.cs | 5 ----- .../CallStacksOptions.cs | 1 - .../CorsConfigurationOptions.cs | 1 - .../DiagnosticPortOptions.cs | 4 ---- .../EgressOptions.cs | 2 -- .../ExceptionsOptions.cs | 3 --- .../FileSystemEgressProviderOptions.cs | 3 --- .../GlobalCounterOptions.cs | 4 ---- .../InProcessFeaturesOptions.cs | 4 ---- .../MetricsOptions.cs | 10 ---------- .../MonitorApiKeyOptions.cs | 3 --- .../ParameterCapturingOptions.cs | 1 - .../ProcessFilterOptions.cs | 13 ------------- .../StorageOptions.cs | 3 --- .../Options/ConsoleFormatterOptions.cs | 3 --- .../Options/ConsoleLoggerOptions.cs | 4 ---- .../Options/JsonConsoleFormatterOptions.cs | 4 ---- .../Options/LogLevelOptions.cs | 1 - .../Options/LoggingOptions.cs | 6 ------ .../Options/SimpleConsoleFormatterOptions.cs | 5 ----- .../Options/Actions/CollectDumpOptions.cs | 3 --- .../Options/Actions/CollectExceptionsOptions.cs | 4 ---- .../Options/Actions/CollectGCDumpOptions.cs | 2 -- .../Options/Actions/CollectLiveMetricsOptions.cs | 6 ------ .../Options/Actions/CollectLogsOptions.cs | 7 ------- .../Options/Actions/CollectStacksOptions.cs | 3 --- .../Options/Actions/CollectTraceOptions.cs | 8 -------- .../Options/Actions/ExecuteOptions.cs | 2 -- .../Actions/GetEnvironmentVariableOptions.cs | 1 - .../Options/Actions/LoadProfilerOptions.cs | 2 -- .../Actions/SetEnvironmentVariableOptions.cs | 2 -- .../Options/Actions/TraceEventFilter.cs | 3 --- .../CollectionRuleActionDefaultsOptions.cs | 1 - .../Options/CollectionRuleActionOptions.cs | 4 ---- .../Options/CollectionRuleDefaultsOptions.cs | 3 --- .../CollectionRuleLimitsDefaultsOptions.cs | 3 --- .../Options/CollectionRuleLimitsOptions.cs | 3 --- .../Options/CollectionRuleOptions.cs | 4 ---- .../CollectionRuleTriggerDefaultsOptions.cs | 3 --- .../Options/CollectionRuleTriggerOptions.cs | 2 -- .../CollectionRules/Options/TemplateOptions.cs | 4 ---- .../Options/Triggers/AspNetRequestCountOptions.cs | 4 ---- .../Triggers/AspNetRequestDurationOptions.cs | 5 ----- .../Triggers/AspNetResponseStatusOptions.cs | 5 ----- .../Options/Triggers/EventCounterOptions.cs | 5 ----- .../EventCounterShortcuts/CPUUsageOptions.cs | 3 --- .../EventCounterShortcuts/GCHeapSizeOptions.cs | 3 --- .../ThreadpoolQueueLengthOptions.cs | 4 +--- .../Options/Triggers/EventMeterOptions.cs | 6 ------ 52 files changed, 1 insertion(+), 213 deletions(-) diff --git a/src/Extensions/AzureBlobStorage/AzureBlobEgressProviderOptions.cs b/src/Extensions/AzureBlobStorage/AzureBlobEgressProviderOptions.cs index 544b4b4020b..dcfd74a2fe2 100644 --- a/src/Extensions/AzureBlobStorage/AzureBlobEgressProviderOptions.cs +++ b/src/Extensions/AzureBlobStorage/AzureBlobEgressProviderOptions.cs @@ -11,94 +11,79 @@ namespace Microsoft.Diagnostics.Monitoring.AzureBlobStorage internal sealed partial class AzureBlobEgressProviderOptions { [Display( - Name = nameof(AccountUri), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_AccountUri))] [Required] public Uri AccountUri { get; set; } [Display( - Name = nameof(AccountKey), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_AccountKey))] public string AccountKey { get; set; } [Display( - Name = nameof(AccountKeyName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_AccountKeyName))] public string AccountKeyName { get; set; } [Display( - Name = nameof(SharedAccessSignature), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_SharedAccessSignature))] public string SharedAccessSignature { get; set; } [Display( - Name = nameof(SharedAccessSignatureName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_SharedAccessSignatureName))] public string SharedAccessSignatureName { get; set; } [Display( - Name = nameof(ManagedIdentityClientId), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_ManagedIdentityClientId))] public string ManagedIdentityClientId { get; set; } [Display( - Name = nameof(UseWorkloadIdentityFromEnvironment), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_UseWorkloadIdentityFromEnvironment))] public bool? UseWorkloadIdentityFromEnvironment { get; set; } [Display( - Name = nameof(ContainerName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_ContainerName))] [Required] public string ContainerName { get; set; } [Display( - Name = nameof(BlobPrefix), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_BlobPrefix))] public string BlobPrefix { get; set; } [Display( - Name = nameof(CopyBufferSize), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CommonEgressProviderOptions_CopyBufferSize))] [Range(1, int.MaxValue)] public int? CopyBufferSize { get; set; } [Display( - Name = nameof(QueueName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_QueueName))] public string QueueName { get; set; } [Display( - Name = nameof(QueueAccountUri), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_QueueAccountUri))] public Uri QueueAccountUri { get; set; } [Display( - Name = nameof(QueueSharedAccessSignature), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_QueueSharedAccessSignature))] public string QueueSharedAccessSignature { get; set; } [Display( - Name = nameof(QueueSharedAccessSignatureName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_QueueSharedAccessSignatureName))] public string QueueSharedAccessSignatureName { get; set; } [Display( - Name = nameof(Metadata), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureBlobEgressProviderOptions_Metadata))] public IDictionary Metadata { get; set; } diff --git a/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs b/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs index 45b83bd316e..5e868364369 100644 --- a/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs +++ b/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs @@ -13,50 +13,42 @@ namespace Microsoft.Diagnostics.Monitoring.Extension.S3Storage internal sealed partial class S3StorageEgressProviderOptions { [Display( - Name = nameof(Endpoint), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_Endpoint))] public string? Endpoint { get; set; } [Display( - Name = nameof(BucketName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_BucketName))] [Required(AllowEmptyStrings = false)] public string BucketName { get; set; } = string.Empty; [Display( - Name = nameof(RegionName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_RegionName))] public string? RegionName { get; set; } [Display( - Name = nameof(AccessKeyId), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_AccessKeyId))] public string? AccessKeyId { get; set; } [Display( - Name = nameof(SecretAccessKey), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_SecretAccessKey))] public string? SecretAccessKey { get; set; } [Display( - Name = nameof(AwsProfileName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_AWSProfileName))] public string? AwsProfileName { get; set; } [Display( - Name = nameof(AwsProfilePath), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_AWSProfilePath))] public string? AwsProfilePath { get; set; } [Display( - Name = nameof(PreSignedUrlExpiry), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_PreSignedUrlExpiry))] [Range(typeof(TimeSpan), "00:01:00", "1.00:00:00")] @@ -64,26 +56,22 @@ internal sealed partial class S3StorageEgressProviderOptions public TimeSpan? PreSignedUrlExpiry { get; set; } [Display( - Name = nameof(ForcePathStyle), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_ForcePathStyle))] public bool ForcePathStyle { get; set; } [Display( - Name = nameof(CopyBufferSize), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CommonEgressProviderOptions_CopyBufferSize))] [Range(1, int.MaxValue)] public int? CopyBufferSize { get; set; } [Display( - Name = nameof(UseKmsEncryption), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_UseKmsEncryption))] public bool UseKmsEncryption { get; set; } [Display( - Name = nameof(KmsEncryptionKey), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_KmsEncryptionKey))] public string? KmsEncryptionKey { get; set; } diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.cs index afc9d6b623c..8b2b8567588 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.cs @@ -9,13 +9,11 @@ namespace Microsoft.Diagnostics.Tools.Monitor internal sealed partial class AuthenticationOptions { [Display( - Name = nameof(MonitorApiKey), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AuthenticationOptions_MonitorApiKey))] public MonitorApiKeyOptions? MonitorApiKey { get; set; } [Display( - Name = nameof(AzureAd), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AuthenticationOptions_AzureAd))] public AzureAdOptions? AzureAd { get; set; } diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/AzureAdOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/AzureAdOptions.cs index e5cdd5c85fd..dd8e6eecace 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/AzureAdOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/AzureAdOptions.cs @@ -11,34 +11,29 @@ namespace Microsoft.Diagnostics.Tools.Monitor internal sealed partial class AzureAdOptions { [Display( - Name = nameof(Instance), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureAdOptions_Instance))] [DefaultValue(AzureAdOptionsDefaults.DefaultInstance)] public Uri? Instance { get; set; } [Display( - Name = nameof(TenantId), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureAdOptions_TenantId))] [Required] public string TenantId { get; set; } = string.Empty; [Display( - Name = nameof(ClientId), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureAdOptions_ClientId))] [Required] public string ClientId { get; set; } = string.Empty; [Display( - Name = nameof(AppIdUri), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureAdOptions_AppIdUri))] public Uri? AppIdUri { get; set; } [Display( - Name = nameof(RequiredRole), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AzureAdOptions_RequiredRole))] [Required] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/CallStacksOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/CallStacksOptions.cs index e2c091ad9be..7ed2b6ef532 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/CallStacksOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/CallStacksOptions.cs @@ -11,7 +11,6 @@ public sealed class CallStacksOptions : IInProcessFeatureOptions { [Display( - Name = nameof(Enabled), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CallStacksOptions_Enabled))] [DefaultValue(CallStacksOptionsDefaults.Enabled)] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/CorsConfigurationOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/CorsConfigurationOptions.cs index d5451967e6a..c2b905fb636 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/CorsConfigurationOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/CorsConfigurationOptions.cs @@ -8,7 +8,6 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi public class CorsConfigurationOptions { [Display( - Name = nameof(AllowedOrigins), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CorsConfiguration_AllowedOrigins))] [Required] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortOptions.cs index f0bf626f983..cb6d4431ca4 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/DiagnosticPortOptions.cs @@ -9,26 +9,22 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi public class DiagnosticPortOptions { [Display( - Name = nameof(ConnectionMode), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_DiagnosticPortOptions_ConnectionMode))] [DefaultValue(DiagnosticPortOptionsDefaults.ConnectionMode)] public DiagnosticPortConnectionMode? ConnectionMode { get; set; } [Display( - Name = nameof(EndpointName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_DiagnosticPortOptions_EndpointName))] public string? EndpointName { get; set; } [Display( - Name = nameof(MaxConnections), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_DiagnosticPortOptions_MaxConnections))] public int? MaxConnections { get; set; } [Display( - Name = nameof(DeleteEndpointOnStartup), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_DiagnosticPortOptions_DeleteEndpointOnStartup))] [DefaultValue(DiagnosticPortOptionsDefaults.DeleteEndpointOnStartup)] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/EgressOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/EgressOptions.cs index 32b79b4016b..b0b07ca343e 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/EgressOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/EgressOptions.cs @@ -11,13 +11,11 @@ namespace Microsoft.Diagnostics.Tools.Monitor internal sealed class EgressOptions { [Display( - Name = nameof(FileSystem), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EgressOptions_FileSystem))] public IDictionary? FileSystem { get; set; } [Display( - Name = nameof(Properties), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EgressOptions_Properties))] public IDictionary? Properties { get; set; } diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/ExceptionsOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/ExceptionsOptions.cs index 787bc1b2d15..db816efd44e 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/ExceptionsOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/ExceptionsOptions.cs @@ -11,14 +11,12 @@ public sealed class ExceptionsOptions : IInProcessFeatureOptions { [Display( - Name = nameof(Enabled), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ExceptionsOptions_Enabled))] [DefaultValue(ExceptionsOptionsDefaults.Enabled)] public bool? Enabled { get; set; } [Display( - Name = nameof(TopLevelLimit), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ExceptionsOptions_TopLevelLimit))] [Range(1, int.MaxValue)] @@ -26,7 +24,6 @@ public sealed class ExceptionsOptions : public int? TopLevelLimit { get; set; } [Display( - Name = nameof(CollectionFilters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ExceptionsOptions_CollectionFilters))] public ExceptionsConfiguration? CollectionFilters { get; set; } diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/FileSystemEgressProviderOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/FileSystemEgressProviderOptions.cs index 3dcc4953c9c..0caee405036 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/FileSystemEgressProviderOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/FileSystemEgressProviderOptions.cs @@ -15,20 +15,17 @@ internal sealed class FileSystemEgressProviderOptions public const int CopyBufferSize_MaxValue = int.MaxValue; [Display( - Name = nameof(DirectoryPath), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_FileSystemEgressProviderOptions_DirectoryPath))] [Required] public string DirectoryPath { get; set; } = string.Empty; [Display( - Name = nameof(IntermediateDirectoryPath), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_FileSystemEgressProviderOptions_IntermediateDirectoryPath))] public string? IntermediateDirectoryPath { get; set; } [Display( - Name = nameof(CopyBufferSize), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CommonEgressProviderOptions_CopyBufferSize))] [Range(CopyBufferSize_MinValue, CopyBufferSize_MaxValue)] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs index 9dc0450e83e..c360b5184d1 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs @@ -16,7 +16,6 @@ public partial class GlobalCounterOptions public const float IntervalMaxSeconds = 60 * 60 * 24; // One day [Display( - Name = nameof(IntervalSeconds), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_GlobalCounterOptions_IntervalSeconds))] [Range(IntervalMinSeconds, IntervalMaxSeconds)] @@ -24,7 +23,6 @@ public partial class GlobalCounterOptions public float? IntervalSeconds { get; set; } [Display( - Name = nameof(MaxHistograms), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_MaxHistograms))] [DefaultValue(GlobalCounterOptionsDefaults.MaxHistograms)] @@ -32,7 +30,6 @@ public partial class GlobalCounterOptions public int? MaxHistograms { get; set; } [Display( - Name = nameof(MaxTimeSeries), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_MaxTimeSeries))] [DefaultValue(GlobalCounterOptionsDefaults.MaxTimeSeries)] @@ -40,7 +37,6 @@ public partial class GlobalCounterOptions public int? MaxTimeSeries { get; set; } [Display( - Name = nameof(Providers), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_GlobalCounterOptions_Providers))] public System.Collections.Generic.IDictionary? Providers { get; set; } = new Dictionary(StringComparer.OrdinalIgnoreCase); diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/InProcessFeaturesOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/InProcessFeaturesOptions.cs index 0bd7a2f8b3e..0d7dadbd92f 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/InProcessFeaturesOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/InProcessFeaturesOptions.cs @@ -13,26 +13,22 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class InProcessFeaturesOptions { [Display( - Name = nameof(Enabled), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_InProcessFeaturesOptions_Enabled))] [DefaultValue(InProcessFeaturesOptionsDefaults.Enabled)] public bool? Enabled { get; set; } [Display( - Name = nameof(CallStacks), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_InProcessFeaturesOptions_CallStacks))] public CallStacksOptions? CallStacks { get; set; } [Display( - Name = nameof(Exceptions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_InProcessFeaturesOptions_Exceptions))] public ExceptionsOptions? Exceptions { get; set; } [Display( - Name = nameof(ParameterCapturing), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_InProcessFeaturesOptions_ParameterCapturing))] [Experimental] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/MetricsOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/MetricsOptions.cs index 794ebae9843..faa647690f3 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/MetricsOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/MetricsOptions.cs @@ -17,20 +17,17 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi public class MetricsOptions { [Display( - Name = nameof(Enabled), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_Enabled))] [DefaultValue(MetricsOptionsDefaults.Enabled)] public bool? Enabled { get; set; } [Display( - Name = nameof(Endpoints), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_Endpoints))] public string? Endpoints { get; set; } [Display( - Name = nameof(MetricCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_MetricCount))] [DefaultValue(MetricsOptionsDefaults.MetricCount)] @@ -38,20 +35,17 @@ public class MetricsOptions public int? MetricCount { get; set; } [Display( - Name = nameof(IncludeDefaultProviders), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_IncludeDefaultProviders))] [DefaultValue(MetricsOptionsDefaults.IncludeDefaultProviders)] public bool? IncludeDefaultProviders { get; set; } [Display( - Name = nameof(Providers), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_Providers))] public List Providers { get; set; } = []; [Display( - Name = nameof(Meters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricsOptions_Meters))] public List Meters { get; set; } = []; @@ -60,14 +54,12 @@ public class MetricsOptions public class MetricProvider { [Display( - Name = nameof(ProviderName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricProvider_ProviderName))] [Required] public string ProviderName { get; set; } = string.Empty; [Display( - Name = nameof(CounterNames), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MetricProvider_CounterNames))] public List CounterNames { get; set; } = []; @@ -76,13 +68,11 @@ public class MetricProvider public class MeterConfiguration { [Display( - Name = nameof(MeterName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MeterConfiguration_MeterName))] public string? MeterName { get; set; } [Display( - Name = nameof(InstrumentNames), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MeterConfiguration_InstrumentNames))] public List InstrumentNames { get; set; } = []; diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/MonitorApiKeyOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/MonitorApiKeyOptions.cs index c3e751c5b1b..d37c2c6449d 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/MonitorApiKeyOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/MonitorApiKeyOptions.cs @@ -9,14 +9,12 @@ namespace Microsoft.Diagnostics.Tools.Monitor internal sealed class MonitorApiKeyOptions { [Display( - Name = nameof(Subject), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MonitorApiKeyOptions_Subject))] [Required] public string Subject { get; set; } = string.Empty; [Display( - Name = nameof(PublicKey), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MonitorApiKeyOptions_PublicKey))] [RegularExpression("[0-9a-zA-Z_-]+")] @@ -24,7 +22,6 @@ internal sealed class MonitorApiKeyOptions public string PublicKey { get; set; } = string.Empty; [Display( - Name = nameof(Issuer), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_MonitorApiKeyOptions_Issuer))] public string? Issuer { get; set; } diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/ParameterCapturingOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/ParameterCapturingOptions.cs index a11d9a91d4b..fe195a8f1ba 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/ParameterCapturingOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/ParameterCapturingOptions.cs @@ -11,7 +11,6 @@ public sealed class ParameterCapturingOptions : IInProcessFeatureOptions { [Display( - Name = nameof(Enabled), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ParameterCapturingOptions_Enabled))] [DefaultValue(ParameterCapturingOptionsDefaults.Enabled)] diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/ProcessFilterOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/ProcessFilterOptions.cs index 67677775b77..451d18a9cab 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/ProcessFilterOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/ProcessFilterOptions.cs @@ -10,17 +10,14 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi public enum ProcessFilterKey { [Display( - Name = nameof(ProcessId), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterKey_ProcessId))] ProcessId, [Display( - Name = nameof(ProcessName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterKey_ProcessName))] ProcessName, [Display( - Name = nameof(CommandLine), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterKey_CommandLine))] CommandLine, @@ -30,13 +27,11 @@ public enum ProcessFilterKey public enum ProcessFilterType { [Display( - Name = nameof(Exact), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterType_Exact))] Exact, [Display( - Name = nameof(Contains), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterType_Contains))] Contains, @@ -45,7 +40,6 @@ public enum ProcessFilterType public sealed class ProcessFilterOptions { [Display( - Name = nameof(Filters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterOptions_Filters))] public List Filters { get; set; } = []; @@ -54,44 +48,37 @@ public sealed class ProcessFilterOptions public sealed partial class ProcessFilterDescriptor { [Display( - Name = nameof(Key), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_Key))] public ProcessFilterKey Key { get; set; } [Display( - Name = nameof(Value), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_Value))] public string? Value { get; set; } [Display( - Name = nameof(MatchType), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_MatchType))] [DefaultValue(ProcessFilterType.Exact)] public ProcessFilterType MatchType { get; set; } = ProcessFilterType.Exact; [Display( - Name = nameof(ProcessName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_ProcessName))] public string? ProcessName { get; set; } [Display( - Name = nameof(ProcessId), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_ProcessId))] public string? ProcessId { get; set; } [Display( - Name = nameof(CommandLine), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_CommandLine))] public string? CommandLine { get; set; } [Display( - Name = nameof(ManagedEntryPointAssemblyName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ProcessFilterDescriptor_ManagedEntryPointAssemblyName))] public string? ManagedEntryPointAssemblyName { get; set; } diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/StorageOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/StorageOptions.cs index 1c410810cef..39c925fee41 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/StorageOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/StorageOptions.cs @@ -9,20 +9,17 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi public class StorageOptions { [Display( - Name = nameof(DefaultSharedPath), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_StorageOptions_DefaultSharedPath))] public string? DefaultSharedPath { get; set; } [Display( - Name = nameof(DumpTempFolder), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_StorageOptions_DumpTempFolder))] public string? DumpTempFolder { get; set; } [Experimental] [Display( - Name = nameof(SharedLibraryPath), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_StorageOptions_SharedLibraryPath))] public string? SharedLibraryPath { get; set; } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleFormatterOptions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleFormatterOptions.cs index a3dd2c33dbe..111d30c9897 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleFormatterOptions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleFormatterOptions.cs @@ -10,20 +10,17 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class ConsoleFormatterOptions { [Display( - Name = nameof(IncludeScopes), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_IncludeScopes))] public bool IncludeScopes { get; set; } [Display( - Name = nameof(TimestampFormat), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_TimestampFormat))] [DefaultValue(null)] public string? TimestampFormat { get; set; } [Display( - Name = nameof(UseUtcTimestamp), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_UseUtcTimestamp))] [DefaultValue(false)] diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleLoggerOptions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleLoggerOptions.cs index f4700cab8df..67a672fda0e 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleLoggerOptions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/ConsoleLoggerOptions.cs @@ -12,26 +12,22 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class ConsoleLoggerOptions { [Display( - Name = nameof(FormatterName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleLoggerOptions_FormatterName))] [DefaultValue(ConsoleLoggerFormat.Simple)] public ConsoleLoggerFormat FormatterName { get; set; } = ConsoleLoggerFormat.Simple; [Display( - Name = nameof(LogToStandardErrorThreshold), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleLoggerOptions_LogToStandardErrorThreshold))] public LogLevel LogToStandardErrorThreshold { get; set; } [Display( - Name = nameof(FormatterOptions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleLoggerOptions_FormatterOptions))] public object? FormatterOptions { get; set; } [Display( - Name = nameof(LogLevel), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleLoggerOptions_LogLevel))] public IDictionary? LogLevel { get; set; } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/JsonConsoleFormatterOptions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/JsonConsoleFormatterOptions.cs index efea74486b2..340249c50ba 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/JsonConsoleFormatterOptions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/JsonConsoleFormatterOptions.cs @@ -11,26 +11,22 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class JsonConsoleFormatterOptions { [Display( - Name = nameof(JsonWriterOptions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_JsonConsoleFormatterOptions_WriterOptions))] public JsonWriterOptions JsonWriterOptions { get; set; } [Display( - Name = nameof(IncludeScopes), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_IncludeScopes))] public bool IncludeScopes { get; set; } [Display( - Name = nameof(TimestampFormat), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_TimestampFormat))] [DefaultValue(null)] public string? TimestampFormat { get; set; } [Display( - Name = nameof(UseUtcTimestamp), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_UseUtcTimestamp))] [DefaultValue(false)] diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LogLevelOptions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LogLevelOptions.cs index 086065809cb..e98f40cc06d 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LogLevelOptions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LogLevelOptions.cs @@ -11,7 +11,6 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class LogLevelOptions { [Display( - Name = nameof(LogLevel), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LogLevelOptions_LogLevel))] public IDictionary? LogLevel { get; set; } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LoggingOptions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LoggingOptions.cs index 168ed1b79fa..87b2191428d 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LoggingOptions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/LoggingOptions.cs @@ -12,37 +12,31 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class LoggingOptions { [Display( - Name = nameof(LogLevel), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoggingOptions_LogLevel))] public IDictionary? LogLevel { get; set; } [Display( - Name = nameof(Console), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoggingOptions_Console))] public ConsoleLoggerOptions? Console { get; set; } [Display( - Name = nameof(EventLog), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoggingOptions_EventLog))] public LogLevelOptions? EventLog { get; set; } [Display( - Name = nameof(Debug), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoggingOptions_Debug))] public LogLevelOptions? Debug { get; set; } [Display( - Name = nameof(EventSource), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoggingOptions_EventSource))] public LogLevelOptions? EventSource { get; set; } [Display( - Name = nameof(CaptureScopes), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoggingOptions_CaptureScopes))] [DefaultValue(true)] diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/SimpleConsoleFormatterOptions.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/SimpleConsoleFormatterOptions.cs index 91accf8ef1a..5e947480b99 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/SimpleConsoleFormatterOptions.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Options/SimpleConsoleFormatterOptions.cs @@ -12,33 +12,28 @@ namespace Microsoft.Diagnostics.Monitoring.Options internal sealed class SimpleConsoleFormatterOptions { [Display( - Name = nameof(ColorBehavior), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_SimpleConsoleFormatterOptions_ColorBehavior))] [JsonConverter(typeof(JsonStringEnumConverter))] public LoggerColorBehavior ColorBehavior { get; set; } [Display( - Name = nameof(SingleLine), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_SimpleConsoleFormatterOptions_SingleLine))] public bool SingleLine { get; set; } [Display( - Name = nameof(IncludeScopes), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_IncludeScopes))] public bool IncludeScopes { get; set; } [Display( - Name = nameof(TimestampFormat), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_TimestampFormat))] [DefaultValue(null)] public string? TimestampFormat { get; set; } [Display( - Name = nameof(UseUtcTimestamp), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ConsoleFormatterOptions_UseUtcTimestamp))] [DefaultValue(false)] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectDumpOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectDumpOptions.cs index cc2db3004d4..cb8c950fcff 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectDumpOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectDumpOptions.cs @@ -22,7 +22,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed partial record class CollectDumpOptions : BaseRecordOptions, IEgressProviderProperties { [Display( - Name = nameof(Type), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectDumpOptions_Type))] [EnumDataType(typeof(DumpType))] @@ -30,7 +29,6 @@ internal sealed partial record class CollectDumpOptions : BaseRecordOptions, IEg public DumpType? Type { get; set; } [Display( - Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -42,7 +40,6 @@ internal sealed partial record class CollectDumpOptions : BaseRecordOptions, IEg public string Egress { get; set; } = string.Empty; [Display( - Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs index e8b686159ee..34ea08dc30b 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs @@ -23,7 +23,6 @@ internal sealed partial record class CollectExceptionsOptions : IEgressProviderProperties { [Display( - Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -35,20 +34,17 @@ internal sealed partial record class CollectExceptionsOptions : public string Egress { get; set; } = string.Empty; [Display( - Name = nameof(Format), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectExceptionsOptions_Format))] [DefaultValue(CollectExceptionsOptionsDefaults.Format)] public ExceptionFormat? Format { get; set; } [Display( - Name = nameof(Filters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectExceptionsOptions_Filters))] public ExceptionsConfiguration? Filters { get; set; } [Display( - Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectGCDumpOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectGCDumpOptions.cs index 37443fbe7a3..bdc0c61c1b2 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectGCDumpOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectGCDumpOptions.cs @@ -20,7 +20,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed partial record class CollectGCDumpOptions : BaseRecordOptions, IEgressProviderProperties { [Display( - Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -32,7 +31,6 @@ internal sealed partial record class CollectGCDumpOptions : BaseRecordOptions, I public string Egress { get; set; } = string.Empty; [Display( - Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs index 4e78cafde04..7010eac43f3 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs @@ -24,26 +24,22 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed partial record class CollectLiveMetricsOptions : BaseRecordOptions, IEgressProviderProperties { [Display( - Name = nameof(IncludeDefaultProviders), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLiveMetricsOptions_IncludeDefaultProviders))] [DefaultValue(CollectLiveMetricsOptionsDefaults.IncludeDefaultProviders)] public bool? IncludeDefaultProviders { get; set; } [Display( - Name = nameof(Providers), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLiveMetricsOptions_Providers))] public EventMetricsProvider[]? Providers { get; set; } [Display( - Name = nameof(Meters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLiveMetricsOptions_Meters))] public EventMetricsMeter[]? Meters { get; set; } [Display( - Name = nameof(Duration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Duration))] [Range(typeof(TimeSpan), ActionOptionsConstants.Duration_MinValue, ActionOptionsConstants.Duration_MaxValue)] @@ -52,7 +48,6 @@ internal sealed partial record class CollectLiveMetricsOptions : BaseRecordOptio public TimeSpan? Duration { get; set; } [Display( - Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -64,7 +59,6 @@ internal sealed partial record class CollectLiveMetricsOptions : BaseRecordOptio public string Egress { get; set; } = string.Empty; [Display( - Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs index 74477c54523..147ebb29ddc 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs @@ -26,7 +26,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed partial record class CollectLogsOptions : BaseRecordOptions, IEgressProviderProperties { [Display( - Name = nameof(DefaultLevel), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLogsOptions_DefaultLevel))] [EnumDataType(typeof(LogLevel))] @@ -34,20 +33,17 @@ internal sealed partial record class CollectLogsOptions : BaseRecordOptions, IEg public LogLevel? DefaultLevel { get; set; } [Display( - Name = nameof(FilterSpecs), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLogsOptions_FilterSpecs))] public Dictionary? FilterSpecs { get; set; } [Display( - Name = nameof(UseAppFilters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLogsOptions_UseAppFilters))] [DefaultValue(CollectLogsOptionsDefaults.UseAppFilters)] public bool? UseAppFilters { get; set; } [Display( - Name = nameof(Duration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Duration))] [Range(typeof(TimeSpan), ActionOptionsConstants.Duration_MinValue, ActionOptionsConstants.Duration_MaxValue)] @@ -56,7 +52,6 @@ internal sealed partial record class CollectLogsOptions : BaseRecordOptions, IEg public TimeSpan? Duration { get; set; } [Display( - Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -68,7 +63,6 @@ internal sealed partial record class CollectLogsOptions : BaseRecordOptions, IEg public string Egress { get; set; } = string.Empty; [Display( - Name = nameof(Format), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectLogsOptions_Format))] [DefaultValue(CollectLogsOptionsDefaults.Format)] @@ -76,7 +70,6 @@ internal sealed partial record class CollectLogsOptions : BaseRecordOptions, IEg public LogFormat? Format { get; set; } [Display( - Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.cs index ddb47c51ec4..e1958403170 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.cs @@ -25,7 +25,6 @@ internal enum CallStackFormat internal sealed partial record class CollectStacksOptions : BaseRecordOptions, IEgressProviderProperties { [Display( - Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -37,14 +36,12 @@ internal sealed partial record class CollectStacksOptions : BaseRecordOptions, I public string Egress { get; set; } = string.Empty; [Display( - Name = nameof(Format), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectStacksOptions_Format))] [DefaultValue(CallStackFormat.Json)] public CallStackFormat? Format { get; set; } [Display( - Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs index ca40aa8cf38..2491c12a88b 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs @@ -25,27 +25,23 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed partial record class CollectTraceOptions : BaseRecordOptions, IEgressProviderProperties { [Display( - Name = nameof(Profile), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectTraceOptions_Profile))] [EnumDataType(typeof(TraceProfile))] public TraceProfile? Profile { get; set; } [Display( - Name = nameof(Providers), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectTraceOptions_Providers))] public List? Providers { get; set; } [Display( - Name = nameof(RequestRundown), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectTraceOptions_RequestRundown))] [DefaultValue(CollectTraceOptionsDefaults.RequestRundown)] public bool? RequestRundown { get; set; } [Display( - Name = nameof(BufferSizeMegabytes), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectTraceOptions_BufferSizeMegabytes))] [Range(ActionOptionsConstants.BufferSizeMegabytes_MinValue, ActionOptionsConstants.BufferSizeMegabytes_MaxValue)] @@ -53,7 +49,6 @@ internal sealed partial record class CollectTraceOptions : BaseRecordOptions, IE public int? BufferSizeMegabytes { get; set; } [Display( - Name = nameof(Duration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Duration))] [Range(typeof(TimeSpan), ActionOptionsConstants.Duration_MinValue, ActionOptionsConstants.Duration_MaxValue)] @@ -62,7 +57,6 @@ internal sealed partial record class CollectTraceOptions : BaseRecordOptions, IE public TimeSpan? Duration { get; set; } [Display( - Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Egress))] [Required( @@ -74,13 +68,11 @@ internal sealed partial record class CollectTraceOptions : BaseRecordOptions, IE public string Egress { get; set; } = string.Empty; [Display( - Name = nameof(StoppingEvent), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectTraceOptions_StoppingEvent))] public TraceEventFilter? StoppingEvent { get; set; } [Display( - Name = nameof(ArtifactName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_ArtifactName))] public string? ArtifactName { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ExecuteOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ExecuteOptions.cs index 1d67e15d7fd..f62f665430f 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ExecuteOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ExecuteOptions.cs @@ -20,14 +20,12 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed record class ExecuteOptions : BaseRecordOptions { [Display( - Name = nameof(Path), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ExecuteOptions_Path))] [Required] public string Path { get; set; } = string.Empty; [Display( - Name = nameof(Arguments), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ExecuteOptions_Arguments))] [ActionOptionsDependencyProperty] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/GetEnvironmentVariableOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/GetEnvironmentVariableOptions.cs index 887111c62b5..67da644add3 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/GetEnvironmentVariableOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/GetEnvironmentVariableOptions.cs @@ -17,7 +17,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed record class GetEnvironmentVariableOptions : BaseRecordOptions { [Display( - Name = nameof(Name), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_GetEnvironmentVariableOptions_Name))] [Required] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/LoadProfilerOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/LoadProfilerOptions.cs index 1ec2f24ee63..d3f2fadba13 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/LoadProfilerOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/LoadProfilerOptions.cs @@ -18,14 +18,12 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed record class LoadProfilerOptions : BaseRecordOptions { [Display( - Name = nameof(Path), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoadProfilerOptions_Path))] [Required] public string Path { get; set; } = string.Empty; [Display( - Name = nameof(Clsid), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_LoadProfilerOptions_Clsid))] [Required] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/SetEnvironmentVariableOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/SetEnvironmentVariableOptions.cs index 88f9ff26aac..d9323b29bcc 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/SetEnvironmentVariableOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/SetEnvironmentVariableOptions.cs @@ -19,14 +19,12 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed record class SetEnvironmentVariableOptions : BaseRecordOptions { [Display( - Name = nameof(Name), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_SetEnvironmentVariableOptions_Name))] [Required] public string Name { get; set; } = string.Empty; [Display( - Name = nameof(Value), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_SetEnvironmentVariableOptions_Value))] public string? Value { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/TraceEventFilter.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/TraceEventFilter.cs index 6371fb113ab..ab7e874fc9f 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/TraceEventFilter.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/TraceEventFilter.cs @@ -20,21 +20,18 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions internal sealed record class TraceEventFilter : BaseRecordOptions { [Display( - Name = nameof(ProviderName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_TraceEventFilter_ProviderName))] [Required] public string ProviderName { get; set; } = string.Empty; [Display( - Name = nameof(EventName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_TraceEventFilter_EventName))] [Required] public string EventName { get; set; } = string.Empty; [Display( - Name = nameof(PayloadFilter), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_TraceEventFilter_PayloadFilter))] public IDictionary? PayloadFilter { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionDefaultsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionDefaultsOptions.cs index 9e4410b9737..f9978705d0b 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionDefaultsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionDefaultsOptions.cs @@ -11,7 +11,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed class CollectionRuleActionDefaultsOptions { [Display( - Name = nameof(Egress), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleActionDefaultsOptions_Egress))] public string? Egress { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.cs index 39199158033..66e29494f0a 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.cs @@ -17,26 +17,22 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed partial class CollectionRuleActionOptions { [Display( - Name = nameof(Name), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleActionOptions_Name))] public string? Name { get; set; } [Display( - Name = nameof(Type), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleActionOptions_Type))] [Required] public string Type { get; set; } = string.Empty; [Display( - Name = nameof(Settings), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleActionOptions_Settings))] public object? Settings { get; internal set; } [Display( - Name = nameof(WaitForCompletion), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleActionOptions_WaitForCompletion))] [DefaultValue(CollectionRuleActionOptionsDefaults.WaitForCompletion)] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleDefaultsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleDefaultsOptions.cs index c3ac776599f..064d4ab8f9b 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleDefaultsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleDefaultsOptions.cs @@ -11,19 +11,16 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed class CollectionRuleDefaultsOptions { [Display( - Name = nameof(Triggers), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleDefaultsOptions_Triggers))] public CollectionRuleTriggerDefaultsOptions? Triggers { get; set; } [Display( - Name = nameof(Actions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleDefaultsOptions_Actions))] public CollectionRuleActionDefaultsOptions? Actions { get; set; } [Display( - Name = nameof(Limits), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleDefaultsOptions_Limits))] public CollectionRuleLimitsDefaultsOptions? Limits { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs index 50cc9392817..64096acc700 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs @@ -11,14 +11,12 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed class CollectionRuleLimitsDefaultsOptions { [Display( - Name = nameof(ActionCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsDefaultsOptions_ActionCount))] [Range(1, int.MaxValue)] public int? ActionCount { get; set; } [Display( - Name = nameof(ActionCountSlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsDefaultsOptions_ActionCountSlidingWindowDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MinValue, CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MaxValue)] @@ -26,7 +24,6 @@ internal sealed class CollectionRuleLimitsDefaultsOptions public TimeSpan? ActionCountSlidingWindowDuration { get; set; } [Display( - Name = nameof(RuleDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsDefaultsOptions_RuleDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.RuleDuration_MinValue, CollectionRuleOptionsConstants.RuleDuration_MaxValue)] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs index 2d3318aff40..74d657ce290 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs @@ -15,7 +15,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed class CollectionRuleLimitsOptions { [Display( - Name = nameof(ActionCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsOptions_ActionCount))] [DefaultValue(CollectionRuleLimitsOptionsDefaults.ActionCount)] @@ -23,7 +22,6 @@ internal sealed class CollectionRuleLimitsOptions public int? ActionCount { get; set; } [Display( - Name = nameof(ActionCountSlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsOptions_ActionCountSlidingWindowDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MinValue, CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MaxValue)] @@ -31,7 +29,6 @@ internal sealed class CollectionRuleLimitsOptions public TimeSpan? ActionCountSlidingWindowDuration { get; set; } [Display( - Name = nameof(RuleDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsOptions_RuleDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.RuleDuration_MinValue, CollectionRuleOptionsConstants.RuleDuration_MaxValue)] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs index b61dfb52836..06ac0cb12ff 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs @@ -15,14 +15,12 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed partial class CollectionRuleOptions { [Display( - Name = nameof(Filters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Filters))] public List Filters { get; set; } = []; #nullable disable [Display( - Name = nameof(Trigger), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Trigger))] [Required] @@ -30,13 +28,11 @@ internal sealed partial class CollectionRuleOptions #nullable enable [Display( - Name = nameof(Actions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Actions))] public List Actions { get; set; } = []; [Display( - Name = nameof(Limits), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Limits))] public CollectionRuleLimitsOptions? Limits { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs index e466695de75..59b4b5e4ebc 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs @@ -12,21 +12,18 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed class CollectionRuleTriggerDefaultsOptions { [Display( - Name = nameof(RequestCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleTriggerDefaultsOptions_RequestCount))] [Range(1, int.MaxValue)] public int? RequestCount { get; set; } [Display( - Name = nameof(ResponseCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleTriggerDefaultsOptions_ResponseCount))] [Range(1, int.MaxValue)] public int? ResponseCount { get; set; } [Display( - Name = nameof(SlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleTriggerDefaultsOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerOptions.cs index 3117a0bf5bf..6abf18ab2d0 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerOptions.cs @@ -16,14 +16,12 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed partial class CollectionRuleTriggerOptions { [Display( - Name = nameof(Type), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleTriggerOptions_Type))] [Required] public string Type { get; set; } = string.Empty; [Display( - Name = nameof(Settings), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleTriggerOptions_Settings))] public object? Settings { get; internal set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/TemplateOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/TemplateOptions.cs index a634188271d..40b91ff4282 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/TemplateOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/TemplateOptions.cs @@ -15,25 +15,21 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options internal sealed partial class TemplateOptions { [Display( - Name = nameof(CollectionRuleFilters), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Filters))] public IDictionary? CollectionRuleFilters { get; set; } = new Dictionary(); [Display( - Name = nameof(CollectionRuleTriggers), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Trigger))] public IDictionary? CollectionRuleTriggers { get; set; } = new Dictionary(); [Display( - Name = nameof(CollectionRuleActions), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Actions))] public IDictionary? CollectionRuleActions { get; set; } = new Dictionary(); [Display( - Name = nameof(CollectionRuleLimits), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Limits))] public IDictionary? CollectionRuleLimits { get; set; } = new Dictionary(); diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs index bd6f59bb3d6..973795d5bf7 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs @@ -21,7 +21,6 @@ internal sealed partial class AspNetRequestCountOptions : IValidateOptions { [Display( - Name = nameof(RequestCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestCountOptions_RequestCount))] @@ -32,7 +31,6 @@ internal sealed partial class AspNetRequestCountOptions : public int RequestCount { get; set; } [Display( - Name = nameof(SlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestCountOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] @@ -42,7 +40,6 @@ internal sealed partial class AspNetRequestCountOptions : // CONSIDER: Currently described that paths have to exactly match one item in the list. // Consider allowing for wildcard/globbing to simplify list of matchable paths. [Display( - Name = nameof(IncludePaths), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestCountOptions_IncludePaths))] public string[]? IncludePaths { get; set; } @@ -50,7 +47,6 @@ internal sealed partial class AspNetRequestCountOptions : // CONSIDER: Currently described that paths have to exactly match one item in the list. // Consider allowing for wildcard/globbing to simplify list of matchable paths. [Display( - Name = nameof(ExcludePaths), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestCountOptions_ExcludePaths))] public string[]? ExcludePaths { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs index e796c1b639a..3009fd19fd5 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs @@ -25,7 +25,6 @@ internal sealed partial class AspNetRequestDurationOptions : public const string RequestDuration_MinValue = "00:00:00"; [Display( - Name = nameof(RequestCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_RequestCount))] @@ -36,7 +35,6 @@ internal sealed partial class AspNetRequestDurationOptions : public int RequestCount { get; set; } [Display( - Name = nameof(RequestDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_RequestDuration))] [DefaultValue(AspNetRequestDurationOptionsDefaults.RequestDuration)] @@ -45,7 +43,6 @@ internal sealed partial class AspNetRequestDurationOptions : public TimeSpan? RequestDuration { get; set; } [Display( - Name = nameof(SlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] @@ -55,7 +52,6 @@ internal sealed partial class AspNetRequestDurationOptions : // CONSIDER: Currently described that paths have to exactly match one item in the list. // Consider allowing for wildcard/globbing to simplify list of matchable paths. [Display( - Name = nameof(IncludePaths), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_IncludePaths))] public string[]? IncludePaths { get; set; } @@ -63,7 +59,6 @@ internal sealed partial class AspNetRequestDurationOptions : // CONSIDER: Currently described that paths have to exactly match one item in the list. // Consider allowing for wildcard/globbing to simplify list of matchable paths. [Display( - Name = nameof(ExcludePaths), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_ExcludePaths))] public string[]? ExcludePaths { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs index 0feb7ca228b..abeb51e0e87 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs @@ -25,7 +25,6 @@ internal sealed partial class AspNetResponseStatusOptions : #nullable disable [Display( - Name = nameof(StatusCodes), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_StatusCodes))] [Required] @@ -38,7 +37,6 @@ internal sealed partial class AspNetResponseStatusOptions : #nullable enable [Display( - Name = nameof(ResponseCount), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_ResponseCount))] @@ -49,7 +47,6 @@ internal sealed partial class AspNetResponseStatusOptions : public int ResponseCount { get; set; } [Display( - Name = nameof(SlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] @@ -59,7 +56,6 @@ internal sealed partial class AspNetResponseStatusOptions : // CONSIDER: Currently described that paths have to exactly match one item in the list. // Consider allowing for wildcard/globbing to simplify list of matchable paths. [Display( - Name = nameof(IncludePaths), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_IncludePaths))] public string[]? IncludePaths { get; set; } @@ -67,7 +63,6 @@ internal sealed partial class AspNetResponseStatusOptions : // CONSIDER: Currently described that paths have to exactly match one item in the list. // Consider allowing for wildcard/globbing to simplify list of matchable paths. [Display( - Name = nameof(ExcludePaths), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_ExcludePaths))] public string[]? ExcludePaths { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs index c31304a1f82..6b68b783c7e 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs @@ -17,33 +17,28 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers internal sealed partial class EventCounterOptions : IValidateOptions, ISlidingWindowDurationProperties { [Display( - Name = nameof(ProviderName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_ProviderName))] [Required] public string ProviderName { get; set; } = string.Empty; [Display( - Name = nameof(CounterName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_CounterName))] [Required] public string CounterName { get; set; } = string.Empty; [Display( - Name = nameof(GreaterThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_GreaterThan))] public double? GreaterThan { get; set; } [Display( - Name = nameof(LessThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_LessThan))] public double? LessThan { get; set; } [Display( - Name = nameof(SlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventCounterOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs index fe048c53d0e..d67f7c8edac 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs @@ -18,7 +18,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.E internal sealed partial class CPUUsageOptions : IValidateOptions, IEventCounterShortcuts, ISlidingWindowDurationProperties { [Display( - Name = nameof(GreaterThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CPUUsageOptions_GreaterThan))] [DefaultValue(CPUUsageOptionsDefaults.GreaterThan)] @@ -26,14 +25,12 @@ internal sealed partial class CPUUsageOptions : IValidateOptions, IEventCounterShortcuts, ISlidingWindowDurationProperties { [Display( - Name = nameof(GreaterThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_GCHeapSizeOptions_GreaterThan))] [DefaultValue(GCHeapSizeOptionsDefaults.GreaterThan)] @@ -26,14 +25,12 @@ internal sealed partial class GCHeapSizeOptions : IValidateOptions, IEventCounterShortcuts, ISlidingWindowDurationProperties { [Display( - Name = nameof(GreaterThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_ThreadpoolQueueLengthOptions_GreaterThan))] [DefaultValue(ThreadpoolQueueLengthOptionsDefaults.GreaterThan)] @@ -26,14 +25,13 @@ internal sealed partial class ThreadpoolQueueLengthOptions : IValidateOptions, ISlidingWindowDurationProperties { [Display( - Name = nameof(MeterName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventMeterOptions_MeterName))] [Required] public string MeterName { get; set; } = string.Empty; [Display( - Name = nameof(InstrumentName), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventMeterOptions_InstrumentName))] [Required] public string InstrumentName { get; set; } = string.Empty; [Display( - Name = nameof(GreaterThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventMeterOptions_GreaterThan))] public double? GreaterThan { get; set; } [Display( - Name = nameof(LessThan), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventMeterOptions_LessThan))] public double? LessThan { get; set; } [Display( - Name = nameof(SlidingWindowDuration), ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_EventMeterOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] @@ -51,7 +46,6 @@ internal sealed partial class EventMeterOptions : IValidateOptions Date: Fri, 25 Apr 2025 17:40:45 +0000 Subject: [PATCH 145/174] Fix Microsoft.Extensions.Logging.Abstractions central version --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index fb70839d70e..b7980999bc2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -109,7 +109,7 @@ $(MicrosoftAspNetCoreApp100Version) $(MicrosoftNETCoreApp100Version) $(MicrosoftNETCoreApp100Version) - $(MicrosoftExtensionsLoggingAbstractions100Version) + $(MicrosoftNETCoreApp100Version) $(MicrosoftNETCoreApp100Version) $(MicrosoftNETCoreApp100Version) $(MicrosoftAspNetCoreApp100Version) From e70e9e7441f9107cafa78a851a30106af55169c6 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 25 Apr 2025 17:50:41 +0000 Subject: [PATCH 146/174] Fix MonitorApiKey mapping --- src/Tools/dotnet-monitor/CommonOptionsMapper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs index 6eed2682591..6b6958e39d2 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs @@ -794,8 +794,8 @@ private static void MapAuthenticationOptions(AuthenticationOptions? obj, string if (null != obj) { string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapMonitorApiKeyOptions(obj.MonitorApiKey, prefix, separator, map); - MapAzureAdOptions(obj.AzureAd, prefix, separator, map); + MapMonitorApiKeyOptions(obj.MonitorApiKey, FormattableString.Invariant($"{prefix}{nameof(obj.MonitorApiKey)}"), separator, map); + MapAzureAdOptions(obj.AzureAd, FormattableString.Invariant($"{prefix}{nameof(obj.AzureAd)}"), separator, map); } } From 10f43082c37c3f3b7ce8e14c0ee81b259f90353f Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 25 Apr 2025 18:28:31 +0000 Subject: [PATCH 147/174] Fix AzureAdOptions tests - Set content root to AppContext.BaseDirectory to prevent failure when running in helix - Add AzureAdOptions type info --- .../Program.cs | 9 +- .../ValidatableInfoResolver.cs | 91 +++++++++++++++---- .../TemplatesConfigureNamedOptions.cs | 1 - 3 files changed, 82 insertions(+), 19 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs index a34cca569e7..be3c8080f60 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs @@ -1,12 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; -var builder = WebApplication.CreateBuilder(args); +var builder = WebApplication.CreateBuilder(new WebApplicationOptions +{ + ContentRootPath = AppContext.BaseDirectory +}); + Microsoft.AspNetCore.Http.Validation.Generated.GeneratedServiceCollectionExtensions.AddValidation(builder.Services); builder.Build(); @@ -22,4 +27,6 @@ sealed class TestValidatableType public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } public required ExecuteOptions ExecuteOptions { get; init; } + + public required AzureAdOptions AzureAdOptions { get; init; } } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs index 70fe3cdb292..21ecadd532c 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs @@ -159,6 +159,11 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateExecuteOptions(); return true; } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions)) + { + validatableInfo = CreateAzureAdOptions(); + return true; + } if (type == typeof(global::TestValidatableType)) { validatableInfo = CreateTestValidatableType(); @@ -688,12 +693,6 @@ private ValidatableTypeInfo CreateBaseRecordOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), ] ); } @@ -702,12 +701,6 @@ private ValidatableTypeInfo CreateExecuteOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - // propertyType: typeof(global::System.Type), - // name: "EqualityContract", - // displayName: "EqualityContract" - // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), propertyType: typeof(string), @@ -717,6 +710,38 @@ private ValidatableTypeInfo CreateExecuteOptions() ] ); } + private ValidatableTypeInfo CreateAzureAdOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "TenantId", + displayName: "TenantId" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "ClientId", + displayName: "ClientId" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(global::System.Uri), + name: "AppIdUri", + displayName: "AppIdUri" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "RequiredRole", + displayName: "RequiredRole" + ), + ] + ); + } private ValidatableTypeInfo CreateTestValidatableType() { return new GeneratedValidatableTypeInfo( @@ -740,6 +765,12 @@ private ValidatableTypeInfo CreateTestValidatableType() name: "ExecuteOptions", displayName: "ExecuteOptions" ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::TestValidatableType), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + name: "AzureAdOptions", + displayName: "AzureAdOptions" + ), ] ); } @@ -749,8 +780,8 @@ private ValidatableTypeInfo CreateTestValidatableType() [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] internal static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "nMLdYxVpxyjXwof6UabUh7sBAABQcm9ncmFtLmNz")] - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "/S4C/fYaYK+RGue0pzw4eqSWAABWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => @@ -777,13 +808,39 @@ private sealed record CacheKey(global::System.Type ContainingType, string Proper var key = new CacheKey(containingType, propertyName); return _cache.GetOrAdd(key, static k => { + var results = new global::System.Collections.Generic.List(); + + // Get attributes from the property var property = k.ContainingType.GetProperty(k.PropertyName); - if (property == null) + if (property != null) { - return []; + var propertyAttributes = global::System.Reflection.CustomAttributeExtensions + .GetCustomAttributes(property, inherit: true); + + results.AddRange(propertyAttributes); + } + + // Check constructors for parameters that match the property name + // to handle record scenarios + foreach (var constructor in k.ContainingType.GetConstructors()) + { + // Look for parameter with matching name (case insensitive) + var parameter = global::System.Linq.Enumerable.FirstOrDefault( + constructor.GetParameters(), + p => string.Equals(p.Name, k.PropertyName, global::System.StringComparison.OrdinalIgnoreCase)); + + if (parameter != null) + { + var paramAttributes = global::System.Reflection.CustomAttributeExtensions + .GetCustomAttributes(parameter, inherit: true); + + results.AddRange(paramAttributes); + + break; + } } - return [.. global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(property, inherit: true)]; + return results.ToArray(); }); } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/TemplatesConfigureNamedOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/TemplatesConfigureNamedOptions.cs index ced87172119..ff35634307f 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/TemplatesConfigureNamedOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/TemplatesConfigureNamedOptions.cs @@ -30,7 +30,6 @@ public TemplatesPostConfigureOptions( public void PostConfigure(string? name, TemplateOptions options) { - System.Console.WriteLine("TemplatesConfigureNamedOptions PostConfigure"); IConfigurationSection collectionRuleActionsSection = _configuration.GetSection(collectionRuleActionsPath); if (options.CollectionRuleActions != null) From 3b90099bbd337084d856c85bed9885fe380cf63f Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 25 Apr 2025 18:36:56 +0000 Subject: [PATCH 148/174] Fix ActionCountLimitSlidingDurationTest Range validation was causing failures because the SlidingWindowDuration was less than 1s --- .../CollectionRulePipelineTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs index c6335074318..1f7882a4d64 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs @@ -477,8 +477,8 @@ public Task CollectionRulePipeline_ActionCountLimitSlidingDurationTest(TargetFra { const int IterationCount = 5; const int ExpectedActionExecutionCount = 3; - TimeSpan SlidingWindowDuration = TimeSpan.FromMilliseconds(100); - TimeSpan ClockIncrementDuration = TimeSpan.FromMilliseconds(10); + TimeSpan SlidingWindowDuration = TimeSpan.FromMilliseconds(1000); + TimeSpan ClockIncrementDuration = TimeSpan.FromMilliseconds(100); MockTimeProvider timeProvider = new(); ManualTriggerService triggerService = new(); From 02e83492c2ed2a6ec72f1a513c572ae6b9a51567 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 25 Apr 2025 19:00:45 +0000 Subject: [PATCH 149/174] Fix GlobalCounterOptions ValidationResult --- .../GlobalCounterOptions.cs | 3 ++- .../Options/Actions/CollectTraceOptions.Validate.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs index c360b5184d1..ff3c222d629 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs @@ -64,7 +64,8 @@ public IEnumerable Validate(ValidationContext validationContex { // We prefix the validation error with the provider. results.AddRange(providerResults.Select(r => new ValidationResult( - string.Format(CultureInfo.CurrentCulture, OptionsDisplayStrings.ErrorMessage_NestedProviderValidationError, provider, r.ErrorMessage)))); + string.Format(CultureInfo.CurrentCulture, OptionsDisplayStrings.ErrorMessage_NestedProviderValidationError, provider, r.ErrorMessage), + [nameof(Providers)]))); } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs index 5db027f7bab..e5ee1cf2762 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs @@ -81,7 +81,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali } catch (OptionsValidationException e) { - results.AddRange(e.Failures.Select((string failure) => new ValidationResult(e.Message))); + results.AddRange(e.Failures.Select((string failure) => new ValidationResult(e.Message, [e.OptionsType.Name]))); } // Validate that each provider is valid. From b96f6203b7171ad68200c8bd69c92eca48910f08 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 25 Apr 2025 22:04:37 +0000 Subject: [PATCH 150/174] Fix RejectsBadSubject, test failure at startup on empty Subject --- .../AuthenticationTests.cs | 22 ++++++- .../dotnet-monitor/ValidatableInfoResolver.cs | 60 +++++++++++++------ 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/AuthenticationTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/AuthenticationTests.cs index e13ae742e76..555348cba9d 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/AuthenticationTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/AuthenticationTests.cs @@ -472,9 +472,6 @@ public async Task AllowsConfiguredIssuer() [Theory] // Guids that don't match should get rejected [InlineData("980d2b17-71e1-4313-a084-c077e962680c", "10253b7a-454d-41bb-a3f5-5f2e6b26ed93", HttpStatusCode.Forbidden)] - // Empty string isn't valid even when signed and configured correctly - [InlineData("", "", HttpStatusCode.Unauthorized)] - [InlineData("10253b7a-454d-41bb-a3f5-5f2e6b26ed93", "", HttpStatusCode.Unauthorized)] [InlineData("", "10253b7a-454d-41bb-a3f5-5f2e6b26ed93", HttpStatusCode.Forbidden)] public async Task RejectsBadSubject(string jwtSubject, string configSubject, HttpStatusCode expectedError) { @@ -501,6 +498,25 @@ public async Task RejectsBadSubject(string jwtSubject, string configSubject, Htt Assert.Equal(expectedError, statusCodeException.StatusCode); } + /// + /// This tests that an empty configured subject fails on startup. + /// + [Fact] + public async Task DoesNotStart_With_EmptySubject() + { + var configSubject = ""; + await using MonitorCollectRunner toolRunner = new(_outputHelper); + toolRunner.DisableMetricsViaCommandLine = true; + + _outputHelper.WriteLine("Generating API key."); + + JwtPayload newPayload = GetJwtPayload(AuthConstants.ApiKeyJwtAudience, configSubject, AuthConstants.ApiKeyJwtInternalIssuer, AuthConstants.ApiKeyJwtDefaultExpiration); + + toolRunner.ConfigurationFromEnvironment.UseApiKey(SecurityAlgorithms.EcdsaSha384, configSubject, newPayload, out string token); + + await Assert.ThrowsAsync(toolRunner.StartAsync); + } + [Fact] public async Task RejectsMissingExpiration() { diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index decce8f8067..776331e9d0b 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -1,4 +1,4 @@ -#nullable enable annotations +#nullable enable annotations //------------------------------------------------------------------------------ // // This code was generated by a tool. @@ -129,7 +129,7 @@ private ValidatableTypeInfo CreateMetricProvider() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), propertyType: typeof(string), name: "ProviderName", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "ProviderName" ), ] ); @@ -143,13 +143,13 @@ private ValidatableTypeInfo CreateMetricsOptions() containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), propertyType: typeof(int?), name: "MetricCount", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "MetricCount" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), propertyType: typeof(global::System.Collections.Generic.List), name: "Providers", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Providers" ), ] ); @@ -163,13 +163,13 @@ private ValidatableTypeInfo CreateMonitorApiKeyOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), propertyType: typeof(string), name: "Subject", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "Subject" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), propertyType: typeof(string), name: "PublicKey", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "PublicKey" ), ] ); @@ -183,25 +183,25 @@ private ValidatableTypeInfo CreateAzureAdOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), propertyType: typeof(string), name: "TenantId", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "TenantId" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), propertyType: typeof(string), name: "ClientId", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "ClientId" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), propertyType: typeof(global::System.Uri), name: "AppIdUri", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "AppIdUri" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), propertyType: typeof(string), name: "RequiredRole", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "RequiredRole" ), ] ); @@ -215,13 +215,13 @@ private ValidatableTypeInfo CreateAuthenticationOptions() containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), name: "MonitorApiKey", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "MonitorApiKey" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), name: "AzureAd", - displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" + displayName: "AzureAd" ), ] ); @@ -260,8 +260,8 @@ static class MyExtensions [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] file static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "M2kOaR09/X9mJ22GvhUC4+4FAABTdGFydHVwLmNz")] - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "tgKaeQ8w+KgICFY1OfbdmEk4AABWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => @@ -288,13 +288,39 @@ private sealed record CacheKey([property: global::System.Diagnostics.CodeAnalysi var key = new CacheKey(containingType, propertyName); return _cache.GetOrAdd(key, static k => { + var results = new global::System.Collections.Generic.List(); + + // Get attributes from the property var property = k.ContainingType.GetProperty(k.PropertyName); - if (property == null) + if (property != null) { - return []; + var propertyAttributes = global::System.Reflection.CustomAttributeExtensions + .GetCustomAttributes(property, inherit: true); + + results.AddRange(propertyAttributes); + } + + // Check constructors for parameters that match the property name + // to handle record scenarios + foreach (var constructor in k.ContainingType.GetConstructors()) + { + // Look for parameter with matching name (case insensitive) + var parameter = global::System.Linq.Enumerable.FirstOrDefault( + constructor.GetParameters(), + p => string.Equals(p.Name, k.PropertyName, global::System.StringComparison.OrdinalIgnoreCase)); + + if (parameter != null) + { + var paramAttributes = global::System.Reflection.CustomAttributeExtensions + .GetCustomAttributes(parameter, inherit: true); + + results.AddRange(paramAttributes); + + break; + } } - return [.. global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(property, inherit: true)]; + return results.ToArray(); }); } } From d72d4b56b4a5e83c20a654d94ba25fc28a843da1 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 28 Apr 2025 17:37:08 +0000 Subject: [PATCH 151/174] Share validation type info --- .../TestHostHelper.cs | 1 + .../TestValidatableType.cs | 55 +- .../ValidatableInfoResolver.cs | 1435 +---------------- ...ics.Monitoring.Tool.UnitTestsSample.csproj | 8 - .../Program.cs | 22 +- .../ValidatableInfoResolver.cs | 847 ---------- .../dotnet-monitor}/CustomValidationInfo.cs | 0 .../Extensibility/ExtensionManifest.cs | 1 - .../HostBuilder/HostBuilderHelper.cs | 3 +- .../dotnet-monitor/ValidatableInfoResolver.cs | 1361 +++++++++++++++- src/Tools/dotnet-monitor/ValidatableTypes.cs | 72 + 11 files changed, 1418 insertions(+), 2387 deletions(-) delete mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs rename src/{Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon => Tools/dotnet-monitor}/CustomValidationInfo.cs (100%) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs index 98d65a2919e..759098fe8f4 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs @@ -127,6 +127,7 @@ public static IHost CreateHost( services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + ValidatableTypes.AddValidation(services); TestValidatableTypes.AddValidation(services); servicesCallback?.Invoke(services); }) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs index dce48d1ce2c..b21f9deddfb 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs @@ -4,14 +4,6 @@ using Microsoft.AspNetCore.Http.Validation; using Microsoft.AspNetCore.Http.Validation.Generated; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Diagnostics.Tools.Monitor; -using Microsoft.Diagnostics.Monitoring.WebApi.Models; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts; -using Microsoft.Diagnostics.Monitoring.WebApi; -using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; namespace Microsoft.Diagnostics.Monitoring.TestCommon { @@ -22,56 +14,11 @@ namespace Microsoft.Diagnostics.Monitoring.TestCommon [ValidatableType] internal sealed class TestValidatableTypes { - public required CollectionRuleOptions CollectionRuleOptions { get; init; } - - public required ExecuteOptions ExecuteOptions { get; init; } - - public required SetEnvironmentVariableOptions SetEnvironmentVariableOptions { get; init; } - - public required GetEnvironmentVariableOptions GetEnvironmentVariableOptions { get; init; } - - public required CollectTraceOptions CollectTraceOptions { get; init; } - - public required GlobalCounterOptions GlobalCounterOptions { get; init; } - - public required CollectGCDumpOptions CollectGCDumpOptions { get; init; } - - public required CollectLiveMetricsOptions CollectLiveMetricsOptions { get; init; } - - public required CollectStacksOptions CollectStacksOptions { get; init; } - - public required CollectLogsOptions CollectLogsOptions { get; init; } - - public required RootOptions RootOptions { get; init; } - - public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } - - public required CollectDumpOptions CollectDumpOptions { get; init; } - - public required LoadProfilerOptions LoadProfilerOptions { get; init; } - - public required CollectExceptionsOptions CollectExceptionsOptions { get; init; } - - // Triggers... - public required AspNetRequestCountOptions AspNetRequestCountOptions { get; init; } - public required AspNetRequestDurationOptions AspNetRequestDurationOptions { get; init; } - public required AspNetResponseStatusOptions AspNetResponseStatusOptions { get; init; } - public required EventCounterOptions EventCounterOptions { get; init; } - public required CPUUsageOptions CPUUsageOptions { get; init; } - public required GCHeapSizeOptions GCHeapSizeOptions { get; init; } - public required ThreadpoolQueueLengthOptions ThreadpoolQueueLengthOptions { get; init; } - public required EventMeterOptions EventMeterOptions { get; init; } - - // Nested member - public required EventPipeProvider EventPipeProvider { get; init; } - - // TODO: only one resolver per project? Generate this for tests, for now. Maybe want to separate this one out - // by test later. public required PassThroughOptions PassThroughOptions { get; init; } public static void AddValidation(IServiceCollection services) { - GeneratedServiceCollectionExtensions.AddValidation(services); + TestGeneratedServiceCollectionExtensions.AddValidation(services); } } } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs index 4e11e02a0b7..e85fa33860c 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs @@ -61,26 +61,6 @@ public GeneratedValidatableTypeInfo( public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) { validatableInfo = null; - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions)) - { - validatableInfo = CreateCollectionRuleTriggerOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions)) - { - validatableInfo = CreateCollectionRuleActionOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions)) - { - validatableInfo = CreateCollectionRuleLimitsOptions(); - return true; - } - // if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions)) - // { - // validatableInfo = CreateCollectionRuleOptions(); - // return true; - // } if (type == typeof(global::System.Reflection.MethodBase)) { validatableInfo = CreateMethodBase(); @@ -166,206 +146,6 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateBaseRecordOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions)) - { - validatableInfo = CreateExecuteOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions)) - { - validatableInfo = CreateSetEnvironmentVariableOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions)) - { - validatableInfo = CreateGetEnvironmentVariableOptions(); - return true; - } - if (type == typeof(global::System.Collections.Generic.IDictionary)) - { - validatableInfo = CreateIDictionary_2(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter)) - { - validatableInfo = CreateTraceEventFilter(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions)) - { - validatableInfo = CreateCollectTraceOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions)) - { - validatableInfo = CreateGlobalCounterOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions)) - { - validatableInfo = CreateCollectGCDumpOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions)) - { - validatableInfo = CreateCollectLiveMetricsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions)) - { - validatableInfo = CreateCollectStacksOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions)) - { - validatableInfo = CreateCollectLogsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions)) - { - validatableInfo = CreateMonitorApiKeyOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions)) - { - validatableInfo = CreateAzureAdOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions)) - { - validatableInfo = CreateAuthenticationOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration)) - { - validatableInfo = CreateExceptionsConfiguration(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions)) - { - validatableInfo = CreateExceptionsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions)) - { - validatableInfo = CreateInProcessFeaturesOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions)) - { - validatableInfo = CreateCorsConfigurationOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions)) - { - validatableInfo = CreateEgressOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider)) - { - validatableInfo = CreateMetricProvider(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions)) - { - validatableInfo = CreateMetricsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions)) - { - validatableInfo = CreateProcessFilterOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions)) - { - validatableInfo = CreateCollectionRuleTriggerDefaultsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions)) - { - validatableInfo = CreateCollectionRuleLimitsDefaultsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions)) - { - validatableInfo = CreateCollectionRuleDefaultsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions)) - { - validatableInfo = CreateTemplateOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions)) - { - validatableInfo = CreateRootOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions)) - { - validatableInfo = CreateFileSystemEgressProviderOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions)) - { - validatableInfo = CreateCollectDumpOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions)) - { - validatableInfo = CreateLoadProfilerOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions)) - { - validatableInfo = CreateCollectExceptionsOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions)) - { - validatableInfo = CreateAspNetRequestCountOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions)) - { - validatableInfo = CreateAspNetRequestDurationOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions)) - { - validatableInfo = CreateAspNetResponseStatusOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions)) - { - validatableInfo = CreateEventCounterOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions)) - { - validatableInfo = CreateCPUUsageOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions)) - { - validatableInfo = CreateGCHeapSizeOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions)) - { - validatableInfo = CreateThreadpoolQueueLengthOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions)) - { - validatableInfo = CreateEventMeterOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider)) - { - validatableInfo = CreateEventPipeProvider(); - return true; - } if (type == typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions)) { validatableInfo = CreatePassThroughOptions(); @@ -387,86 +167,6 @@ public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterIn return false; } - private ValidatableTypeInfo CreateCollectionRuleTriggerOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), - propertyType: typeof(string), - name: "Type", - displayName: "Type" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectionRuleActionOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), - propertyType: typeof(string), - name: "Type", - displayName: "Type" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectionRuleLimitsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - propertyType: typeof(int?), - name: "ActionCount", - displayName: "ActionCount" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "ActionCountSlidingWindowDuration", - displayName: "ActionCountSlidingWindowDuration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "RuleDuration", - displayName: "RuleDuration" - ), - ] - ); - } - // private ValidatableTypeInfo CreateCollectionRuleOptions() - // { - // return new GeneratedValidatableTypeInfo( - // type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - // members: [ - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - // propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), - // name: "Trigger", - // displayName: "Trigger" - // ), - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - // propertyType: typeof(global::System.Collections.Generic.List), - // name: "Actions", - // displayName: "Actions" - // ), - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - // propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - // name: "Limits", - // displayName: "Limits" - // ), - // ] - // ); - // } private ValidatableTypeInfo CreateMethodBase() { return new GeneratedValidatableTypeInfo( @@ -950,1141 +650,42 @@ private ValidatableTypeInfo CreateBaseRecordOptions() ] ); } - private ValidatableTypeInfo CreateExecuteOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - propertyType: typeof(string), - name: "Path", - displayName: "Path" - ), - ] - ); - } - private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), - propertyType: typeof(string), - name: "Name", - displayName: "Name" - ), - ] - ); - } - private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), - propertyType: typeof(string), - name: "Name", - displayName: "Name" - ), - ] - ); - } - private ValidatableTypeInfo CreateIDictionary_2() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Collections.Generic.IDictionary), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Collections.Generic.IDictionary), - propertyType: typeof(global::System.Collections.Generic.ICollection), - name: "Values", - displayName: "Values" - ), - ] - ); - } - private ValidatableTypeInfo CreateTraceEventFilter() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - propertyType: typeof(string), - name: "ProviderName", - displayName: "ProviderName" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - propertyType: typeof(string), - name: "EventName", - displayName: "EventName" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "PayloadFilter", - displayName: "PayloadFilter" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectTraceOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.TraceProfile?), - name: "Profile", - displayName: "Profile" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(int?), - name: "BufferSizeMegabytes", - displayName: "BufferSizeMegabytes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "Duration", - displayName: "Duration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - name: "StoppingEvent", - displayName: "StoppingEvent" - ), - ] - ); - } - private ValidatableTypeInfo CreateGlobalCounterOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - propertyType: typeof(float?), - name: "IntervalSeconds", - displayName: "IntervalSeconds" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - propertyType: typeof(int?), - name: "MaxHistograms", - displayName: "MaxHistograms" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - propertyType: typeof(int?), - name: "MaxTimeSeries", - displayName: "MaxTimeSeries" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "Providers", - displayName: "Providers" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectGCDumpOptions() + private ValidatableTypeInfo CreatePassThroughOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" - ), - ] + type: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), + members: [] ); } - private ValidatableTypeInfo CreateCollectLiveMetricsOptions() + private ValidatableTypeInfo CreateTestValidatableTypes() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + type: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "Duration", - displayName: "Duration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), + name: "PassThroughOptions", + displayName: "PassThroughOptions" ), ] ); } - private ValidatableTypeInfo CreateCollectStacksOptions() + + } + + internal static class TestGeneratedServiceCollectionExtensions + { + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(global::Microsoft.Extensions.DependencyInjection.IServiceCollection services) { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" - ), - ] - ); + return GeneratedServiceCollectionExtensions.AddValidation(services); } - - private ValidatableTypeInfo CreateCollectLogsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - propertyType: typeof(global::Microsoft.Extensions.Logging.LogLevel?), - name: "DefaultLevel", - displayName: "DefaultLevel" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - propertyType: typeof(global::System.Collections.Generic.Dictionary), - name: "FilterSpecs", - displayName: "FilterSpecs" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "Duration", - displayName: "Duration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.LogFormat?), - name: "Format", - displayName: "Format" - ), - ] - ); - } - private ValidatableTypeInfo CreateMonitorApiKeyOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), - propertyType: typeof(string), - name: "Subject", - displayName: "Subject" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), - propertyType: typeof(string), - name: "PublicKey", - displayName: "PublicKey" - ), - ] - ); - } - private ValidatableTypeInfo CreateAzureAdOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - propertyType: typeof(string), - name: "TenantId", - displayName: "TenantId" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - propertyType: typeof(string), - name: "ClientId", - displayName: "ClientId" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - propertyType: typeof(global::System.Uri), - name: "AppIdUri", - displayName: "AppIdUri" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - propertyType: typeof(string), - name: "RequiredRole", - displayName: "RequiredRole" - ), - ] - ); - } - private ValidatableTypeInfo CreateAuthenticationOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), - name: "MonitorApiKey", - displayName: "MonitorApiKey" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - name: "AzureAd", - displayName: "AzureAd" - ), - ] - ); - } - private ValidatableTypeInfo CreateExceptionsConfiguration() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), - propertyType: typeof(global::System.Collections.Generic.List), - name: "Exclude", - displayName: "Exclude" - ), - ] - ); - } - private ValidatableTypeInfo CreateExceptionsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), - propertyType: typeof(int?), - name: "TopLevelLimit", - displayName: "TopLevelLimit" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), - name: "CollectionFilters", - displayName: "CollectionFilters" - ), - ] - ); - } - private ValidatableTypeInfo CreateInProcessFeaturesOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), - name: "Exceptions", - displayName: "Exceptions" - ), - ] - ); - } - private ValidatableTypeInfo CreateCorsConfigurationOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), - propertyType: typeof(string), - name: "AllowedOrigins", - displayName: "AllowedOrigins" - ), - ] - ); - } - private ValidatableTypeInfo CreateEgressOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "FileSystem", - displayName: "FileSystem" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "Properties", - displayName: "Properties" - ), - ] - ); - } - private ValidatableTypeInfo CreateMetricProvider() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), - propertyType: typeof(string), - name: "ProviderName", - displayName: "ProviderName" - ), - ] - ); - } - private ValidatableTypeInfo CreateMetricsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - propertyType: typeof(int?), - name: "MetricCount", - displayName: "MetricCount" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - propertyType: typeof(global::System.Collections.Generic.List), - name: "Providers", - displayName: "Providers" - ), - ] - ); - } - private ValidatableTypeInfo CreateProcessFilterOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), - propertyType: typeof(global::System.Collections.Generic.List), - name: "Filters", - displayName: "Filters" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectionRuleTriggerDefaultsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - propertyType: typeof(int?), - name: "RequestCount", - displayName: "RequestCount" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - propertyType: typeof(int?), - name: "ResponseCount", - displayName: "ResponseCount" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectionRuleLimitsDefaultsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - propertyType: typeof(int?), - name: "ActionCount", - displayName: "ActionCount" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "ActionCountSlidingWindowDuration", - displayName: "ActionCountSlidingWindowDuration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "RuleDuration", - displayName: "RuleDuration" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectionRuleDefaultsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - name: "Triggers", - displayName: "Triggers" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - name: "Limits", - displayName: "Limits" - ), - ] - ); - } - private ValidatableTypeInfo CreateTemplateOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRuleFilters", - displayName: "CollectionRuleFilters" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRuleTriggers", - displayName: "CollectionRuleTriggers" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRuleActions", - displayName: "CollectionRuleActions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRuleLimits", - displayName: "CollectionRuleLimits" - ), - ] - ); - } - private ValidatableTypeInfo CreateRootOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), - name: "Authentication", - displayName: "Authentication" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRules", - displayName: "CollectionRules" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - name: "GlobalCounter", - displayName: "GlobalCounter" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), - name: "InProcessFeatures", - displayName: "InProcessFeatures" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), - name: "CorsConfiguration", - displayName: "CorsConfiguration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), - name: "Egress", - displayName: "Egress" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - name: "Metrics", - displayName: "Metrics" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), - name: "DefaultProcess", - displayName: "DefaultProcess" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), - name: "CollectionRuleDefaults", - displayName: "CollectionRuleDefaults" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - name: "Templates", - displayName: "Templates" - ), - ] - ); - } - private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - propertyType: typeof(string), - name: "DirectoryPath", - displayName: "DirectoryPath" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - propertyType: typeof(int?), - name: "CopyBufferSize", - displayName: "CopyBufferSize" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectDumpOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.DumpType?), - name: "Type", - displayName: "Type" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" - ), - ] - ); - } - private ValidatableTypeInfo CreateLoadProfilerOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), - propertyType: typeof(string), - name: "Path", - displayName: "Path" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), - propertyType: typeof(global::System.Guid), - name: "Clsid", - displayName: "Clsid" - ), - ] - ); - } - private ValidatableTypeInfo CreateCollectExceptionsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), - name: "Filters", - displayName: "Filters" - ), - ] - ); - } - private ValidatableTypeInfo CreateAspNetRequestCountOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), - propertyType: typeof(int), - name: "RequestCount", - displayName: "RequestCount" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), - propertyType: typeof(string[]), - name: "IncludePaths", - displayName: "IncludePaths" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), - propertyType: typeof(string[]), - name: "ExcludePaths", - displayName: "ExcludePaths" - ), - ] - ); - } - private ValidatableTypeInfo CreateAspNetRequestDurationOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), - propertyType: typeof(int), - name: "RequestCount", - displayName: "RequestCount" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "RequestDuration", - displayName: "RequestDuration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), - propertyType: typeof(string[]), - name: "IncludePaths", - displayName: "IncludePaths" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), - propertyType: typeof(string[]), - name: "ExcludePaths", - displayName: "ExcludePaths" - ), - ] - ); - } - private ValidatableTypeInfo CreateAspNetResponseStatusOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), - propertyType: typeof(string[]), - name: "StatusCodes", - displayName: "StatusCodes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), - propertyType: typeof(int), - name: "ResponseCount", - displayName: "ResponseCount" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), - propertyType: typeof(string[]), - name: "IncludePaths", - displayName: "IncludePaths" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), - propertyType: typeof(string[]), - name: "ExcludePaths", - displayName: "ExcludePaths" - ), - ] - ); - } - private ValidatableTypeInfo CreateEventCounterOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), - propertyType: typeof(string), - name: "ProviderName", - displayName: "ProviderName" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), - propertyType: typeof(string), - name: "CounterName", - displayName: "CounterName" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" - ), - ] - ); - } - private ValidatableTypeInfo CreateCPUUsageOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), - propertyType: typeof(double?), - name: "GreaterThan", - displayName: "GreaterThan" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), - propertyType: typeof(double?), - name: "LessThan", - displayName: "LessThan" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" - ), - ] - ); - } - private ValidatableTypeInfo CreateGCHeapSizeOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), - propertyType: typeof(double?), - name: "GreaterThan", - displayName: "GreaterThan" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), - propertyType: typeof(double?), - name: "LessThan", - displayName: "LessThan" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" - ), - ] - ); - } - private ValidatableTypeInfo CreateThreadpoolQueueLengthOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), - propertyType: typeof(double?), - name: "GreaterThan", - displayName: "GreaterThan" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), - propertyType: typeof(double?), - name: "LessThan", - displayName: "LessThan" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" - ), - ] - ); - } - private ValidatableTypeInfo CreateEventMeterOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), - propertyType: typeof(string), - name: "MeterName", - displayName: "MeterName" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), - propertyType: typeof(string), - name: "InstrumentName", - displayName: "InstrumentName" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), - propertyType: typeof(int?), - name: "HistogramPercentile", - displayName: "HistogramPercentile" - ), - ] - ); - } - private ValidatableTypeInfo CreateEventPipeProvider() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), - propertyType: typeof(string), - name: "Name", - displayName: "Name" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), - propertyType: typeof(string), - name: "Keywords", - displayName: "Keywords" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), - propertyType: typeof(global::System.Diagnostics.Tracing.EventLevel), - name: "EventLevel", - displayName: "EventLevel" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "Arguments", - displayName: "Arguments" - ), - ] - ); - } - private ValidatableTypeInfo CreatePassThroughOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), - members: [] - ); - } - private ValidatableTypeInfo CreateTestValidatableTypes() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - name: "CollectionRuleOptions", - displayName: "CollectionRuleOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - name: "ExecuteOptions", - displayName: "ExecuteOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), - name: "SetEnvironmentVariableOptions", - displayName: "SetEnvironmentVariableOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), - name: "GetEnvironmentVariableOptions", - displayName: "GetEnvironmentVariableOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - name: "CollectTraceOptions", - displayName: "CollectTraceOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - name: "GlobalCounterOptions", - displayName: "GlobalCounterOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), - name: "CollectGCDumpOptions", - displayName: "CollectGCDumpOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), - name: "CollectLiveMetricsOptions", - displayName: "CollectLiveMetricsOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), - name: "CollectStacksOptions", - displayName: "CollectStacksOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - name: "CollectLogsOptions", - displayName: "CollectLogsOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - name: "RootOptions", - displayName: "RootOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - name: "FileSystemEgressProviderOptions", - displayName: "FileSystemEgressProviderOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), - name: "CollectDumpOptions", - displayName: "CollectDumpOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), - name: "LoadProfilerOptions", - displayName: "LoadProfilerOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), - name: "CollectExceptionsOptions", - displayName: "CollectExceptionsOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), - name: "AspNetRequestCountOptions", - displayName: "AspNetRequestCountOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), - name: "AspNetRequestDurationOptions", - displayName: "AspNetRequestDurationOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), - name: "AspNetResponseStatusOptions", - displayName: "AspNetResponseStatusOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), - name: "EventCounterOptions", - displayName: "EventCounterOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), - name: "CPUUsageOptions", - displayName: "CPUUsageOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), - name: "GCHeapSizeOptions", - displayName: "GCHeapSizeOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), - name: "ThreadpoolQueueLengthOptions", - displayName: "ThreadpoolQueueLengthOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), - name: "EventMeterOptions", - displayName: "EventMeterOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), - name: "PassThroughOptions", - displayName: "PassThroughOptions" - ), - ] - ); - } - } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - internal static class GeneratedServiceCollectionExtensions + file static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "9oH9pfUMx0r35bT1qr89ily/AQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "PAnjif+NkJ3ztrKunTBG39nHAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj index b361489a992..45472d5924c 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj @@ -4,8 +4,6 @@ net10.0 enable enable - $(InterceptorsNamespaces);Microsoft.AspNetCore.Http.Validation.Generated - true @@ -31,10 +29,4 @@ LatestRuntimeFrameworkVersion="$(AspNetCoreAppVersion)" /> - - - - - - diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs index be3c8080f60..904c7830862 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs @@ -1,32 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Tools.Monitor; -using Microsoft.AspNetCore.Http.Validation; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; -using Microsoft.Diagnostics.Tools.Monitor.Extensibility; -using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; +using Microsoft.AspNetCore.Http.Validation.Generated; var builder = WebApplication.CreateBuilder(new WebApplicationOptions { ContentRootPath = AppContext.BaseDirectory }); -Microsoft.AspNetCore.Http.Validation.Generated.GeneratedServiceCollectionExtensions.AddValidation(builder.Services); +GeneratedServiceCollectionExtensions.AddValidation(builder.Services); builder.Build(); public partial class Program {} - -[ValidatableType] -sealed class TestValidatableType -{ - public required ExtensionManifest ExtensionManifest { get; init; } - - // public RootOptions RootOptions { get; init; } // TODO: this hits bad generated code. - // Take a more granular approach for now. - public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } - - public required ExecuteOptions ExecuteOptions { get; init; } - - public required AzureAdOptions AzureAdOptions { get; init; } -} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs deleted file mode 100644 index 21ecadd532c..00000000000 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/ValidatableInfoResolver.cs +++ /dev/null @@ -1,847 +0,0 @@ -#nullable enable annotations -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ -#nullable enable - -namespace System.Runtime.CompilerServices -{ - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] - file sealed class InterceptsLocationAttribute : System.Attribute - { - public InterceptsLocationAttribute(int version, string data) - { - } - } -} - -namespace Microsoft.AspNetCore.Http.Validation.Generated -{ - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - file sealed class GeneratedValidatablePropertyInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatablePropertyInfo - { - public GeneratedValidatablePropertyInfo( - [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] - global::System.Type containingType, - global::System.Type propertyType, - string name, - string displayName) : base(containingType, propertyType, name, displayName) - { - ContainingType = containingType; - Name = name; - } - - internal global::System.Type ContainingType { get; } - internal string Name { get; } - - protected override global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes() - => ValidationAttributeCache.GetValidationAttributes(ContainingType, Name); - } - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - file sealed class GeneratedValidatableTypeInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatableTypeInfo - { - public GeneratedValidatableTypeInfo( - [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.Interfaces)] - global::System.Type type, - ValidatablePropertyInfo[] members) : base(type, members) { } - } - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - file class GeneratedValidatableInfoResolver : global::Microsoft.AspNetCore.Http.Validation.IValidatableInfoResolver - { - public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) - { - validatableInfo = null; - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest)) - { - validatableInfo = CreateExtensionManifest(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions)) - { - validatableInfo = CreateFileSystemEgressProviderOptions(); - return true; - } - if (type == typeof(global::System.Reflection.MethodBase)) - { - validatableInfo = CreateMethodBase(); - return true; - } - if (type == typeof(global::System.Reflection.ConstructorInfo)) - { - validatableInfo = CreateConstructorInfo(); - return true; - } - if (type == typeof(global::System.Reflection.CustomAttributeTypedArgument)) - { - validatableInfo = CreateCustomAttributeTypedArgument(); - return true; - } - if (type == typeof(global::System.Reflection.CustomAttributeNamedArgument)) - { - validatableInfo = CreateCustomAttributeNamedArgument(); - return true; - } - if (type == typeof(global::System.Reflection.CustomAttributeData)) - { - validatableInfo = CreateCustomAttributeData(); - return true; - } - if (type == typeof(global::System.Reflection.ParameterInfo)) - { - validatableInfo = CreateParameterInfo(); - return true; - } - if (type == typeof(global::System.Reflection.MethodInfo)) - { - validatableInfo = CreateMethodInfo(); - return true; - } - if (type == typeof(global::System.Reflection.EventInfo)) - { - validatableInfo = CreateEventInfo(); - return true; - } - if (type == typeof(global::System.Reflection.FieldInfo)) - { - validatableInfo = CreateFieldInfo(); - return true; - } - if (type == typeof(global::System.Reflection.PropertyInfo)) - { - validatableInfo = CreatePropertyInfo(); - return true; - } - if (type == typeof(global::System.Reflection.TypeInfo)) - { - validatableInfo = CreateTypeInfo(); - return true; - } - if (type == typeof(global::System.Reflection.Assembly)) - { - validatableInfo = CreateAssembly(); - return true; - } - if (type == typeof(global::System.Guid)) - { - validatableInfo = CreateGuid(); - return true; - } - if (type == typeof(global::System.Reflection.Module)) - { - validatableInfo = CreateModule(); - return true; - } - if (type == typeof(global::System.Reflection.MemberInfo)) - { - validatableInfo = CreateMemberInfo(); - return true; - } - if (type == typeof(global::System.Type)) - { - validatableInfo = CreateType(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions)) - { - validatableInfo = CreateBaseRecordOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions)) - { - validatableInfo = CreateExecuteOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions)) - { - validatableInfo = CreateAzureAdOptions(); - return true; - } - if (type == typeof(global::TestValidatableType)) - { - validatableInfo = CreateTestValidatableType(); - return true; - } - - return false; - } - - // No-ops, rely on runtime code for ParameterInfo-based resolution - public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterInfo parameterInfo, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) - { - validatableInfo = null; - return false; - } - - private ValidatableTypeInfo CreateExtensionManifest() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), - propertyType: typeof(string), - name: "Name", - displayName: "Name" - ), - ] - ); - } - private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - propertyType: typeof(string), - name: "DirectoryPath", - displayName: "DirectoryPath" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - propertyType: typeof(int?), - name: "CopyBufferSize", - displayName: "CopyBufferSize" - ), - ] - ); - } - private ValidatableTypeInfo CreateMethodBase() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.MethodBase), - members: [] - ); - } - private ValidatableTypeInfo CreateConstructorInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.ConstructorInfo), - members: [] - ); - } - private ValidatableTypeInfo CreateCustomAttributeTypedArgument() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.CustomAttributeTypedArgument), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeTypedArgument), - propertyType: typeof(global::System.Type), - name: "ArgumentType", - displayName: "ArgumentType" - ), - ] - ); - } - private ValidatableTypeInfo CreateCustomAttributeNamedArgument() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.CustomAttributeNamedArgument), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), - propertyType: typeof(global::System.Reflection.MemberInfo), - name: "MemberInfo", - displayName: "MemberInfo" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), - propertyType: typeof(global::System.Reflection.CustomAttributeTypedArgument), - name: "TypedValue", - displayName: "TypedValue" - ), - ] - ); - } - private ValidatableTypeInfo CreateCustomAttributeData() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.CustomAttributeData), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeData), - propertyType: typeof(global::System.Type), - name: "AttributeType", - displayName: "AttributeType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeData), - propertyType: typeof(global::System.Reflection.ConstructorInfo), - name: "Constructor", - displayName: "Constructor" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeData), - propertyType: typeof(global::System.Collections.Generic.IList), - name: "ConstructorArguments", - displayName: "ConstructorArguments" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeData), - propertyType: typeof(global::System.Collections.Generic.IList), - name: "NamedArguments", - displayName: "NamedArguments" - ), - ] - ); - } - private ValidatableTypeInfo CreateParameterInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.ParameterInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.ParameterInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "CustomAttributes", - displayName: "CustomAttributes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.ParameterInfo), - propertyType: typeof(global::System.Reflection.MemberInfo), - name: "Member", - displayName: "Member" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.ParameterInfo), - propertyType: typeof(global::System.Type), - name: "ParameterType", - displayName: "ParameterType" - ), - ] - ); - } - private ValidatableTypeInfo CreateMethodInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.MethodInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MethodInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MethodInfo), - propertyType: typeof(global::System.Reflection.ParameterInfo), - name: "ReturnParameter", - displayName: "ReturnParameter" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MethodInfo), - propertyType: typeof(global::System.Type), - name: "ReturnType", - displayName: "ReturnType" - ), - ] - ); - } - private ValidatableTypeInfo CreateEventInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.EventInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "AddMethod", - displayName: "AddMethod" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Type), - name: "EventHandlerType", - displayName: "EventHandlerType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "RaiseMethod", - displayName: "RaiseMethod" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "RemoveMethod", - displayName: "RemoveMethod" - ), - ] - ); - } - private ValidatableTypeInfo CreateFieldInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.FieldInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.FieldInfo), - propertyType: typeof(global::System.Type), - name: "FieldType", - displayName: "FieldType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.FieldInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - ] - ); - } - private ValidatableTypeInfo CreatePropertyInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.PropertyInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.PropertyInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "GetMethod", - displayName: "GetMethod" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.PropertyInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.PropertyInfo), - propertyType: typeof(global::System.Type), - name: "PropertyType", - displayName: "PropertyType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.PropertyInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "SetMethod", - displayName: "SetMethod" - ), - ] - ); - } - private ValidatableTypeInfo CreateTypeInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.TypeInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredConstructors", - displayName: "DeclaredConstructors" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredEvents", - displayName: "DeclaredEvents" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredFields", - displayName: "DeclaredFields" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredMembers", - displayName: "DeclaredMembers" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredMethods", - displayName: "DeclaredMethods" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredNestedTypes", - displayName: "DeclaredNestedTypes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredProperties", - displayName: "DeclaredProperties" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "ImplementedInterfaces", - displayName: "ImplementedInterfaces" - ), - ] - ); - } - private ValidatableTypeInfo CreateAssembly() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.Assembly), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "CustomAttributes", - displayName: "CustomAttributes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DefinedTypes", - displayName: "DefinedTypes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "EntryPoint", - displayName: "EntryPoint" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "ExportedTypes", - displayName: "ExportedTypes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Reflection.Module), - name: "ManifestModule", - displayName: "ManifestModule" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "Modules", - displayName: "Modules" - ), - ] - ); - } - private ValidatableTypeInfo CreateGuid() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Guid), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Guid), - propertyType: typeof(global::System.Guid), - name: "AllBitsSet", - displayName: "AllBitsSet" - ), - ] - ); - } - private ValidatableTypeInfo CreateModule() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.Module), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Module), - propertyType: typeof(global::System.Reflection.Assembly), - name: "Assembly", - displayName: "Assembly" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Module), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "CustomAttributes", - displayName: "CustomAttributes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Module), - propertyType: typeof(global::System.Guid), - name: "ModuleVersionId", - displayName: "ModuleVersionId" - ), - ] - ); - } - private ValidatableTypeInfo CreateMemberInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.MemberInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "CustomAttributes", - displayName: "CustomAttributes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Type), - name: "DeclaringType", - displayName: "DeclaringType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Reflection.Module), - name: "Module", - displayName: "Module" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Type), - name: "ReflectedType", - displayName: "ReflectedType" - ), - ] - ); - } - private ValidatableTypeInfo CreateType() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Type), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.Assembly), - name: "Assembly", - displayName: "Assembly" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type), - name: "BaseType", - displayName: "BaseType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.MethodBase), - name: "DeclaringMethod", - displayName: "DeclaringMethod" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type), - name: "DeclaringType", - displayName: "DeclaringType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type[]), - name: "GenericTypeArguments", - displayName: "GenericTypeArguments" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Guid), - name: "GUID", - displayName: "GUID" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.Module), - name: "Module", - displayName: "Module" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type), - name: "ReflectedType", - displayName: "ReflectedType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.ConstructorInfo), - name: "TypeInitializer", - displayName: "TypeInitializer" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type), - name: "UnderlyingSystemType", - displayName: "UnderlyingSystemType" - ), - ] - ); - } - private ValidatableTypeInfo CreateBaseRecordOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), - members: [ - ] - ); - } - private ValidatableTypeInfo CreateExecuteOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - propertyType: typeof(string), - name: "Path", - displayName: "Path" - ), - ] - ); - } - private ValidatableTypeInfo CreateAzureAdOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - propertyType: typeof(string), - name: "TenantId", - displayName: "TenantId" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - propertyType: typeof(string), - name: "ClientId", - displayName: "ClientId" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - propertyType: typeof(global::System.Uri), - name: "AppIdUri", - displayName: "AppIdUri" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - propertyType: typeof(string), - name: "RequiredRole", - displayName: "RequiredRole" - ), - ] - ); - } - private ValidatableTypeInfo CreateTestValidatableType() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::TestValidatableType), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::TestValidatableType), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), - name: "ExtensionManifest", - displayName: "ExtensionManifest" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::TestValidatableType), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - name: "FileSystemEgressProviderOptions", - displayName: "FileSystemEgressProviderOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::TestValidatableType), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - name: "ExecuteOptions", - displayName: "ExecuteOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::TestValidatableType), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - name: "AzureAdOptions", - displayName: "AzureAdOptions" - ), - ] - ); - } - - } - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - internal static class GeneratedServiceCollectionExtensions - { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "/S4C/fYaYK+RGue0pzw4eqSWAABWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) - { - // Use non-extension method to avoid infinite recursion. - return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => - { - options.Resolvers.Insert(0, new GeneratedValidatableInfoResolver()); - if (configureOptions is not null) - { - configureOptions(options); - } - }); - } - } - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - file static class ValidationAttributeCache - { - private sealed record CacheKey(global::System.Type ContainingType, string PropertyName); - private static readonly global::System.Collections.Concurrent.ConcurrentDictionary _cache = new(); - - public static global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes( - global::System.Type containingType, - string propertyName) - { - var key = new CacheKey(containingType, propertyName); - return _cache.GetOrAdd(key, static k => - { - var results = new global::System.Collections.Generic.List(); - - // Get attributes from the property - var property = k.ContainingType.GetProperty(k.PropertyName); - if (property != null) - { - var propertyAttributes = global::System.Reflection.CustomAttributeExtensions - .GetCustomAttributes(property, inherit: true); - - results.AddRange(propertyAttributes); - } - - // Check constructors for parameters that match the property name - // to handle record scenarios - foreach (var constructor in k.ContainingType.GetConstructors()) - { - // Look for parameter with matching name (case insensitive) - var parameter = global::System.Linq.Enumerable.FirstOrDefault( - constructor.GetParameters(), - p => string.Equals(p.Name, k.PropertyName, global::System.StringComparison.OrdinalIgnoreCase)); - - if (parameter != null) - { - var paramAttributes = global::System.Reflection.CustomAttributeExtensions - .GetCustomAttributes(parameter, inherit: true); - - results.AddRange(paramAttributes); - - break; - } - } - - return results.ToArray(); - }); - } - } -} \ No newline at end of file diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CustomValidationInfo.cs b/src/Tools/dotnet-monitor/CustomValidationInfo.cs similarity index 100% rename from src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/CustomValidationInfo.cs rename to src/Tools/dotnet-monitor/CustomValidationInfo.cs diff --git a/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs b/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs index e9aee2074bc..39190d80b54 100644 --- a/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs +++ b/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs @@ -21,7 +21,6 @@ internal partial class ExtensionManifestContext : JsonSerializerContext { } - [ValidatableType] internal class ExtensionManifest : IValidatableObject { public const string DefaultFileName = "extension.json"; diff --git a/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs b/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs index 0e02219e242..0024823d9d2 100644 --- a/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs +++ b/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.AspNetCore.Http.Validation.Generated; using Microsoft.AspNetCore.Hosting; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.Auth; @@ -130,7 +129,7 @@ public static IHostBuilder CreateHostBuilder(HostBuilderSettings settings) services.AddSingleton(listenResults); services.AddSingleton(); services.AddHostedService(); - MyExtensions.AddValidation(services); + ValidatableTypes.AddValidation(services); }) .ConfigureKestrel((context, options) => { diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index 776331e9d0b..5b2c4d67fb7 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -60,11 +60,6 @@ public GeneratedValidatableTypeInfo( public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) { validatableInfo = null; - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest)) - { - validatableInfo = CreateExtensionManifest(); - return true; - } if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider)) { validatableInfo = CreateMetricProvider(); @@ -90,6 +85,206 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateAuthenticationOptions(); return true; } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions)) + { + validatableInfo = CreateCollectionRuleTriggerOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions)) + { + validatableInfo = CreateCollectionRuleActionOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions)) + { + validatableInfo = CreateCollectionRuleLimitsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions)) + { + validatableInfo = CreateCollectionRuleOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter)) + { + validatableInfo = CreateTraceEventFilter(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions)) + { + validatableInfo = CreateCollectTraceOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions)) + { + validatableInfo = CreateExecuteOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions)) + { + validatableInfo = CreateSetEnvironmentVariableOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions)) + { + validatableInfo = CreateGetEnvironmentVariableOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions)) + { + validatableInfo = CreateGlobalCounterOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions)) + { + validatableInfo = CreateCollectGCDumpOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions)) + { + validatableInfo = CreateCollectLiveMetricsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions)) + { + validatableInfo = CreateCollectStacksOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions)) + { + validatableInfo = CreateCollectLogsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration)) + { + validatableInfo = CreateExceptionsConfiguration(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions)) + { + validatableInfo = CreateExceptionsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions)) + { + validatableInfo = CreateInProcessFeaturesOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions)) + { + validatableInfo = CreateCorsConfigurationOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions)) + { + validatableInfo = CreateEgressOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions)) + { + validatableInfo = CreateProcessFilterOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions)) + { + validatableInfo = CreateCollectionRuleTriggerDefaultsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions)) + { + validatableInfo = CreateCollectionRuleLimitsDefaultsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions)) + { + validatableInfo = CreateCollectionRuleDefaultsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions)) + { + validatableInfo = CreateTemplateOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions)) + { + validatableInfo = CreateRootOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions)) + { + validatableInfo = CreateFileSystemEgressProviderOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions)) + { + validatableInfo = CreateCollectDumpOptions(); + return true; + } + if (type == typeof(global::System.Guid)) + { + validatableInfo = CreateGuid(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions)) + { + validatableInfo = CreateLoadProfilerOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions)) + { + validatableInfo = CreateCollectExceptionsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions)) + { + validatableInfo = CreateAspNetRequestCountOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions)) + { + validatableInfo = CreateAspNetRequestDurationOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions)) + { + validatableInfo = CreateAspNetResponseStatusOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions)) + { + validatableInfo = CreateEventCounterOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions)) + { + validatableInfo = CreateCPUUsageOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions)) + { + validatableInfo = CreateGCHeapSizeOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions)) + { + validatableInfo = CreateThreadpoolQueueLengthOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions)) + { + validatableInfo = CreateEventMeterOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider)) + { + validatableInfo = CreateEventPipeProvider(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest)) + { + validatableInfo = CreateExtensionManifest(); + return true; + } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes)) { validatableInfo = CreateValidatableTypes(); @@ -106,20 +301,6 @@ public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterIn return false; } - private ValidatableTypeInfo CreateExtensionManifest() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), - propertyType: typeof(string), - name: "Name", - displayName: "Name" - ), - ] - ); - } private ValidatableTypeInfo CreateMetricProvider() { return new GeneratedValidatableTypeInfo( @@ -226,41 +407,1145 @@ private ValidatableTypeInfo CreateAuthenticationOptions() ] ); } - private ValidatableTypeInfo CreateValidatableTypes() + private ValidatableTypeInfo CreateCollectionRuleTriggerOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - name: "MetricsOptions", - displayName: "MetricsOptions" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + propertyType: typeof(string), + name: "Type", + displayName: "Type" ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleActionOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), + members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), - name: "AuthenticationOptions", - displayName: "AuthenticationOptions" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), + propertyType: typeof(string), + name: "Type", + displayName: "Type" ), ] ); } - - } - - static class MyExtensions - { - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + private ValidatableTypeInfo CreateCollectionRuleLimitsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(int?), + name: "ActionCount", + displayName: "ActionCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "ActionCountSlidingWindowDuration", + displayName: "ActionCountSlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RuleDuration", + displayName: "RuleDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + name: "Trigger", + displayName: "Trigger" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Actions", + displayName: "Actions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + name: "Limits", + displayName: "Limits" + ), + ] + ); + } + private ValidatableTypeInfo CreateTraceEventFilter() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(string), + name: "ProviderName", + displayName: "ProviderName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(string), + name: "EventName", + displayName: "EventName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "PayloadFilter", + displayName: "PayloadFilter" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectTraceOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.TraceProfile?), + name: "Profile", + displayName: "Profile" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(int?), + name: "BufferSizeMegabytes", + displayName: "BufferSizeMegabytes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Duration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + name: "StoppingEvent", + displayName: "StoppingEvent" + ), + ] + ); + } + private ValidatableTypeInfo CreateExecuteOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + propertyType: typeof(string), + name: "Path", + displayName: "Path" + ), + ] + ); + } + private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + propertyType: typeof(string), + name: "Name", + displayName: "Name" + ), + ] + ); + } + private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() { - return GeneratedServiceCollectionExtensions.AddValidation(services, configureOptions); + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + propertyType: typeof(string), + name: "Name", + displayName: "Name" + ), + ] + ); } + private ValidatableTypeInfo CreateGlobalCounterOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(float?), + name: "IntervalSeconds", + displayName: "IntervalSeconds" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(int?), + name: "MaxHistograms", + displayName: "MaxHistograms" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(int?), + name: "MaxTimeSeries", + displayName: "MaxTimeSeries" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Providers", + displayName: "Providers" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectGCDumpOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectLiveMetricsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Duration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectStacksOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectLogsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::Microsoft.Extensions.Logging.LogLevel?), + name: "DefaultLevel", + displayName: "DefaultLevel" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::System.Collections.Generic.Dictionary), + name: "FilterSpecs", + displayName: "FilterSpecs" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Duration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.LogFormat?), + name: "Format", + displayName: "Format" + ), + ] + ); + } + private ValidatableTypeInfo CreateExceptionsConfiguration() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Exclude", + displayName: "Exclude" + ), + ] + ); + } + private ValidatableTypeInfo CreateExceptionsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + propertyType: typeof(int?), + name: "TopLevelLimit", + displayName: "TopLevelLimit" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + name: "CollectionFilters", + displayName: "CollectionFilters" + ), + ] + ); + } + private ValidatableTypeInfo CreateInProcessFeaturesOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + name: "Exceptions", + displayName: "Exceptions" + ), + ] + ); + } + private ValidatableTypeInfo CreateCorsConfigurationOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + propertyType: typeof(string), + name: "AllowedOrigins", + displayName: "AllowedOrigins" + ), + ] + ); + } + private ValidatableTypeInfo CreateEgressOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "FileSystem", + displayName: "FileSystem" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Properties", + displayName: "Properties" + ), + ] + ); + } + private ValidatableTypeInfo CreateProcessFilterOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Filters", + displayName: "Filters" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleTriggerDefaultsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(int?), + name: "RequestCount", + displayName: "RequestCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(int?), + name: "ResponseCount", + displayName: "ResponseCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleLimitsDefaultsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(int?), + name: "ActionCount", + displayName: "ActionCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "ActionCountSlidingWindowDuration", + displayName: "ActionCountSlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RuleDuration", + displayName: "RuleDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleDefaultsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + name: "Triggers", + displayName: "Triggers" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + name: "Limits", + displayName: "Limits" + ), + ] + ); + } + private ValidatableTypeInfo CreateTemplateOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleFilters", + displayName: "CollectionRuleFilters" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleTriggers", + displayName: "CollectionRuleTriggers" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleActions", + displayName: "CollectionRuleActions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleLimits", + displayName: "CollectionRuleLimits" + ), + ] + ); + } + private ValidatableTypeInfo CreateRootOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + name: "Authentication", + displayName: "Authentication" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRules", + displayName: "CollectionRules" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + name: "GlobalCounter", + displayName: "GlobalCounter" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + name: "InProcessFeatures", + displayName: "InProcessFeatures" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + name: "CorsConfiguration", + displayName: "CorsConfiguration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + name: "Egress", + displayName: "Egress" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + name: "Metrics", + displayName: "Metrics" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), + name: "DefaultProcess", + displayName: "DefaultProcess" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + name: "CollectionRuleDefaults", + displayName: "CollectionRuleDefaults" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + name: "Templates", + displayName: "Templates" + ), + ] + ); + } + private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + propertyType: typeof(string), + name: "DirectoryPath", + displayName: "DirectoryPath" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + propertyType: typeof(int?), + name: "CopyBufferSize", + displayName: "CopyBufferSize" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectDumpOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.DumpType?), + name: "Type", + displayName: "Type" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + ] + ); + } + private ValidatableTypeInfo CreateGuid() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Guid), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Guid), + propertyType: typeof(global::System.Guid), + name: "AllBitsSet", + displayName: "AllBitsSet" + ), + ] + ); + } + private ValidatableTypeInfo CreateLoadProfilerOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + propertyType: typeof(string), + name: "Path", + displayName: "Path" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + propertyType: typeof(global::System.Guid), + name: "Clsid", + displayName: "Clsid" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectExceptionsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + name: "Filters", + displayName: "Filters" + ), + ] + ); + } + private ValidatableTypeInfo CreateAspNetRequestCountOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + propertyType: typeof(int), + name: "RequestCount", + displayName: "RequestCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + propertyType: typeof(string[]), + name: "IncludePaths", + displayName: "IncludePaths" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + propertyType: typeof(string[]), + name: "ExcludePaths", + displayName: "ExcludePaths" + ), + ] + ); + } + private ValidatableTypeInfo CreateAspNetRequestDurationOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(int), + name: "RequestCount", + displayName: "RequestCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RequestDuration", + displayName: "RequestDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(string[]), + name: "IncludePaths", + displayName: "IncludePaths" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(string[]), + name: "ExcludePaths", + displayName: "ExcludePaths" + ), + ] + ); + } + private ValidatableTypeInfo CreateAspNetResponseStatusOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(string[]), + name: "StatusCodes", + displayName: "StatusCodes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(int), + name: "ResponseCount", + displayName: "ResponseCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(string[]), + name: "IncludePaths", + displayName: "IncludePaths" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(string[]), + name: "ExcludePaths", + displayName: "ExcludePaths" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventCounterOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + propertyType: typeof(string), + name: "ProviderName", + displayName: "ProviderName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + propertyType: typeof(string), + name: "CounterName", + displayName: "CounterName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateCPUUsageOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + propertyType: typeof(double?), + name: "GreaterThan", + displayName: "GreaterThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + propertyType: typeof(double?), + name: "LessThan", + displayName: "LessThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateGCHeapSizeOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + propertyType: typeof(double?), + name: "GreaterThan", + displayName: "GreaterThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + propertyType: typeof(double?), + name: "LessThan", + displayName: "LessThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateThreadpoolQueueLengthOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + propertyType: typeof(double?), + name: "GreaterThan", + displayName: "GreaterThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + propertyType: typeof(double?), + name: "LessThan", + displayName: "LessThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventMeterOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + propertyType: typeof(string), + name: "MeterName", + displayName: "MeterName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + propertyType: typeof(string), + name: "InstrumentName", + displayName: "InstrumentName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + propertyType: typeof(int?), + name: "HistogramPercentile", + displayName: "HistogramPercentile" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventPipeProvider() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(string), + name: "Name", + displayName: "Name" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(string), + name: "Keywords", + displayName: "Keywords" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(global::System.Diagnostics.Tracing.EventLevel), + name: "EventLevel", + displayName: "EventLevel" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Arguments", + displayName: "Arguments" + ), + ] + ); + } + private ValidatableTypeInfo CreateExtensionManifest() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), + propertyType: typeof(string), + name: "Name", + displayName: "Name" + ), + ] + ); + } + private ValidatableTypeInfo CreateValidatableTypes() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + name: "MetricsOptions", + displayName: "MetricsOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + name: "AuthenticationOptions", + displayName: "AuthenticationOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + name: "CollectionRuleOptions", + displayName: "CollectionRuleOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + name: "CollectTraceOptions", + displayName: "CollectTraceOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + name: "ExecuteOptions", + displayName: "ExecuteOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + name: "SetEnvironmentVariableOptions", + displayName: "SetEnvironmentVariableOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + name: "GetEnvironmentVariableOptions", + displayName: "GetEnvironmentVariableOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + name: "GlobalCounterOptions", + displayName: "GlobalCounterOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + name: "CollectGCDumpOptions", + displayName: "CollectGCDumpOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + name: "CollectLiveMetricsOptions", + displayName: "CollectLiveMetricsOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + name: "CollectStacksOptions", + displayName: "CollectStacksOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + name: "CollectLogsOptions", + displayName: "CollectLogsOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + name: "RootOptions", + displayName: "RootOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + name: "FileSystemEgressProviderOptions", + displayName: "FileSystemEgressProviderOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + name: "CollectDumpOptions", + displayName: "CollectDumpOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + name: "LoadProfilerOptions", + displayName: "LoadProfilerOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + name: "CollectExceptionsOptions", + displayName: "CollectExceptionsOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + name: "AspNetRequestCountOptions", + displayName: "AspNetRequestCountOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + name: "AspNetRequestDurationOptions", + displayName: "AspNetRequestDurationOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + name: "AspNetResponseStatusOptions", + displayName: "AspNetResponseStatusOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + name: "EventCounterOptions", + displayName: "EventCounterOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + name: "CPUUsageOptions", + displayName: "CPUUsageOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + name: "GCHeapSizeOptions", + displayName: "GCHeapSizeOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + name: "ThreadpoolQueueLengthOptions", + displayName: "ThreadpoolQueueLengthOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + name: "EventMeterOptions", + displayName: "EventMeterOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + name: "EventPipeProvider", + displayName: "EventPipeProvider" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), + name: "ExtensionManifest", + displayName: "ExtensionManifest" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + name: "AzureAdOptions", + displayName: "AzureAdOptions" + ), + ] + ); + } + } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - file static class GeneratedServiceCollectionExtensions + internal static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "tgKaeQ8w+KgICFY1OfbdmEk4AABWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "D6nh8/WlpPzAY1xLUbepOblXAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. diff --git a/src/Tools/dotnet-monitor/ValidatableTypes.cs b/src/Tools/dotnet-monitor/ValidatableTypes.cs index d535e7540ee..1e9e43246cf 100644 --- a/src/Tools/dotnet-monitor/ValidatableTypes.cs +++ b/src/Tools/dotnet-monitor/ValidatableTypes.cs @@ -2,7 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http.Validation; +using Microsoft.AspNetCore.Http.Validation.Generated; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts; +using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; +using Microsoft.Diagnostics.Tools.Monitor.Extensibility; +using Microsoft.Extensions.DependencyInjection; namespace Microsoft.Diagnostics.Tools.Monitor { @@ -16,5 +26,67 @@ internal class ValidatableTypes public required MetricsOptions MetricsOptions { get; init; } public required AuthenticationOptions AuthenticationOptions { get; init; } + + public required CollectionRuleOptions CollectionRuleOptions { get; init; } + + public required CollectTraceOptions CollectTraceOptions { get; init; } + + public required ExecuteOptions ExecuteOptions { get; init; } + + public required SetEnvironmentVariableOptions SetEnvironmentVariableOptions { get; init; } + + public required GetEnvironmentVariableOptions GetEnvironmentVariableOptions { get; init; } + + public required GlobalCounterOptions GlobalCounterOptions { get; init; } + + public required CollectGCDumpOptions CollectGCDumpOptions { get; init; } + + public required CollectLiveMetricsOptions CollectLiveMetricsOptions { get; init; } + + public required CollectStacksOptions CollectStacksOptions { get; init; } + + public required CollectLogsOptions CollectLogsOptions { get; init; } + + public required RootOptions RootOptions { get; init; } + + public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } + + public required CollectDumpOptions CollectDumpOptions { get; init; } + + public required LoadProfilerOptions LoadProfilerOptions { get; init; } + + public required CollectExceptionsOptions CollectExceptionsOptions { get; init; } + + // Triggers... + public required AspNetRequestCountOptions AspNetRequestCountOptions { get; init; } + public required AspNetRequestDurationOptions AspNetRequestDurationOptions { get; init; } + public required AspNetResponseStatusOptions AspNetResponseStatusOptions { get; init; } + public required EventCounterOptions EventCounterOptions { get; init; } + public required CPUUsageOptions CPUUsageOptions { get; init; } + public required GCHeapSizeOptions GCHeapSizeOptions { get; init; } + public required ThreadpoolQueueLengthOptions ThreadpoolQueueLengthOptions { get; init; } + public required EventMeterOptions EventMeterOptions { get; init; } + + // Nested member + public required EventPipeProvider EventPipeProvider { get; init; } + + public required ExtensionManifest ExtensionManifest { get; init; } + + // public RootOptions RootOptions { get; init; } // TODO: this hits bad generated code. + // Take a more granular approach for now. + + + public required AzureAdOptions AzureAdOptions { get; init; } + + // TODO: only one resolver per project? Generate this for tests, for now. Maybe want to separate this one out + // by test later. + public static void AddValidation(IServiceCollection services) + { + GeneratedServiceCollectionExtensions.AddValidation(services); + ValidationServiceCollectionExtensions.AddValidation(services, options => + { + options.Resolvers.Insert(0, new CustomValidatableInfoResolver()); + }); + } } } From f017416ae9fd3ad68d68df9ffdc3286b39925b9c Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 28 Apr 2025 18:01:08 +0000 Subject: [PATCH 152/174] Clean up some build infra --- Directory.Build.props | 1 - Directory.Packages.props | 4 ++-- NuGet.config | 1 - eng/Versions.props | 4 ++-- eng/dependabot/net10.0/Directory.Build.props | 5 ----- eng/dependabot/net10.0/NuGet.config | 1 - eng/dependabot/net10.0/Packages.props | 18 ------------------ eng/dependabot/net10.0/Versions.props | 17 ----------------- eng/dependabot/net10.0/dependabot.csproj | 6 ------ 9 files changed, 4 insertions(+), 53 deletions(-) delete mode 100644 eng/dependabot/net10.0/Directory.Build.props delete mode 120000 eng/dependabot/net10.0/NuGet.config delete mode 100644 eng/dependabot/net10.0/Packages.props delete mode 100644 eng/dependabot/net10.0/Versions.props delete mode 100644 eng/dependabot/net10.0/dependabot.csproj diff --git a/Directory.Build.props b/Directory.Build.props index 0591cf36145..15d48e5b35d 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -8,7 +8,6 @@ Latest 4 true - false true true true diff --git a/Directory.Packages.props b/Directory.Packages.props index ec92f28debd..7923f760fc8 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,8 +7,9 @@ - + + @@ -29,6 +30,5 @@ - diff --git a/NuGet.config b/NuGet.config index 6c11aedded8..5ea1461ad8a 100644 --- a/NuGet.config +++ b/NuGet.config @@ -16,7 +16,6 @@ - diff --git a/eng/Versions.props b/eng/Versions.props index b7980999bc2..45f861b0c8c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -13,7 +13,7 @@ - 'daily': sets the blob group release name to 'daily' so a release type does not have to be assigned. - 'release': sets the blob group release name to 'release'. Can be used for prereleases and full releases. --> - release + daily @@ -60,7 +60,7 @@ 9.0.0-preview.25220.1 9.0.0-preview.25220.1 - 10.0.0-preview.25076.4 + 9.0.0-preview.25076.3 10.0.0-preview.4.25217.10 10.0.0-preview.4.25217.10 diff --git a/eng/dependabot/net10.0/Directory.Build.props b/eng/dependabot/net10.0/Directory.Build.props deleted file mode 100644 index fe86741bd6c..00000000000 --- a/eng/dependabot/net10.0/Directory.Build.props +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/eng/dependabot/net10.0/NuGet.config b/eng/dependabot/net10.0/NuGet.config deleted file mode 120000 index 941555881f8..00000000000 --- a/eng/dependabot/net10.0/NuGet.config +++ /dev/null @@ -1 +0,0 @@ -../../../NuGet.config \ No newline at end of file diff --git a/eng/dependabot/net10.0/Packages.props b/eng/dependabot/net10.0/Packages.props deleted file mode 100644 index 4b4d0b76d04..00000000000 --- a/eng/dependabot/net10.0/Packages.props +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - diff --git a/eng/dependabot/net10.0/Versions.props b/eng/dependabot/net10.0/Versions.props deleted file mode 100644 index 1df4da9faf3..00000000000 --- a/eng/dependabot/net10.0/Versions.props +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - $(MicrosoftNETCoreApp100Version) - - $(MicrosoftNETCoreApp100Version) - - $(MicrosoftNETCoreApp100Version) - - $(MicrosoftNETCoreApp100Version) - - $(MicrosoftNETCoreApp100Version) - - - diff --git a/eng/dependabot/net10.0/dependabot.csproj b/eng/dependabot/net10.0/dependabot.csproj deleted file mode 100644 index 34fdf6e5f06..00000000000 --- a/eng/dependabot/net10.0/dependabot.csproj +++ /dev/null @@ -1,6 +0,0 @@ - - - - net10.0 - - From affc0984ee03dde90eb2a54272b52b60708c26c2 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 28 Apr 2025 18:01:31 +0000 Subject: [PATCH 153/174] Clean up skipped tests, remove per-test AddValidation --- .../ActionListExecutorTests.cs | 13 ++++++------- .../CollectDumpActionTests.cs | 2 +- .../CollectGCDumpActionTests.cs | 2 +- .../CollectLiveMetricsActionTests.cs | 2 +- .../CollectTraceActionTests.cs | 8 +++----- .../EnvironmentVariableActionTests.cs | 12 ++++++------ .../ExecuteActionTests.cs | 12 ++++++------ .../LoadProfilerActionTests.cs | 2 +- .../ActionDependencyAnalyzerTests.cs | 6 ------ .../CollectionRuleDefaultsTests.cs | 2 +- .../CollectionRuleDescriptionPipelineTests.cs | 4 ---- .../CollectionRulePipelineTests.cs | 4 ---- 12 files changed, 26 insertions(+), 43 deletions(-) diff --git a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs index 338f5e63e11..ba8cced86a9 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs @@ -46,7 +46,7 @@ public ActionListExecutorTests(ITestOutputHelper outputHelper) _outputHelper = outputHelper; } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] + [Fact] public async Task ActionListExecutor_AllActionsSucceed() { await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => @@ -73,16 +73,16 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => await executor.ExecuteActions(context, startCallback, cancellationTokenSource.Token); VerifyStartCallbackCount(waitForCompletion: false, callbackCount); - }, TestValidatableTypes.AddValidation); + }); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] + [Fact] public Task ActionListExecutor_SecondActionFail_DeferredCompletion() { return ActionListExecutor_SecondActionFail(waitForCompletion: false); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] + [Fact] public Task ActionListExecutor_SecondActionFail_WaitedCompletion() { return ActionListExecutor_SecondActionFail(waitForCompletion: true); @@ -119,7 +119,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => Assert.Equal(string.Format(Strings.ErrorMessage_NonzeroExitCode, "1"), actionExecutionException.Message); VerifyStartCallbackCount(waitForCompletion, callbackCount); - }, TestValidatableTypes.AddValidation); + }); } [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/61379")] @@ -165,7 +165,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => Assert.Equal(string.Format(Strings.ErrorMessage_NonzeroExitCode, "1"), actionExecutionException.Message); VerifyStartCallbackCount(waitForCompletion, callbackCount); - }, TestValidatableTypes.AddValidation); + }); } @@ -187,7 +187,6 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(); - TestValidatableTypes.AddValidation(serviceCollection); }); } private static void VerifyStartCallbackCount(bool waitForCompletion, int callbackCount) diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs index 0253279e99f..be96a7eb410 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectDumpActionTests.cs @@ -101,7 +101,7 @@ await runner.ExecuteAsync(async () => await runner.SendCommandAsync(TestAppScenarios.AsyncWait.Commands.Continue); }); - }, TestValidatableTypes.AddValidation); + }); } } } diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs index 9d791a01aff..16903391c50 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectGCDumpActionTests.cs @@ -104,7 +104,7 @@ await runner.ExecuteAsync(async () => await runner.SendCommandAsync(TestAppScenarios.AsyncWait.Commands.Continue); }); - }, TestValidatableTypes.AddValidation); + }); } private static async Task ValidateGCDump(Stream gcdumpStream) diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectLiveMetricsActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectLiveMetricsActionTests.cs index 1dfaf9b9ab5..a82a33f43c0 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectLiveMetricsActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectLiveMetricsActionTests.cs @@ -111,7 +111,7 @@ await LiveMetricsTestUtilities.ValidateMetrics(new[] { providerName }, await runner.SendCommandAsync(TestAppScenarios.AsyncWait.Commands.Continue); }); - }, TestValidatableTypes.AddValidation); + }); } [Theory(Skip = "Flaky")] diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs index e3b7902cf88..7f27357ca24 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectTraceActionTests.cs @@ -55,7 +55,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, async host => { await PerformTrace(host, tfm); - }, TestValidatableTypes.AddValidation); + }); } [Theory] @@ -79,8 +79,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => options.Duration = TimeSpan.FromSeconds(2); }) .SetStartupTrigger(); - }, host => PerformTrace(host, tfm), - TestValidatableTypes.AddValidation); + }, host => PerformTrace(host, tfm)); } [Fact] @@ -100,8 +99,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => options.Duration = TimeSpan.FromSeconds(2); }) .SetStartupTrigger(); - }, host => PerformTrace(host, TargetFrameworkMoniker.Current, artifactName), - TestValidatableTypes.AddValidation); + }, host => PerformTrace(host, TargetFrameworkMoniker.Current, artifactName)); } private async Task PerformTrace(IHost host, TargetFrameworkMoniker tfm, string artifactName = null) diff --git a/src/Tests/CollectionRuleActions.UnitTests/EnvironmentVariableActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/EnvironmentVariableActionTests.cs index e358b2fa962..4152d6724e9 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/EnvironmentVariableActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/EnvironmentVariableActionTests.cs @@ -41,7 +41,7 @@ public EnvironmentVariableActionTests(ITestOutputHelper outputHelper) /// /// The required APIs only exist on .NET 6.0+ /// - [Theory(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] + [Theory] [MemberData(nameof(ActionTestsHelper.GetTfms), MemberType = typeof(ActionTestsHelper))] public async Task TestSetEnvVar(TargetFrameworkMoniker tfm) { @@ -79,7 +79,7 @@ await runner.ExecuteAsync(async () => await runner.SendCommandAsync(TestAppScenarios.EnvironmentVariables.Commands.ShutdownScenario); }); - }, TestValidatableTypes.AddValidation); + }); } /// @@ -88,7 +88,7 @@ await runner.ExecuteAsync(async () => /// /// The required APIs only exist on .NET 6.0+ /// - [Theory(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] + [Theory] [MemberData(nameof(ActionTestsHelper.GetTfms), MemberType = typeof(ActionTestsHelper))] public async Task TestGetEnvVar(TargetFrameworkMoniker tfm) { @@ -145,7 +145,7 @@ await runner.ExecuteAsync(async () => await runner.SendCommandAsync(TestAppScenarios.EnvironmentVariables.Commands.ShutdownScenario); }); - }, TestValidatableTypes.AddValidation); + }); } /// @@ -155,7 +155,7 @@ await runner.ExecuteAsync(async () => /// /// The required APIs only exist on .NET 6.0+ /// - [Theory(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] + [Theory] [MemberData(nameof(ActionTestsHelper.GetTfms), MemberType = typeof(ActionTestsHelper))] public async Task TestEnvVarRoundTrip(TargetFrameworkMoniker tfm) { @@ -199,7 +199,7 @@ await runner.ExecuteAsync(async () => Assert.True(getResult.OutputValues.TryGetValue(CollectionRuleActionConstants.EnvironmentVariableValueName, out string value)); Assert.Equal(DefaultVarValue, value); }); - }, TestValidatableTypes.AddValidation); + }); } } } diff --git a/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs index db76a4ebb4e..5c062e23516 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs @@ -41,7 +41,7 @@ public ExecuteActionTests(ITestOutputHelper outputHelper, ExecuteActionFixture f _fixture = fixture; } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] + [Fact] public async Task ExecuteAction_ZeroExitCode() { await ValidateAction( @@ -60,7 +60,7 @@ await ValidateAction( }); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] + [Fact] public async Task ExecuteAction_NonzeroExitCode() { await ValidateAction( @@ -80,7 +80,7 @@ await ValidateAction( }); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] + [Fact] public async Task ExecuteAction_TokenCancellation() { // This timeout is much shorter than the default test timeout. @@ -107,7 +107,7 @@ await Assert.ThrowsAsync( }); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] + [Fact] public async Task ExecuteAction_TextFileOutput() { using TemporaryDirectory outputDirectory = new(_outputHelper); @@ -134,7 +134,7 @@ await ValidateAction( Assert.Equal(testMessage, File.ReadAllText(textFileOutputPath)); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] + [Fact] public async Task ExecuteAction_InvalidPath() { string uniquePathName = Guid.NewGuid().ToString(); @@ -154,7 +154,7 @@ await ValidateAction( }); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/pull/61402")] + [Fact] public async Task ExecuteAction_IgnoreExitCode() { await ValidateAction( diff --git a/src/Tests/CollectionRuleActions.UnitTests/LoadProfilerActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/LoadProfilerActionTests.cs index 0e91544c104..5e1a35c2fb9 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/LoadProfilerActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/LoadProfilerActionTests.cs @@ -73,7 +73,7 @@ await runner.ExecuteAsync(async () => await runner.SendCommandAsync(TestAppScenarios.AsyncWait.Commands.Continue); }); - }, TestValidatableTypes.AddValidation); + }); } /// diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs index d27e9847ac9..0644ea01ab5 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs @@ -136,7 +136,6 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(); - TestValidatableTypes.AddValidation(serviceCollection); }); } @@ -177,7 +176,6 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(); - TestValidatableTypes.AddValidation(serviceCollection); }); } @@ -216,7 +214,6 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { serviceCollection.AddSingleton(); serviceCollection.RegisterCollectionRuleAction(); - TestValidatableTypes.AddValidation(serviceCollection); }); } @@ -261,7 +258,6 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(); - TestValidatableTypes.AddValidation(serviceCollection); }, loggingBuilder => { loggingBuilder.AddProvider(new TestLoggerProvider(record)); @@ -299,7 +295,6 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(); - TestValidatableTypes.AddValidation(serviceCollection); }); } @@ -362,7 +357,6 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction(); - TestValidatableTypes.AddValidation(serviceCollection); }); } } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDefaultsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDefaultsTests.cs index 977098235a9..7ffb6ee6611 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDefaultsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDefaultsTests.cs @@ -73,7 +73,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => () => ActionTestsHelper.GetActionOptions(host, DefaultRuleName)); Assert.Equal(string.Format(OptionsDisplayStrings.ErrorMessage_NoDefaultEgressProvider), invalidOptionsException.Message); - }, TestValidatableTypes.AddValidation); + }); } [Fact] diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs index 032ac057a62..585a788847f 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs @@ -91,7 +91,6 @@ public Task CollectionRuleDescriptionPipeline_StartupTriggerTest(TargetFramework services => { services.RegisterTestAction(callbackService); - TestValidatableTypes.AddValidation(services); }); } @@ -292,7 +291,6 @@ await CollectionRulePipelineTestsHelper.ManualTriggerAsync( services.AddSingleton(timeProvider); services.RegisterManualTrigger(triggerService); services.RegisterTestAction(callbackService); - TestValidatableTypes.AddValidation(services); }); } @@ -340,7 +338,6 @@ public Task CollectionRuleDescriptionPipeline_ReachedRuleDuration(TargetFramewor { services.RegisterManualTrigger(triggerService); services.RegisterTestAction(callbackService); - TestValidatableTypes.AddValidation(services); }); } @@ -409,7 +406,6 @@ await CollectionRulePipelineTestsHelper.ManualTriggerAsync( services.AddSingleton(timeProvider); services.RegisterManualTrigger(triggerService); services.RegisterTestAction(callbackService); - TestValidatableTypes.AddValidation(services); }); } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs index 1f7882a4d64..a3889d34d03 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs @@ -94,7 +94,6 @@ public Task CollectionRulePipeline_StartupTriggerTest(TargetFrameworkMoniker app services => { services.RegisterTestAction(callbackService); - TestValidatableTypes.AddValidation(services); }); } @@ -224,7 +223,6 @@ public Task CollectionRulePipeline_EventMeterTriggerTest_Gauge(TargetFrameworkMo services => { services.RegisterTestAction(callbackService); - TestValidatableTypes.AddValidation(services); }); } @@ -400,7 +398,6 @@ public Task CollectionRulePipeline_DurationLimitTest(TargetFrameworkMoniker appT { services.RegisterManualTrigger(triggerService); services.RegisterTestAction(callbackService); - TestValidatableTypes.AddValidation(services); }); } @@ -464,7 +461,6 @@ await CollectionRulePipelineTestsHelper.ManualTriggerAsync( services.AddSingleton(timeProvider); services.RegisterManualTrigger(triggerService); services.RegisterTestAction(callbackService); - TestValidatableTypes.AddValidation(services); }); } From df92923fb5d8765001efae507db89df637c23c96 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 28 Apr 2025 18:27:05 +0000 Subject: [PATCH 154/174] Map metrics options --- .../dotnet-monitor/CommonOptionsMapper.cs | 69 ++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs index 6b6958e39d2..5cc5fcaada7 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs @@ -111,7 +111,7 @@ private void MapRootOptions(RootOptions obj, string prefix, string separator, ID // CorsConfigurationOptions MapDiagnosticPortOptions(obj.DiagnosticPort, FormattableString.Invariant($"{prefix}{nameof(obj.DiagnosticPort)}"), separator, map); MapEgressOptions(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), separator, map); - // MetricsOptions + MapMetricsOptions(obj.Metrics, FormattableString.Invariant($"{prefix}{nameof(obj.Metrics)}"), separator, map); MapStorageOptions(obj.Storage, FormattableString.Invariant($"{prefix}{nameof(obj.Storage)}"), separator, map); // ProcessFilterOptions MapCollectionRuleDefaultsOptions(obj.CollectionRuleDefaults, FormattableString.Invariant($"{prefix}{nameof(obj.CollectionRuleDefaults)}"), separator, map); @@ -983,6 +983,73 @@ private static void MapFileSystemEgressProviderOptions(FileSystemEgressProviderO } } + private static void MapMetricsOptions(MetricsOptions? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapBool(obj.Enabled, FormattableString.Invariant($"{prefix}{nameof(obj.Enabled)}"), map); + MapString(obj.Endpoints, FormattableString.Invariant($"{prefix}{nameof(obj.Endpoints)}"), map); + MapInt(obj.MetricCount, FormattableString.Invariant($"{prefix}{nameof(obj.MetricCount)}"), map); + MapBool(obj.IncludeDefaultProviders, FormattableString.Invariant($"{prefix}{nameof(obj.IncludeDefaultProviders)}"), map); + MapList_MetricProvider(obj.Providers, FormattableString.Invariant($"{prefix}{nameof(obj.Providers)}"), separator, map); + MapList_MeterConfiguration(obj.Meters, FormattableString.Invariant($"{prefix}{nameof(obj.Meters)}"), separator, map); + } + } + + private static void MapList_MetricProvider(List? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + for (int index = 0; index < obj.Count; index++) + { + MetricProvider value = obj[index]; + MapMetricProvider(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); + } + } + } + + private static void MapMetricProvider(MetricProvider obj, string valueName, string separator, IDictionary map) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.ProviderName, FormattableString.Invariant($"{prefix}{nameof(obj.ProviderName)}"), map); + MapList_String(obj.CounterNames, FormattableString.Invariant($"{prefix}{nameof(obj.CounterNames)}"), separator, map); + } + + private static void MapList_String(List? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + for (int index = 0; index < obj.Count; index++) + { + string value = obj[index]; + MapString(value, FormattableString.Invariant($"{prefix}{index}"), map); + } + } + } + + private static void MapList_MeterConfiguration(List? obj, string valueName, string separator, IDictionary map) + { + if (null != obj) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + for (int index = 0; index < obj.Count; index++) + { + MeterConfiguration value = obj[index]; + MapMeterConfiguration(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); + } + } + } + + private static void MapMeterConfiguration(MeterConfiguration obj, string valueName, string separator, IDictionary map) + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + MapString(obj.MeterName, FormattableString.Invariant($"{prefix}{nameof(obj.MeterName)}"), map); + MapList_String(obj.InstrumentNames, FormattableString.Invariant($"{prefix}{nameof(obj.InstrumentNames)}"), separator, map); + } + private static void MapStorageOptions(StorageOptions? obj, string valueName, string separator, IDictionary map) { if (null != obj) From c1dfd1bf89b1d9c0abc7391600c3a582708b79df Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 28 Apr 2025 20:38:46 +0000 Subject: [PATCH 155/174] Fix trim warnings --- .../Options/Actions/CollectLogsOptions.Validate.cs | 2 +- .../Options/Actions/CollectTraceOptions.Validate.cs | 2 +- src/Tools/dotnet-monitor/ConfigurationTokenParser.cs | 2 +- src/Tools/dotnet-monitor/CustomValidationInfo.cs | 9 +++++++-- src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs | 6 +++--- src/Tools/dotnet-monitor/ValidatableInfoResolver.cs | 4 +++- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs index e650ea7bbd1..624db8b4c86 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs @@ -23,7 +23,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali RequiredAttribute requiredAttribute = new(); EnumDataTypeAttribute enumValidationAttribute = new(typeof(LogLevel)); - ValidationContext filterSpecsContext = new(FilterSpecs, validationContext, validationContext.Items); + ValidationContext filterSpecsContext = new(FilterSpecs, nameof(FilterSpecs), validationContext, validationContext.Items); filterSpecsContext.MemberName = nameof(FilterSpecs); // Validate that the category is not null and that the level is a valid level value. diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs index e5ee1cf2762..8878daa5470 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs @@ -88,7 +88,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali int index = 0; foreach (EventPipeProvider provider in Providers) { - ValidationContext providerContext = new(provider, validationContext, validationContext.Items); + ValidationContext providerContext = new(provider, nameof(Providers), validationContext, validationContext.Items); providerContext.MemberName = nameof(Providers) + "[" + index.ToString(CultureInfo.InvariantCulture) + "]"; // Note: generated validation logic doesn't recurse into members of T for List, when List is not required. diff --git a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs index 281369b94d1..16ff1eae159 100644 --- a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs +++ b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs @@ -64,7 +64,7 @@ public ConfigurationTokenParser(ILogger logger) _logger = logger; } - public object? SubstituteOptionValues(object? originalSettings, Type settingsType, TokenContext context) + public object? SubstituteOptionValues(object? originalSettings, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type settingsType, TokenContext context) { object? settings = originalSettings; diff --git a/src/Tools/dotnet-monitor/CustomValidationInfo.cs b/src/Tools/dotnet-monitor/CustomValidationInfo.cs index 098d33d9f66..e06f4e5e510 100644 --- a/src/Tools/dotnet-monitor/CustomValidationInfo.cs +++ b/src/Tools/dotnet-monitor/CustomValidationInfo.cs @@ -193,6 +193,7 @@ public CustomValidatablePropertyInfo( Name = name; } + [global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties | global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] internal Type ContainingType { get; } internal string Name { get; } @@ -202,10 +203,14 @@ protected override ValidationAttribute[] GetValidationAttributes() static class ValidationAttributeCache { - private sealed record CacheKey(Type ContainingType, string PropertyName); + private sealed record CacheKey( + [property: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties | global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] + Type ContainingType, + string PropertyName); private static readonly ConcurrentDictionary _cache = new(); public static ValidationAttribute[] GetValidationAttributes( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties | global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] Type containingType, string propertyName) { @@ -216,7 +221,7 @@ public static ValidationAttribute[] GetValidationAttributes( // Get attributes from the property var property = k.ContainingType.GetProperty(k.PropertyName); - if (property != null) + if (property != null) { var propertyAttributes = CustomAttributeExtensions.GetCustomAttributes(property, inherit: true); diff --git a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs index 7ae23e12bdd..1dd32c59e4b 100644 --- a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs +++ b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs @@ -197,7 +197,7 @@ public static IServiceCollection ConfigureCollectionRules(this IServiceCollectio return services; } - public static IServiceCollection RegisterCollectionRuleAction(this IServiceCollection services) + public static IServiceCollection RegisterCollectionRuleAction<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFactory, TOptions, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TDescriptor>(this IServiceCollection services) where TFactory : class, ICollectionRuleActionFactory where TOptions : BaseRecordOptions, new() where TDescriptor : class, ICollectionRuleActionDescriptor @@ -211,7 +211,7 @@ public static IServiceCollection RegisterCollectionRuleAction(this IServiceCollection services) + public static IServiceCollection RegisterCollectionRuleTrigger<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFactory, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TDescriptor>(this IServiceCollection services) where TFactory : class, ICollectionRuleTriggerFactory where TDescriptor : class, ICollectionRuleTriggerDescriptor { @@ -221,7 +221,7 @@ public static IServiceCollection RegisterCollectionRuleTrigger(this IServiceCollection services) + public static IServiceCollection RegisterCollectionRuleTrigger<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFactory, TOptions, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TDescriptor>(this IServiceCollection services) where TFactory : class, ICollectionRuleTriggerFactory where TOptions : class, new() where TDescriptor : class, ICollectionRuleTriggerDescriptor diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index 5b2c4d67fb7..75c3716eea3 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -1563,7 +1563,9 @@ internal static class GeneratedServiceCollectionExtensions [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] file static class ValidationAttributeCache { - private sealed record CacheKey([property: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] global::System.Type ContainingType, string PropertyName); + private sealed record CacheKey( + [property: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties| global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] + global::System.Type ContainingType, string PropertyName); private static readonly global::System.Collections.Concurrent.ConcurrentDictionary _cache = new(); public static global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes( From cd2c8d7423cfeffc0ecf40eccb080f930a5b557c Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 28 Apr 2025 20:45:58 +0000 Subject: [PATCH 156/174] Remove more Skip attributes --- .../ActionListExecutorTests.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs index ba8cced86a9..be6564186dd 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs @@ -122,13 +122,13 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => }); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/61379")] + [Fact] public Task ActionListExecutor_FirstActionFail_DeferredCompletion() { return ActionListExecutor_FirstActionFail(waitForCompletion: false); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/61379")] + [Fact] public Task ActionListExecutor_FirstActionFail_WaitedCompletion() { return ActionListExecutor_FirstActionFail(waitForCompletion: true); @@ -189,6 +189,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => serviceCollection.RegisterCollectionRuleAction(); }); } + private static void VerifyStartCallbackCount(bool waitForCompletion, int callbackCount) { //Currently, any attempt to wait on completion will automatically trigger the start callback. From 07e456615d818af20e8724baf5a53d8c30e6ee41 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 28 Apr 2025 21:35:07 +0000 Subject: [PATCH 157/174] Revert non-validation changes --- .../S3StorageEgressProviderOptions.cs | 2 - .../Models/Activity.cs | 2 +- .../Models/EgressOperationStatus.cs | 2 +- .../MonitorJsonSerializerContext.cs | 36 - ...ics.Monitoring.Tool.FunctionalTests.csproj | 2 +- .../Runners/MonitorRunner.cs | 6 +- .../TestHostHelper.cs | 21 +- .../Auth/ApiKey/GeneratedJwtKey.cs | 7 +- .../ActionOptionsDependencyAnalyzer.cs | 16 +- .../Actions/CollectionRuleActionOperations.cs | 15 - .../ICollectionRuleActionOperations.cs | 8 - .../Actions/CollectLiveMetricsOptions.cs | 2 - .../Options/Actions/CollectLogsOptions.cs | 2 - .../Options/Actions/CollectTraceOptions.cs | 2 - .../CollectionRuleLimitsDefaultsOptions.cs | 3 - .../Options/CollectionRuleLimitsOptions.cs | 3 - .../CollectionRuleTriggerDefaultsOptions.cs | 2 - .../Triggers/AspNetRequestCountOptions.cs | 2 - .../Triggers/AspNetRequestDurationOptions.cs | 3 - .../Triggers/AspNetResponseStatusOptions.cs | 3 - .../Options/Triggers/EventCounterOptions.cs | 2 - .../EventCounterShortcuts/CPUUsageOptions.cs | 2 - .../GCHeapSizeOptions.cs | 2 - .../ThreadpoolQueueLengthOptions.cs | 2 - .../Options/Triggers/EventMeterOptions.cs | 2 - .../Options/ValidationHelper.cs | 3 - .../Commands/GenerateApiKeyCommandHandler.cs | 22 +- .../dotnet-monitor/CommonOptionsExtensions.cs | 156 +++ .../dotnet-monitor/CommonOptionsMapper.cs | 1182 ----------------- .../ConfigurationTokenParser.cs | 15 +- .../Extension/EgressExtension.OutputParser.cs | 6 +- .../Egress/Extension/EgressExtension.cs | 14 +- .../Extension/ExtensionEgressPayload.cs | 4 +- .../Exceptions/ExceptionsOperation.cs | 6 +- .../Extensibility/ExtensionManifest.cs | 12 +- .../Extensibility/ExtensionMode.cs | 3 - .../HostBuilder/HostBuilderHelper.cs | 2 + src/Tools/dotnet-monitor/Program.cs | 2 + src/Tools/dotnet-monitor/Startup.cs | 2 - src/Tools/dotnet-monitor/TestAssemblies.cs | 25 + .../dotnet-monitor/ValidatableInfoResolver.cs | 6 +- 41 files changed, 223 insertions(+), 1386 deletions(-) delete mode 100644 src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs create mode 100644 src/Tools/dotnet-monitor/CommonOptionsExtensions.cs delete mode 100644 src/Tools/dotnet-monitor/CommonOptionsMapper.cs diff --git a/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs b/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs index 5e868364369..aa5e0d8c757 100644 --- a/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs +++ b/src/Extensions/S3Storage/S3StorageEgressProviderOptions.cs @@ -3,7 +3,6 @@ using System; using System.ComponentModel.DataAnnotations; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Monitoring.Extension.S3Storage { @@ -52,7 +51,6 @@ internal sealed partial class S3StorageEgressProviderOptions ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_S3StorageEgressProviderOptions_PreSignedUrlExpiry))] [Range(typeof(TimeSpan), "00:01:00", "1.00:00:00")] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? PreSignedUrlExpiry { get; set; } [Display( diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/Activity.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/Activity.cs index 8498ab2274e..f64632d6384 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/Activity.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/Activity.cs @@ -12,7 +12,7 @@ public class Activity public string Id { get; set; } = string.Empty; [JsonPropertyName("idFormat")] - [JsonConverter(typeof(JsonStringEnumConverter))] + [JsonConverter(typeof(JsonStringEnumConverter))] public ActivityIdFormat IdFormat { get; set; } = ActivityIdFormat.Unknown; } } diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EgressOperationStatus.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EgressOperationStatus.cs index 49b6c2cd50f..9238f2ff58e 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EgressOperationStatus.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Models/EgressOperationStatus.cs @@ -60,7 +60,7 @@ public class OperationStatus : OperationSummary public OperationError? Error { get; set; } } - [JsonConverter(typeof(JsonStringEnumConverter))] + [JsonConverter(typeof(JsonStringEnumConverter))] public enum OperationState { Starting, diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs deleted file mode 100644 index 620676dba2b..00000000000 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Text.Json.Serialization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Diagnostics.Monitoring.WebApi.Models; -using Microsoft.Diagnostics.Monitoring.Options; - -namespace Microsoft.Diagnostics.Monitoring.WebApi -{ - [JsonSerializable(typeof(CaptureParametersConfiguration))] - [JsonSerializable(typeof(CollectionRuleDetailedDescription))] - [JsonSerializable(typeof(Dictionary))] - [JsonSerializable(typeof(Dictionary))] - [JsonSerializable(typeof(DotnetMonitorInfo))] - [JsonSerializable(typeof(DumpType))] - [JsonSerializable(typeof(EventMetricsConfiguration))] - [JsonSerializable(typeof(EventPipeConfiguration))] - [JsonSerializable(typeof(ExceptionsConfiguration))] - [JsonSerializable(typeof(FileResult))] - [JsonSerializable(typeof(Guid?))] - [JsonSerializable(typeof(IEnumerable))] - [JsonSerializable(typeof(IEnumerable))] - [JsonSerializable(typeof(IList))] - [JsonSerializable(typeof(LogsConfiguration))] - [JsonSerializable(typeof(OperationStatus))] - [JsonSerializable(typeof(ProcessInfo))] - [JsonSerializable(typeof(ProblemDetails))] - [JsonSerializable(typeof(TraceProfile))] - [JsonSerializable(typeof(ValidationProblemDetails))] - partial class MonitorJsonSerializerContext : JsonSerializerContext - { - } -} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj index eb05f1f6488..546274c7a7c 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj @@ -71,7 +71,7 @@ - + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/MonitorRunner.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/MonitorRunner.cs index 36a604d4e1c..afb28d94448 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/MonitorRunner.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Runners/MonitorRunner.cs @@ -165,8 +165,7 @@ public virtual async Task StartAsync(string command, string[] args, Cancellation _adapter.Environment.Add("ASPNETCORE_HOSTINGSTARTUPASSEMBLIES", TestHostingStartupAssemblyName); // Set configuration via environment variables - var optionsMapper = new CommonOptionsMapper(); - var configurationViaEnvironment = optionsMapper.ToEnvironmentConfiguration(ConfigurationFromEnvironment, useDotnetMonitorPrefix: true); + var configurationViaEnvironment = ConfigurationFromEnvironment.ToEnvironmentConfiguration(useDotnetMonitorPrefix: true); if (configurationViaEnvironment.Count > 0) { // Set additional environment variables from configuration @@ -198,8 +197,7 @@ protected virtual void StandardOutputCallback(string line) public void WriteKeyPerValueConfiguration(RootOptions options) { - CommonOptionsMapper optionsMapper = new(); - foreach (KeyValuePair entry in optionsMapper.ToKeyPerFileConfiguration(options)) + foreach (KeyValuePair entry in options.ToKeyPerFileConfiguration()) { File.WriteAllText( Path.Combine(SharedConfigDirectoryPath, entry.Key), diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs index 759098fe8f4..795b4fb01e9 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs @@ -10,7 +10,6 @@ using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; -using System.Globalization; using System.Threading.Tasks; using Xunit.Abstractions; @@ -74,9 +73,7 @@ public static IHost CreateHost( RootOptions options = new(); setup(options); - CommonOptionsMapper optionsMapper = new(); - optionsMapper.AddActionSettings(nameof(PassThroughAction), MapPassThroughOptions); - IDictionary configurationValues = optionsMapper.ToConfigurationValues(options); + IDictionary configurationValues = options.ToConfigurationValues(); outputHelper.WriteLine("Begin Configuration:"); foreach ((string key, string value) in configurationValues) { @@ -133,21 +130,5 @@ public static IHost CreateHost( }) .Build(); } - - private static void MapPassThroughOptions(PassThroughOptions obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Input1, FormattableString.Invariant($"{prefix}{nameof(obj.Input1)}")); - MapString(obj.Input2, FormattableString.Invariant($"{prefix}{nameof(obj.Input2)}")); - MapString(obj.Input3, FormattableString.Invariant($"{prefix}{nameof(obj.Input3)}")); - } - - void MapString(string value, string valueName) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } } } diff --git a/src/Tools/dotnet-monitor/Auth/ApiKey/GeneratedJwtKey.cs b/src/Tools/dotnet-monitor/Auth/ApiKey/GeneratedJwtKey.cs index 0ee9831044d..3b78f8d8e21 100644 --- a/src/Tools/dotnet-monitor/Auth/ApiKey/GeneratedJwtKey.cs +++ b/src/Tools/dotnet-monitor/Auth/ApiKey/GeneratedJwtKey.cs @@ -54,7 +54,7 @@ public static GeneratedJwtKey Create(TimeSpan expirationOffset) ECDsa pubDsa = ECDsa.Create(dsa.ExportParameters(includePrivateParameters: false)); ECDsaSecurityKey pubSecKey = new ECDsaSecurityKey(pubDsa); JsonWebKey jwk = JsonWebKeyConverter.ConvertFromECDsaSecurityKey(pubSecKey); - string publicKeyJson = JsonSerializer.Serialize(jwk, JsonWebKeyContext.Default.JsonWebKey); + string publicKeyJson = JsonSerializer.Serialize(jwk, new JsonSerializerOptions() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); string publicKeyEncoded = Base64UrlEncoder.Encode(publicKeyJson); JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); @@ -63,9 +63,4 @@ public static GeneratedJwtKey Create(TimeSpan expirationOffset) return new GeneratedJwtKey(output, subjectStr, publicKeyEncoded); } } - - [JsonSerializable(typeof(JsonWebKey))] - partial class JsonWebKeyContext : JsonSerializerContext - { - } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs b/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs index 6198469c77e..3f167ef603b 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs @@ -164,11 +164,7 @@ public IList GetActionDependencies(int actionIndex) } string? commandLine = _ruleContext.EndpointInfo.CommandLine; - if (!_actionOperations.TryGetOptionsType(actionOptions.Type, out Type settingsType)) - { - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownActionType, actionOptions.Name)); - } - settings = _tokenParser.SubstituteOptionValues(settings, settingsType, new TokenContext + settings = _tokenParser.SubstituteOptionValues(settings, new TokenContext { CloneOnSubstitution = ReferenceEquals(originalSettings, settings), RuntimeId = _ruleContext.EndpointInfo.RuntimeInstanceCookie, @@ -199,11 +195,7 @@ private void EnsureDependencies() private void EnsureDependencies(CollectionRuleActionOptions options, int actionIndex) { - if (!_actionOperations.TryGetOptionsType(options.Type, out Type optionsType)) - { - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownActionType, options.Name)); - } - foreach (PropertyInfo property in GetDependencyPropertiesFromSettings(optionsType)) + foreach (PropertyInfo property in GetDependencyPropertiesFromSettings(options)) { string? originalValue = (string?)property.GetValue(options.Settings); if (string.IsNullOrEmpty(originalValue)) @@ -299,9 +291,9 @@ private bool GetActionResultReference(string actionReference, int actionIndex, return true; } - private static IEnumerable GetDependencyPropertiesFromSettings([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type optionsType) + private static IEnumerable GetDependencyPropertiesFromSettings(CollectionRuleActionOptions options) { - return ConfigurationTokenParser.GetPropertiesFromSettings(optionsType, p => p.GetCustomAttributes(typeof(ActionOptionsDependencyPropertyAttribute), inherit: true).Any()); + return ConfigurationTokenParser.GetPropertiesFromSettings(options.Settings, p => p.GetCustomAttributes(typeof(ActionOptionsDependencyPropertyAttribute), inherit: true).Any()); } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs index 813d37c38d2..e92f1510ff9 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs @@ -93,20 +93,5 @@ public bool TryValidateOptions( return false; } } - - /// - public bool TryGetOptionsType( - string actionName, - out Type optionsType) - { - if (_map.TryGetValue(actionName, out ICollectionRuleActionDescriptor descriptor)) - { - optionsType = descriptor.OptionsType; - return true; - } - - optionsType = null; - return false; - } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs index 405939ef02f..11cc5b7f616 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs @@ -41,13 +41,5 @@ bool TryValidateOptions( object options, ValidationContext validationContext, ICollection results); - - /// - /// Attempts to get the type of the options instance - /// associated with the registered action name. - /// - bool TryGetOptionsType( - string actionName, - out Type optionsType); } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs index 7010eac43f3..7bba676bd59 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLiveMetricsOptions.cs @@ -10,7 +10,6 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions { @@ -43,7 +42,6 @@ internal sealed partial record class CollectLiveMetricsOptions : BaseRecordOptio ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Duration))] [Range(typeof(TimeSpan), ActionOptionsConstants.Duration_MinValue, ActionOptionsConstants.Duration_MaxValue)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] [DefaultValue(CollectLiveMetricsOptionsDefaults.Duration)] public TimeSpan? Duration { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs index 147ebb29ddc..ed0a8ba62fb 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.cs @@ -12,7 +12,6 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions { @@ -47,7 +46,6 @@ internal sealed partial record class CollectLogsOptions : BaseRecordOptions, IEg ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Duration))] [Range(typeof(TimeSpan), ActionOptionsConstants.Duration_MinValue, ActionOptionsConstants.Duration_MaxValue)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] [DefaultValue(CollectLogsOptionsDefaults.Duration)] public TimeSpan? Duration { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs index 2491c12a88b..3a32d2a9460 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.cs @@ -11,7 +11,6 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions { @@ -52,7 +51,6 @@ internal sealed partial record class CollectTraceOptions : BaseRecordOptions, IE ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectArtifactOptions_Duration))] [Range(typeof(TimeSpan), ActionOptionsConstants.Duration_MinValue, ActionOptionsConstants.Duration_MaxValue)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] [DefaultValue(CollectTraceOptionsDefaults.Duration)] public TimeSpan? Duration { get; set; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs index 64096acc700..9f3e893be53 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsDefaultsOptions.cs @@ -4,7 +4,6 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using System; using System.ComponentModel.DataAnnotations; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options { @@ -20,14 +19,12 @@ internal sealed class CollectionRuleLimitsDefaultsOptions ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsDefaultsOptions_ActionCountSlidingWindowDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MinValue, CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MaxValue)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? ActionCountSlidingWindowDuration { get; set; } [Display( ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsDefaultsOptions_RuleDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.RuleDuration_MinValue, CollectionRuleOptionsConstants.RuleDuration_MaxValue)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? RuleDuration { get; set; } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs index 74d657ce290..d53f0f36051 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleLimitsOptions.cs @@ -5,7 +5,6 @@ using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options { @@ -25,14 +24,12 @@ internal sealed class CollectionRuleLimitsOptions ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsOptions_ActionCountSlidingWindowDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MinValue, CollectionRuleOptionsConstants.ActionCountSlidingWindowDuration_MaxValue)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? ActionCountSlidingWindowDuration { get; set; } [Display( ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleLimitsOptions_RuleDuration))] [Range(typeof(TimeSpan), CollectionRuleOptionsConstants.RuleDuration_MinValue, CollectionRuleOptionsConstants.RuleDuration_MaxValue)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? RuleDuration { get; set; } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs index 59b4b5e4ebc..ffe3e8d0467 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleTriggerDefaultsOptions.cs @@ -5,7 +5,6 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; using System; using System.ComponentModel.DataAnnotations; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options { @@ -27,7 +26,6 @@ internal sealed class CollectionRuleTriggerDefaultsOptions ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleTriggerDefaultsOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? SlidingWindowDuration { get; set; } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs index 973795d5bf7..75990365de3 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs @@ -8,7 +8,6 @@ using Microsoft.Extensions.Options; using System; using System.ComponentModel.DataAnnotations; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers { @@ -34,7 +33,6 @@ internal sealed partial class AspNetRequestCountOptions : ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestCountOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? SlidingWindowDuration { get; set; } // CONSIDER: Currently described that paths have to exactly match one item in the list. diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs index 3009fd19fd5..3ccf968de4f 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs @@ -9,7 +9,6 @@ using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers { @@ -39,14 +38,12 @@ internal sealed partial class AspNetRequestDurationOptions : Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_RequestDuration))] [DefaultValue(AspNetRequestDurationOptionsDefaults.RequestDuration)] [Range(typeof(TimeSpan), RequestDuration_MinValue, RequestDuration_MaxValue)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? RequestDuration { get; set; } [Display( ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetRequestDurationOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? SlidingWindowDuration { get; set; } // CONSIDER: Currently described that paths have to exactly match one item in the list. diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs index abeb51e0e87..16eb550b870 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs @@ -8,7 +8,6 @@ using Microsoft.Extensions.Options; using System; using System.ComponentModel.DataAnnotations; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers { @@ -29,7 +28,6 @@ internal sealed partial class AspNetResponseStatusOptions : Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_StatusCodes))] [Required] [MinLength(1)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Count of string property is preserved by DynamicDependency.")] [RegularExpressions(StatusCodesRegex, ErrorMessageResourceType = typeof(OptionsDisplayStrings), ErrorMessageResourceName = nameof(OptionsDisplayStrings.ErrorMessage_StatusCodesRegularExpressionDoesNotMatch))] @@ -50,7 +48,6 @@ internal sealed partial class AspNetResponseStatusOptions : ResourceType = typeof(OptionsDisplayStrings), Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_AspNetResponseStatusOptions_SlidingWindowDuration))] [Range(typeof(TimeSpan), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Addressed by DynamicDependency on ValidationHelper.TryValidateOptions method")] public TimeSpan? SlidingWindowDuration { get; set; } // CONSIDER: Currently described that paths have to exactly match one item in the list. diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs index 6b68b783c7e..9132dc98b9b 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs @@ -6,7 +6,6 @@ using Microsoft.Extensions.Options; using System; using System.ComponentModel.DataAnnotations; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers { @@ -42,7 +41,6 @@ internal sealed partial class EventCounterOptions : IValidateOptions results) { RequiredAttribute requiredAttribute = new(); diff --git a/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs b/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs index 5d14456b0c7..03e955be72f 100644 --- a/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs +++ b/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs @@ -49,7 +49,7 @@ public static void Invoke(OutputFormat output, TimeSpan expiration, TextWriter o Authentication = opts.Authentication, AuthorizationHeader = $"{AuthConstants.ApiKeySchema} {newJwt.Token}" // This is the actual format of the HTTP header and should not be localized }; - outputBldr.AppendLine(JsonSerializer.Serialize(result, MachineOutputFormatContext.Default.MachineOutputFormat)); + outputBldr.AppendLine(JsonSerializer.Serialize(result, result.GetType(), new JsonSerializerOptions() { WriteIndented = true })); } else { @@ -68,8 +68,7 @@ public static void Invoke(OutputFormat output, TimeSpan expiration, TextWriter o { // Create configuration from object model. MemoryConfigurationSource source = new(); - CommonOptionsMapper optionsMapper = new(); - source.InitialData = (IDictionary)optionsMapper.ToConfigurationValues(opts); // Cast the values as nullable, since they are reference types we can safely do this. + source.InitialData = (IDictionary)opts.ToConfigurationValues(); // Cast the values as nullable, since they are reference types we can safely do this. ConfigurationBuilder builder = new(); builder.Add(source); IConfigurationRoot configuration = builder.Build(); @@ -101,14 +100,11 @@ public static void Invoke(OutputFormat output, TimeSpan expiration, TextWriter o case OutputFormat.Cmd: case OutputFormat.PowerShell: case OutputFormat.Shell: + IDictionary optList = opts.ToEnvironmentConfiguration(); + foreach ((string name, string value) in optList) { - CommonOptionsMapper optionsMapper = new(); - IDictionary optList = optionsMapper.ToEnvironmentConfiguration(opts); - foreach ((string name, string value) in optList) - { - outputBldr.AppendFormat(CultureInfo.InvariantCulture, GetFormatString(output), name, value); - outputBldr.AppendLine(); - } + outputBldr.AppendFormat(CultureInfo.InvariantCulture, GetFormatString(output), name, value); + outputBldr.AppendLine(); } break; } @@ -150,10 +146,4 @@ internal class MachineOutputFormat public required string AuthorizationHeader { get; set; } } } - - [JsonSourceGenerationOptions(WriteIndented = true)] - [JsonSerializable(typeof(GenerateApiKeyCommandHandler.MachineOutputFormat))] - internal partial class MachineOutputFormatContext : JsonSerializerContext - { - } } diff --git a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs b/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs new file mode 100644 index 00000000000..286250c3d2f --- /dev/null +++ b/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs @@ -0,0 +1,156 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable enable + +#if UNITTEST +using Microsoft.Diagnostics.Monitoring.TestCommon; +#endif +using Microsoft.Extensions.Configuration; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace Microsoft.Diagnostics.Tools.Monitor +{ + internal static class CommonOptionsExtensions + { + private const string KeySegmentSeparator = "__"; + + /// + /// Generates a map of options that can be passed directly to configuration via an in-memory collection. + /// + /// + /// Each key is the configuration path; each value is the configuration path value. + /// + public static IDictionary ToConfigurationValues(this RootOptions options) + { + Dictionary variables = new(StringComparer.OrdinalIgnoreCase); + MapObject(options, string.Empty, ConfigurationPath.KeyDelimiter, variables); + return variables; + } + + /// + /// Generates an environment variable map of the options. + /// + /// + /// Each key is the variable name; each value is the variable value. + /// + public static IDictionary ToEnvironmentConfiguration(this RootOptions options, bool useDotnetMonitorPrefix = false) + { + Dictionary variables = new(StringComparer.OrdinalIgnoreCase); + MapObject(options, useDotnetMonitorPrefix ? ToolIdentifiers.StandardPrefix : string.Empty, KeySegmentSeparator, variables); + return variables; + } + + /// + /// Generates a key-per-file map of the options. + /// + /// + /// Each key is the file name; each value is the file content. + /// + public static IDictionary ToKeyPerFileConfiguration(this RootOptions options) + { + Dictionary variables = new(StringComparer.OrdinalIgnoreCase); + MapObject(options, string.Empty, KeySegmentSeparator, variables); + return variables; + } + + private static void MapDictionary(IDictionary dictionary, string prefix, string separator, IDictionary map) + { + foreach (var key in dictionary.Keys) + { + object? value = dictionary[key]; + + if (null != value) + { + string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); + MapValue( + value, + FormattableString.Invariant($"{prefix}{keyString}"), + separator, + map); + } + } + } + + private static void MapList(IList list, string prefix, string separator, IDictionary map) + { + for (int index = 0; index < list.Count; index++) + { + object? value = list[index]; + if (null != value) + { + MapValue( + value, + FormattableString.Invariant($"{prefix}{index}"), + separator, + map); + } + } + } + + private static void MapObject(object obj, string prefix, string separator, IDictionary map) + { + foreach (PropertyInfo property in obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) + { + if (!property.GetIndexParameters().Any()) + { + MapValue( + property.GetValue(obj), + FormattableString.Invariant($"{prefix}{property.Name}"), + separator, + map); + } + } + } + + private static void MapValue(object? value, string valueName, string separator, IDictionary map) + { + if (null != value) + { + Type valueType = value.GetType(); + if (valueType.IsPrimitive || + valueType.IsEnum || + typeof(Guid) == valueType || + typeof(string) == valueType || + typeof(TimeSpan) == valueType) + { + map.Add( + valueName, + ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); + } + else + { + string prefix = FormattableString.Invariant($"{valueName}{separator}"); + if (value is IDictionary dictionary) + { + MapDictionary(dictionary, prefix, separator, map); + } + else if (value is IList list) + { + MapList(list, prefix, separator, map); + } + else + { + MapObject(value, prefix, separator, map); + } + } + } + } + + private static string ToHexString(byte[] data) + { + StringBuilder builder = new(2 * data.Length); + foreach (byte b in data) + { + builder.Append(b.ToString("X2", CultureInfo.InvariantCulture)); + } + return builder.ToString(); + } + } +} \ No newline at end of file diff --git a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs b/src/Tools/dotnet-monitor/CommonOptionsMapper.cs deleted file mode 100644 index 5cc5fcaada7..00000000000 --- a/src/Tools/dotnet-monitor/CommonOptionsMapper.cs +++ /dev/null @@ -1,1182 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable enable - -#if UNITTEST -using Microsoft.Diagnostics.Monitoring.TestCommon; -#endif -using Microsoft.Diagnostics.Monitoring.Options; -using Microsoft.Diagnostics.Monitoring.WebApi; -using Microsoft.Diagnostics.Monitoring.WebApi.Models; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts; -using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Diagnostics.Tracing; -using System.Globalization; - -namespace Microsoft.Diagnostics.Tools.Monitor -{ - internal class CommonOptionsMapper - { - private const string KeySegmentSeparator = "__"; - - /// - /// Generates a map of options that can be passed directly to configuration via an in-memory collection. - /// - /// - /// Each key is the configuration path; each value is the configuration path value. - /// - public IDictionary ToConfigurationValues(RootOptions options) - { - Dictionary variables = new(StringComparer.OrdinalIgnoreCase); - MapRootOptions(options, string.Empty, ConfigurationPath.KeyDelimiter, variables); - return variables; - } - - /// - /// Generates an environment variable map of the options. - /// - /// - /// Each key is the variable name; each value is the variable value. - /// - public IDictionary ToEnvironmentConfiguration(RootOptions options, bool useDotnetMonitorPrefix = false) - { - Dictionary variables = new(StringComparer.OrdinalIgnoreCase); - MapRootOptions(options, useDotnetMonitorPrefix ? ToolIdentifiers.StandardPrefix : string.Empty, KeySegmentSeparator, variables); - return variables; - } - - /// - /// Generates a key-per-file map of the options. - /// - /// - /// Each key is the file name; each value is the file content. - /// - public IDictionary ToKeyPerFileConfiguration(RootOptions options) - { - Dictionary variables = new(StringComparer.OrdinalIgnoreCase); - MapRootOptions(options, string.Empty, KeySegmentSeparator, variables); - return variables; - } - - // private static void MapDictionary(IDictionary dictionary, string prefix, string separator, IDictionary map) - // { - // foreach (var key in dictionary.Keys) - // { - // object? value = dictionary[key]; - - // if (null != value) - // { - // string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); - // MapValue( - // value, - // FormattableString.Invariant($"{prefix}{keyString}"), - // separator, - // map); - // } - // } - // } - - // private static void MapList(IList list, string prefix, string separator, IDictionary map) - // { - // for (int index = 0; index < list.Count; index++) - // { - // object? value = list[index]; - // if (null != value) - // { - // MapValue( - // value, - // FormattableString.Invariant($"{prefix}{index}"), - // separator, - // map); - // } - // } - // } - - private void MapRootOptions(RootOptions obj, string prefix, string separator, IDictionary map) - { - // TODO: in Tests, it has an additional property. Weird. - MapAuthenticationOptions(obj.Authentication, FormattableString.Invariant($"{prefix}{nameof(obj.Authentication)}"), separator, map); - MapDictionary_String_CollectionRuleOptions(obj.CollectionRules, FormattableString.Invariant($"{prefix}{nameof(obj.CollectionRules)}"), separator, map); - MapGlobalCounterOptions(obj.GlobalCounter, FormattableString.Invariant($"{prefix}{nameof(obj.GlobalCounter)}"), separator, map); - MapInProcessFeaturesOptions(obj.InProcessFeatures, FormattableString.Invariant($"{prefix}{nameof(obj.InProcessFeatures)}"), separator, map); - // CorsConfigurationOptions - MapDiagnosticPortOptions(obj.DiagnosticPort, FormattableString.Invariant($"{prefix}{nameof(obj.DiagnosticPort)}"), separator, map); - MapEgressOptions(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), separator, map); - MapMetricsOptions(obj.Metrics, FormattableString.Invariant($"{prefix}{nameof(obj.Metrics)}"), separator, map); - MapStorageOptions(obj.Storage, FormattableString.Invariant($"{prefix}{nameof(obj.Storage)}"), separator, map); - // ProcessFilterOptions - MapCollectionRuleDefaultsOptions(obj.CollectionRuleDefaults, FormattableString.Invariant($"{prefix}{nameof(obj.CollectionRuleDefaults)}"), separator, map); - // Templates - // DotnetMonitorDebugOptions - // FOR TESTS: Logging? - } - - // private static void MapObject<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>(object obj, string prefix, string separator, IDictionary map) - // { - // foreach (PropertyInfo property in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)) - // { - // if (!property.GetIndexParameters().Any()) - // { - // MapValue( - // property.GetValue(obj), - // FormattableString.Invariant($"{prefix}{property.Name}"), - // separator, - // map); - // } - // } - // } - - private void MapDictionary_String_CollectionRuleOptions(IDictionary? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - var prefix = FormattableString.Invariant($"{valueName}{separator}"); // passed to mapdictionary. - foreach ((string key, CollectionRuleOptions value) in obj) - { - string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); - MapCollectionRuleOptions(value, FormattableString.Invariant($"{prefix}{keyString}"), separator, map); - } - } - } - - private void MapCollectionRuleOptions(CollectionRuleOptions obj, string valueName, string separator, IDictionary map) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapFilters(obj.Filters, FormattableString.Invariant($"{prefix}{nameof(obj.Filters)}"), separator, map); - MapCollectionRuleTriggerOptions(obj.Trigger, FormattableString.Invariant($"{prefix}{nameof(obj.Trigger)}"), separator, map); - MapActions(obj.Actions, FormattableString.Invariant($"{prefix}{nameof(obj.Actions)}"), separator, map); - MapLimits(obj.Limits, FormattableString.Invariant($"{prefix}{nameof(obj.Limits)}"), separator, map); - } - - private void MapActions(List obj, string valueName, string separator, IDictionary map) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - for (int index = 0; index < obj.Count; index++) - { - CollectionRuleActionOptions value = obj[index]; - MapCollectionRuleActionOptions(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); - } - } - - private void MapCollectionRuleActionOptions(CollectionRuleActionOptions obj, string valueName, string separator, IDictionary map) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Name, FormattableString.Invariant($"{prefix}{nameof(obj.Name)}"), map); - MapString(obj.Type, FormattableString.Invariant($"{prefix}{nameof(obj.Type)}"), map); - MapCollectionRuleActionOptions_Settings(obj.Type, obj.Settings, FormattableString.Invariant($"{prefix}{nameof(obj.Settings)}"), separator, map); - MapBool(obj.WaitForCompletion, FormattableString.Invariant($"{prefix}{nameof(obj.WaitForCompletion)}"), map); - } - - private Dictionary>>? _actionSettingsMap; - - public void AddActionSettings(string type, Action> mapAction) - { - (_actionSettingsMap ??= new()).Add(type, (obj, valueName, separator, map) => - { - mapAction((TSettings)obj, valueName, separator, map); - }); - } - - private void MapCollectionRuleActionOptions_Settings(string type, object? settings, string valueName, string separator, IDictionary map) - { - if (null != settings) - { - // TODO: inline the well-known ones to avoid a dictionary lookup. - switch (type) - { - case KnownCollectionRuleActions.CollectDump: - MapCollectDumpOptions(settings as CollectDumpOptions, valueName, separator, map); - break; - case KnownCollectionRuleActions.CollectExceptions: - MapCollectExceptionsOptions(settings as CollectExceptionsOptions, valueName, separator, map); - break; - case KnownCollectionRuleActions.CollectGCDump: - MapCollectGCDumpOptions(settings as CollectGCDumpOptions, valueName, separator, map); - break; - case KnownCollectionRuleActions.CollectLiveMetrics: - MapCollectLiveMetricsOptions(settings as CollectLiveMetricsOptions, valueName, separator, map); - break; - case KnownCollectionRuleActions.CollectLogs: - MapCollectLogsOptions(settings as CollectLogsOptions, valueName, separator, map); - break; - case KnownCollectionRuleActions.CollectStacks: - MapCollectStacksOptions(settings as CollectStacksOptions, valueName, separator, map); - break; - case KnownCollectionRuleActions.CollectTrace: - MapCollectTraceOptions(settings as CollectTraceOptions, valueName, separator, map); - break; - case KnownCollectionRuleActions.Execute: - MapExecuteOptions(settings as ExecuteOptions, valueName, separator, map); - break; - case KnownCollectionRuleActions.LoadProfiler: - MapLoadProfilerOptions(settings as LoadProfilerOptions, valueName, separator, map); - break; - case KnownCollectionRuleActions.SetEnvironmentVariable: - MapSetEnvironmentVariableOptions(settings as SetEnvironmentVariableOptions, valueName, separator, map); - break; - case KnownCollectionRuleActions.GetEnvironmentVariable: - MapGetEnvironmentVariableOptions(settings as GetEnvironmentVariableOptions, valueName, separator, map); - break; - default: - if (_actionSettingsMap?.TryGetValue(type, out Action>? mapAction) == true) - { - mapAction(settings, valueName, separator, map); - } - else - { - throw new NotSupportedException($"Unknown action type: {type}"); - } - break; - } - } - } - - private static void MapLimits(CollectionRuleLimitsOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapInt(obj.ActionCount, FormattableString.Invariant($"{prefix}{nameof(obj.ActionCount)}"), map); - MapTimeSpan(obj.ActionCountSlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.ActionCountSlidingWindowDuration)}"), map); - MapTimeSpan(obj.RuleDuration, FormattableString.Invariant($"{prefix}{nameof(obj.RuleDuration)}"), map); - } - } - - private static void MapCollectDumpOptions(CollectDumpOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapDumpType(obj.Type, FormattableString.Invariant($"{prefix}{nameof(obj.Type)}"), map); - MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); - MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); - } - } - - private static void MapCollectExceptionsOptions(CollectExceptionsOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); - MapExceptionFormat(obj.Format, FormattableString.Invariant($"{prefix}{nameof(obj.Format)}"), map); - MapExceptionsConfiguration(obj.Filters, FormattableString.Invariant($"{prefix}{nameof(obj.Filters)}"), separator, map); - MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); - } - } - - private static void MapExceptionFormat(ExceptionFormat? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapExceptionsConfiguration(ExceptionsConfiguration? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapList_ExceptionFilter(obj.Include, FormattableString.Invariant($"{prefix}{nameof(obj.Include)}"), separator, map); - MapList_ExceptionFilter(obj.Exclude, FormattableString.Invariant($"{prefix}{nameof(obj.Exclude)}"), separator, map); - } - } - - private static void MapList_ExceptionFilter(List? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - for (int index = 0; index < obj.Count; index++) - { - ExceptionFilter value = obj[index]; - MapExceptionFilter(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); - } - } - } - - private static void MapExceptionFilter(ExceptionFilter obj, string valueName, string separator, IDictionary map) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.ExceptionType, FormattableString.Invariant($"{prefix}{nameof(obj.ExceptionType)}"), map); - MapString(obj.ModuleName, FormattableString.Invariant($"{prefix}{nameof(obj.ModuleName)}"), map); - MapString(obj.TypeName, FormattableString.Invariant($"{prefix}{nameof(obj.TypeName)}"), map); - MapString(obj.MethodName, FormattableString.Invariant($"{prefix}{nameof(obj.MethodName)}"), map); - } - - private static void MapCollectGCDumpOptions(CollectGCDumpOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); - MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); - } - } - - private static void MapCollectLiveMetricsOptions(CollectLiveMetricsOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapBool(obj.IncludeDefaultProviders, FormattableString.Invariant($"{prefix}{nameof(obj.IncludeDefaultProviders)}"), map); - MapArray_EventMetricsProvider(obj.Providers, FormattableString.Invariant($"{prefix}{nameof(obj.Providers)}"), separator, map); - MapArray_EventMetricsMeter(obj.Meters, FormattableString.Invariant($"{prefix}{nameof(obj.Meters)}"), separator, map); - MapTimeSpan(obj.Duration, FormattableString.Invariant($"{prefix}{nameof(obj.Duration)}"), map); - MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); - MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); - } - } - - private static void MapArray_EventMetricsProvider(EventMetricsProvider[]? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - for (int index = 0; index < obj.Length; index++) - { - EventMetricsProvider value = obj[index]; - MapEventMetricsProvider(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); - } - } - } - - private static void MapEventMetricsProvider(EventMetricsProvider obj, string valueName, string separator, IDictionary map) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.ProviderName, FormattableString.Invariant($"{prefix}{nameof(obj.ProviderName)}"), map); - MapArray_String(obj.CounterNames, FormattableString.Invariant($"{prefix}{nameof(obj.CounterNames)}"), separator, map); - } - - static void MapCollectLogsOptions(CollectLogsOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapLogLevel(obj.DefaultLevel, FormattableString.Invariant($"{prefix}{nameof(obj.DefaultLevel)}"), map); - MapDictionary_String_LogLevel(obj.FilterSpecs, FormattableString.Invariant($"{prefix}{nameof(obj.FilterSpecs)}"), separator, map); - MapBool(obj.UseAppFilters, FormattableString.Invariant($"{prefix}{nameof(obj.UseAppFilters)}"), map); - MapTimeSpan(obj.Duration, FormattableString.Invariant($"{prefix}{nameof(obj.Duration)}"), map); - MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); - MapLogFormat(obj.Format, FormattableString.Invariant($"{prefix}{nameof(obj.Format)}"), map); - MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); - } - } - - static void MapLogLevel(LogLevel? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - static void MapDictionary_String_LogLevel(IDictionary? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - foreach ((string key, LogLevel? value) in obj) - { - string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); - MapLogLevel(value, FormattableString.Invariant($"{prefix}{keyString}"), map); - } - } - } - - static void MapLogFormat(LogFormat? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapArray_String(string[]? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - for (int index = 0; index < obj.Length; index++) - { - string value = obj[index]; - MapString(value, FormattableString.Invariant($"{prefix}{index}"), map); - } - } - } - - private static void MapArray_EventMetricsMeter(EventMetricsMeter[]? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - for (int index = 0; index < obj.Length; index++) - { - EventMetricsMeter value = obj[index]; - MapEventMetricsMeter(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); - } - } - } - - private static void MapEventMetricsMeter(EventMetricsMeter obj, string valueName, string separator, IDictionary map) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.MeterName, FormattableString.Invariant($"{prefix}{nameof(obj.MeterName)}"), map); - MapArray_String(obj.InstrumentNames, FormattableString.Invariant($"{prefix}{nameof(obj.InstrumentNames)}"), separator, map); - } - - private static void MapCollectStacksOptions(CollectStacksOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); - MapCallStackFormat(obj.Format, FormattableString.Invariant($"{prefix}{nameof(obj.Format)}"), map); - MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); - } - } - - private static void MapCallStackFormat(CallStackFormat? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapCollectTraceOptions(CollectTraceOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapTraceProfile(obj.Profile, FormattableString.Invariant($"{prefix}{nameof(obj.Profile)}"), map); - MapEventProviders(obj.Providers, FormattableString.Invariant($"{prefix}{nameof(obj.Providers)}"), separator, map); - MapBool(obj.RequestRundown, FormattableString.Invariant($"{prefix}{nameof(obj.RequestRundown)}"), map); - MapInt(obj.BufferSizeMegabytes, FormattableString.Invariant($"{prefix}{nameof(obj.BufferSizeMegabytes)}"), map); - MapTimeSpan(obj.Duration, FormattableString.Invariant($"{prefix}{nameof(obj.Duration)}"), map); - MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); - MapTraceEventFilter(obj.StoppingEvent, FormattableString.Invariant($"{prefix}{nameof(obj.StoppingEvent)}"), separator, map); - MapString(obj.ArtifactName, FormattableString.Invariant($"{prefix}{nameof(obj.ArtifactName)}"), map); - } - } - - private static void MapExecuteOptions(ExecuteOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Path, FormattableString.Invariant($"{prefix}{nameof(obj.Path)}"), map); - MapString(obj.Arguments, FormattableString.Invariant($"{prefix}{nameof(obj.Arguments)}"), map); - MapBool(obj.IgnoreExitCode, FormattableString.Invariant($"{prefix}{nameof(obj.IgnoreExitCode)}"), map); - } - } - - private static void MapLoadProfilerOptions(LoadProfilerOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Path, FormattableString.Invariant($"{prefix}{nameof(obj.Path)}"), map); - MapGuid(obj.Clsid, FormattableString.Invariant($"{prefix}{nameof(obj.Clsid)}"), map); - } - } - - private static void MapGuid(Guid? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapSetEnvironmentVariableOptions(SetEnvironmentVariableOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Name, FormattableString.Invariant($"{prefix}{nameof(obj.Name)}"), map); - MapString(obj.Value, FormattableString.Invariant($"{prefix}{nameof(obj.Value)}"), map); - } - } - - private static void MapGetEnvironmentVariableOptions(GetEnvironmentVariableOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Name, FormattableString.Invariant($"{prefix}{nameof(obj.Name)}"), map); - } - } - - private static void MapTraceProfile(TraceProfile? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapEventProviders(List? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - for (int index = 0; index < obj.Count; index++) - { - EventPipeProvider value = obj[index]; - MapEventPipeProvider(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); - } - } - } - - private static void MapEventPipeProvider(EventPipeProvider obj, string valueName, string separator, IDictionary map) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Name, FormattableString.Invariant($"{prefix}{nameof(obj.Name)}"), map); - MapString(obj.Keywords, FormattableString.Invariant($"{prefix}{nameof(obj.Keywords)}"), map); - MapEventLevel(obj.EventLevel, FormattableString.Invariant($"{prefix}{nameof(obj.EventLevel)}"), map); - MapDictionary_String_String(obj.Arguments, FormattableString.Invariant($"{prefix}{nameof(obj.Arguments)}"), separator, map); - } - - private static void MapEventLevel(EventLevel? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapTimeSpan(TimeSpan? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapTraceEventFilter(TraceEventFilter? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.ProviderName, FormattableString.Invariant($"{prefix}{nameof(obj.ProviderName)}"), map); - MapString(obj.EventName, FormattableString.Invariant($"{prefix}{nameof(obj.EventName)}"), map); - MapDictionary_String_String(obj.PayloadFilter, FormattableString.Invariant($"{prefix}{nameof(obj.PayloadFilter)}"), separator, map); - } - } - - private static void MapDictionary_String_String(IDictionary? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - foreach ((string key, string value) in obj) - { - string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); - MapString(value, FormattableString.Invariant($"{prefix}{keyString}"), map); - } - } - } - - private static void MapDumpType(DumpType? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapFilters(List? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - for (int index = 0; index < obj.Count; index++) - { - ProcessFilterDescriptor value = obj[index]; - MapProcessFilterDescriptor(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); - } - } - } - - private static void MapProcessFilterDescriptor(ProcessFilterDescriptor obj, string valueName, string separator, IDictionary map) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapProcessFilterKey(obj.Key, FormattableString.Invariant($"{prefix}{nameof(obj.Key)}"), map); - MapString(obj.Value, FormattableString.Invariant($"{prefix}{nameof(obj.Value)}"), map); - MapProcessFilterType(obj.MatchType, FormattableString.Invariant($"{prefix}{nameof(obj.MatchType)}"), map); - MapString(obj.ProcessName, FormattableString.Invariant($"{prefix}{nameof(obj.ProcessName)}"), map); - MapString(obj.ProcessId, FormattableString.Invariant($"{prefix}{nameof(obj.ProcessId)}"), map); - MapString(obj.CommandLine, FormattableString.Invariant($"{prefix}{nameof(obj.CommandLine)}"), map); - MapString(obj.ManagedEntryPointAssemblyName, FormattableString.Invariant($"{prefix}{nameof(obj.ManagedEntryPointAssemblyName)}"), map); - } - - private static void MapProcessFilterKey(ProcessFilterKey? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapProcessFilterType(ProcessFilterType? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapCollectionRuleTriggerOptions(CollectionRuleTriggerOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Type, FormattableString.Invariant($"{prefix}{nameof(obj.Type)}"), map); - MapCollectionRuleTriggerOptions_Settings(obj.Type, obj.Settings, FormattableString.Invariant($"{prefix}{nameof(obj.Settings)}"), separator, map); - } - } - - private static void MapCollectionRuleTriggerOptions_Settings(string type, object? settings, string valueName, string separator, IDictionary map) - { - if (null != settings) - { - switch (type) - { - case KnownCollectionRuleTriggers.AspNetRequestCount: - MapAspNetRequestCountOptions(settings as AspNetRequestCountOptions, valueName, separator, map); - break; - case KnownCollectionRuleTriggers.AspNetRequestDuration: - MapAspNetRequestDurationOptions(settings as AspNetRequestDurationOptions, valueName, separator, map); - break; - case KnownCollectionRuleTriggers.AspNetResponseStatus: - MapAspNetResponseStatusOptions(settings as AspNetResponseStatusOptions, valueName, separator, map); - break; - case KnownCollectionRuleTriggers.EventCounter: - MapEventCounterOptions(settings as EventCounterOptions, valueName, separator, map); - break; - case KnownCollectionRuleTriggers.CPUUsage: - MapCPUUsageOptions(settings as CPUUsageOptions, valueName, separator, map); - break; - case KnownCollectionRuleTriggers.GCHeapSize: - MapGCHeapSizeOptions(settings as GCHeapSizeOptions, valueName, separator, map); - break; - case KnownCollectionRuleTriggers.ThreadpoolQueueLength: - MapThreadpoolQueueLengthOptions(settings as ThreadpoolQueueLengthOptions, valueName, separator, map); - break; - case KnownCollectionRuleTriggers.EventMeter: - MapEventMeterOptions(settings as EventMeterOptions, valueName, separator, map); - break; - default: - throw new NotSupportedException($"Unknown trigger type: {type}"); - } - } - } - - private static void MapAspNetRequestCountOptions(AspNetRequestCountOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapInt(obj.RequestCount, FormattableString.Invariant($"{prefix}{nameof(obj.RequestCount)}"), map); - MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); - MapArray_String(obj.IncludePaths, FormattableString.Invariant($"{prefix}{nameof(obj.IncludePaths)}"), separator, map); - MapArray_String(obj.ExcludePaths, FormattableString.Invariant($"{prefix}{nameof(obj.ExcludePaths)}"), separator, map); - } - } - - private static void MapAspNetRequestDurationOptions(AspNetRequestDurationOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapInt(obj.RequestCount, FormattableString.Invariant($"{prefix}{nameof(obj.RequestCount)}"), map); - MapTimeSpan(obj.RequestDuration, FormattableString.Invariant($"{prefix}{nameof(obj.RequestDuration)}"), map); - MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); - MapArray_String(obj.IncludePaths, FormattableString.Invariant($"{prefix}{nameof(obj.IncludePaths)}"), separator, map); - MapArray_String(obj.ExcludePaths, FormattableString.Invariant($"{prefix}{nameof(obj.ExcludePaths)}"), separator, map); - } - } - - private static void MapAspNetResponseStatusOptions(AspNetResponseStatusOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapArray_String(obj.StatusCodes, FormattableString.Invariant($"{prefix}{nameof(obj.StatusCodes)}"), separator, map); - MapInt(obj.ResponseCount, FormattableString.Invariant($"{prefix}{nameof(obj.ResponseCount)}"), map); - MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); - MapArray_String(obj.IncludePaths, FormattableString.Invariant($"{prefix}{nameof(obj.IncludePaths)}"), separator, map); - MapArray_String(obj.ExcludePaths, FormattableString.Invariant($"{prefix}{nameof(obj.ExcludePaths)}"), separator, map); - } - } - - private static void MapEventCounterOptions(EventCounterOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.ProviderName, FormattableString.Invariant($"{prefix}{nameof(obj.ProviderName)}"), map); - MapString(obj.CounterName, FormattableString.Invariant($"{prefix}{nameof(obj.CounterName)}"), map); - MapDouble(obj.GreaterThan, FormattableString.Invariant($"{prefix}{nameof(obj.GreaterThan)}"), map); - MapDouble(obj.LessThan, FormattableString.Invariant($"{prefix}{nameof(obj.LessThan)}"), map); - MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); - } - } - - private static void MapCPUUsageOptions(CPUUsageOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapDouble(obj.GreaterThan, FormattableString.Invariant($"{prefix}{nameof(obj.GreaterThan)}"), map); - MapDouble(obj.LessThan, FormattableString.Invariant($"{prefix}{nameof(obj.LessThan)}"), map); - MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); - } - } - - private static void MapGCHeapSizeOptions(GCHeapSizeOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapDouble(obj.GreaterThan, FormattableString.Invariant($"{prefix}{nameof(obj.GreaterThan)}"), map); - MapDouble(obj.LessThan, FormattableString.Invariant($"{prefix}{nameof(obj.LessThan)}"), map); - MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); - } - } - - private static void MapThreadpoolQueueLengthOptions(ThreadpoolQueueLengthOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapDouble(obj.GreaterThan, FormattableString.Invariant($"{prefix}{nameof(obj.GreaterThan)}"), map); - MapDouble(obj.LessThan, FormattableString.Invariant($"{prefix}{nameof(obj.LessThan)}"), map); - MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); - } - } - - private static void MapEventMeterOptions(EventMeterOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.MeterName, FormattableString.Invariant($"{prefix}{nameof(obj.MeterName)}"), map); - MapString(obj.InstrumentName, FormattableString.Invariant($"{prefix}{nameof(obj.InstrumentName)}"), map); - MapDouble(obj.GreaterThan, FormattableString.Invariant($"{prefix}{nameof(obj.GreaterThan)}"), map); - MapDouble(obj.LessThan, FormattableString.Invariant($"{prefix}{nameof(obj.LessThan)}"), map); - MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); - MapInt(obj.HistogramPercentile, FormattableString.Invariant($"{prefix}{nameof(obj.HistogramPercentile)}"), map); - } - } - - private static void MapDouble(double? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapAuthenticationOptions(AuthenticationOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapMonitorApiKeyOptions(obj.MonitorApiKey, FormattableString.Invariant($"{prefix}{nameof(obj.MonitorApiKey)}"), separator, map); - MapAzureAdOptions(obj.AzureAd, FormattableString.Invariant($"{prefix}{nameof(obj.AzureAd)}"), separator, map); - } - } - - private static void MapMonitorApiKeyOptions(MonitorApiKeyOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Subject, FormattableString.Invariant($"{prefix}{nameof(obj.Subject)}"), map); - MapString(obj.PublicKey, FormattableString.Invariant($"{prefix}{nameof(obj.PublicKey)}"), map); - MapString(obj.Issuer, FormattableString.Invariant($"{prefix}{nameof(obj.Issuer)}"), map); - } - } - - private static void MapAzureAdOptions(AzureAdOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapUri(obj.Instance, FormattableString.Invariant($"{prefix}{nameof(obj.Instance)}"), separator, map); - MapString(obj.TenantId, FormattableString.Invariant($"{prefix}{nameof(obj.TenantId)}"), map); - MapString(obj.ClientId, FormattableString.Invariant($"{prefix}{nameof(obj.ClientId)}"), map); - MapUri(obj.AppIdUri, FormattableString.Invariant($"{prefix}{nameof(obj.AppIdUri)}"), separator, map); - MapString(obj.RequiredRole, FormattableString.Invariant($"{prefix}{nameof(obj.RequiredRole)}"), map); - } - } - - private static void MapUri(Uri? value, string valueName, string separator, IDictionary map) - { - if (null != value) - { - // TODO! - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(value.AbsolutePath, FormattableString.Invariant($"{prefix}{nameof(value.AbsolutePath)}"), map); - MapString(value.AbsoluteUri, FormattableString.Invariant($"{prefix}{nameof(value.AbsoluteUri)}"), map); - MapString(value.Authority, FormattableString.Invariant($"{prefix}{nameof(value.Authority)}"), map); - MapString(value.DnsSafeHost, FormattableString.Invariant($"{prefix}{nameof(value.DnsSafeHost)}"), map); - MapString(value.Fragment, FormattableString.Invariant($"{prefix}{nameof(value.Fragment)}"), map); - MapString(value.Host, FormattableString.Invariant($"{prefix}{nameof(value.Host)}"), map); - // MapHostNameType() - MapString(value.IdnHost, FormattableString.Invariant($"{prefix}{nameof(value.IdnHost)}"), map); - // MapBool(value.IsAbsoluteUri, FormattableString.Invariant($"{prefix}{nameof(value.IsAbsoluteUri)}"), map); - // MapBool(value.IsDefaultPort, FormattableString.Invariant($"{prefix}{nameof(value.IsDefaultPort)}"), map); - // MapBool(value.IsFile, FormattableString.Invariant($"{prefix}{nameof(value.IsFile)}"), map); - // MapBool(value.IsLoopback, FormattableString.Invariant($"{prefix}{nameof(value.IsLoopback)}"), map); - // MapBool(value.IsUnc, FormattableString.Invariant($"{prefix}{nameof(value.IsUnc)}"), map); - MapString(value.LocalPath, FormattableString.Invariant($"{prefix}{nameof(value.LocalPath)}"), map); - MapString(value.OriginalString, FormattableString.Invariant($"{prefix}{nameof(value.OriginalString)}"), map); - MapString(value.PathAndQuery, FormattableString.Invariant($"{prefix}{nameof(value.PathAndQuery)}"), map); - // MapInt(value.Port, FormattableString.Invariant($"{prefix}{nameof(value.Port)}"), map); - MapString(value.Query, FormattableString.Invariant($"{prefix}{nameof(value.Query)}"), map); - MapString(value.Scheme, FormattableString.Invariant($"{prefix}{nameof(value.Scheme)}"), map); - // MapStringArray(value.Segments, FormattableString.Invariant($"{prefix}{nameof(value.Segments)}"), separator, map); - // MapBool(value.UserEscaped, FormattableString.Invariant($"{prefix}{nameof(value.UserEscaped)}"), map); - MapString(value.UserInfo, FormattableString.Invariant($"{prefix}{nameof(value.UserInfo)}"), map); - } - } - - private static void MapGlobalCounterOptions(GlobalCounterOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapFloat(obj.IntervalSeconds, FormattableString.Invariant($"{prefix}{nameof(obj.IntervalSeconds)}"), map); - MapInt(obj.MaxHistograms, FormattableString.Invariant($"{prefix}{nameof(obj.MaxHistograms)}"), map); - MapInt(obj.MaxTimeSeries, FormattableString.Invariant($"{prefix}{nameof(obj.MaxTimeSeries)}"), map); - MapDictionary_String_GlobalProviderOptions(obj.Providers, FormattableString.Invariant($"{prefix}{nameof(obj.Providers)}"), separator, map); - } - } - - private static void MapDictionary_String_GlobalProviderOptions(IDictionary? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - foreach ((string key, GlobalProviderOptions value) in obj) - { - string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); - MapGlobalProviderOptions(value, FormattableString.Invariant($"{prefix}{keyString}"), separator, map); - } - } - } - - private static void MapGlobalProviderOptions(GlobalProviderOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapFloat(obj.IntervalSeconds, FormattableString.Invariant($"{prefix}{nameof(obj.IntervalSeconds)}"), map); - } - } - - private static void MapInProcessFeaturesOptions(InProcessFeaturesOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapBool(obj.Enabled, FormattableString.Invariant($"{prefix}{nameof(obj.Enabled)}"), map); - MapCallStacksOptions(obj.CallStacks, FormattableString.Invariant($"{prefix}{nameof(obj.CallStacks)}"), separator, map); - MapExceptionsOptions(obj.Exceptions, FormattableString.Invariant($"{prefix}{nameof(obj.Exceptions)}"), separator, map); - MapParameterCapturingOptions(obj.ParameterCapturing, FormattableString.Invariant($"{prefix}{nameof(obj.ParameterCapturing)}"), separator, map); - } - } - - private static void MapCallStacksOptions(CallStacksOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapBool(obj.Enabled, FormattableString.Invariant($"{prefix}{nameof(obj.Enabled)}"), map); - } - } - - private static void MapExceptionsOptions(ExceptionsOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapBool(obj.Enabled, FormattableString.Invariant($"{prefix}{nameof(obj.Enabled)}"), map); - MapInt(obj.TopLevelLimit, FormattableString.Invariant($"{prefix}{nameof(obj.TopLevelLimit)}"), map); - MapExceptionsConfiguration(obj.CollectionFilters, FormattableString.Invariant($"{prefix}{nameof(obj.CollectionFilters)}"), separator, map); - } - } - - private static void MapParameterCapturingOptions(ParameterCapturingOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapBool(obj.Enabled, FormattableString.Invariant($"{prefix}{nameof(obj.Enabled)}"), map); - } - } - - private static void MapDiagnosticPortOptions(DiagnosticPortOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapDiagnosticPortConnectionMode(obj.ConnectionMode, FormattableString.Invariant($"{prefix}{nameof(obj.ConnectionMode)}"), map); - MapString(obj.EndpointName, FormattableString.Invariant($"{prefix}{nameof(obj.EndpointName)}"), map); - MapInt(obj.MaxConnections, FormattableString.Invariant($"{prefix}{nameof(obj.MaxConnections)}"), map); - MapBool(obj.DeleteEndpointOnStartup, FormattableString.Invariant($"{prefix}{nameof(obj.DeleteEndpointOnStartup)}"), map); - } - } - - private static void MapDiagnosticPortConnectionMode(DiagnosticPortConnectionMode? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapEgressOptions(EgressOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapDictionary_String_FileSystemEgressProviderOptions(obj.FileSystem, FormattableString.Invariant($"{prefix}{nameof(obj.FileSystem)}"), separator, map); - MapDictionary_String_String(obj.Properties, FormattableString.Invariant($"{prefix}{nameof(obj.Properties)}"), separator, map); - } - } - - private static void MapDictionary_String_FileSystemEgressProviderOptions(IDictionary? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - foreach ((string key, FileSystemEgressProviderOptions value) in obj) - { - string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture); - MapFileSystemEgressProviderOptions(value, FormattableString.Invariant($"{prefix}{keyString}"), separator, map); - } - } - } - - private static void MapFileSystemEgressProviderOptions(FileSystemEgressProviderOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.DirectoryPath, FormattableString.Invariant($"{prefix}{nameof(obj.DirectoryPath)}"), map); - MapString(obj.IntermediateDirectoryPath, FormattableString.Invariant($"{prefix}{nameof(obj.IntermediateDirectoryPath)}"), map); - MapInt(obj.CopyBufferSize, FormattableString.Invariant($"{prefix}{nameof(obj.CopyBufferSize)}"), map); - } - } - - private static void MapMetricsOptions(MetricsOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapBool(obj.Enabled, FormattableString.Invariant($"{prefix}{nameof(obj.Enabled)}"), map); - MapString(obj.Endpoints, FormattableString.Invariant($"{prefix}{nameof(obj.Endpoints)}"), map); - MapInt(obj.MetricCount, FormattableString.Invariant($"{prefix}{nameof(obj.MetricCount)}"), map); - MapBool(obj.IncludeDefaultProviders, FormattableString.Invariant($"{prefix}{nameof(obj.IncludeDefaultProviders)}"), map); - MapList_MetricProvider(obj.Providers, FormattableString.Invariant($"{prefix}{nameof(obj.Providers)}"), separator, map); - MapList_MeterConfiguration(obj.Meters, FormattableString.Invariant($"{prefix}{nameof(obj.Meters)}"), separator, map); - } - } - - private static void MapList_MetricProvider(List? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - for (int index = 0; index < obj.Count; index++) - { - MetricProvider value = obj[index]; - MapMetricProvider(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); - } - } - } - - private static void MapMetricProvider(MetricProvider obj, string valueName, string separator, IDictionary map) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.ProviderName, FormattableString.Invariant($"{prefix}{nameof(obj.ProviderName)}"), map); - MapList_String(obj.CounterNames, FormattableString.Invariant($"{prefix}{nameof(obj.CounterNames)}"), separator, map); - } - - private static void MapList_String(List? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - for (int index = 0; index < obj.Count; index++) - { - string value = obj[index]; - MapString(value, FormattableString.Invariant($"{prefix}{index}"), map); - } - } - } - - private static void MapList_MeterConfiguration(List? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - for (int index = 0; index < obj.Count; index++) - { - MeterConfiguration value = obj[index]; - MapMeterConfiguration(value, FormattableString.Invariant($"{prefix}{index}"), separator, map); - } - } - } - - private static void MapMeterConfiguration(MeterConfiguration obj, string valueName, string separator, IDictionary map) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.MeterName, FormattableString.Invariant($"{prefix}{nameof(obj.MeterName)}"), map); - MapList_String(obj.InstrumentNames, FormattableString.Invariant($"{prefix}{nameof(obj.InstrumentNames)}"), separator, map); - } - - private static void MapStorageOptions(StorageOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.DefaultSharedPath, FormattableString.Invariant($"{prefix}{nameof(obj.DefaultSharedPath)}"), map); - MapString(obj.DumpTempFolder, FormattableString.Invariant($"{prefix}{nameof(obj.DumpTempFolder)}"), map); - MapString(obj.SharedLibraryPath, FormattableString.Invariant($"{prefix}{nameof(obj.SharedLibraryPath)}"), map); - } - } - - private static void MapCollectionRuleDefaultsOptions(CollectionRuleDefaultsOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapCollectionRuleTriggerDefaultsOptions(obj.Triggers, FormattableString.Invariant($"{prefix}{nameof(obj.Triggers)}"), separator, map); - MapCollectionRuleActionDefaultsOptions(obj.Actions, FormattableString.Invariant($"{prefix}{nameof(obj.Actions)}"), separator, map); - MapCollectionRuleLimitsDefaultsOptions(obj.Limits, FormattableString.Invariant($"{prefix}{nameof(obj.Limits)}"), separator, map); - } - } - - private static void MapCollectionRuleTriggerDefaultsOptions(CollectionRuleTriggerDefaultsOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapInt(obj.RequestCount, FormattableString.Invariant($"{prefix}{nameof(obj.RequestCount)}"), map); - MapInt(obj.ResponseCount, FormattableString.Invariant($"{prefix}{nameof(obj.ResponseCount)}"), map); - MapTimeSpan(obj.SlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.SlidingWindowDuration)}"), map); - } - } - - private static void MapCollectionRuleActionDefaultsOptions(CollectionRuleActionDefaultsOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapString(obj.Egress, FormattableString.Invariant($"{prefix}{nameof(obj.Egress)}"), map); - } - } - - private static void MapCollectionRuleLimitsDefaultsOptions(CollectionRuleLimitsDefaultsOptions? obj, string valueName, string separator, IDictionary map) - { - if (null != obj) - { - string prefix = FormattableString.Invariant($"{valueName}{separator}"); - MapInt(obj.ActionCount, FormattableString.Invariant($"{prefix}{nameof(obj.ActionCount)}"), map); - MapTimeSpan(obj.ActionCountSlidingWindowDuration, FormattableString.Invariant($"{prefix}{nameof(obj.ActionCountSlidingWindowDuration)}"), map); - MapTimeSpan(obj.RuleDuration, FormattableString.Invariant($"{prefix}{nameof(obj.RuleDuration)}"), map); - } - } - - private static void MapString(string? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapFloat(float? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapInt(int? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - private static void MapBool(bool? value, string valueName, IDictionary map) - { - if (null != value) - { - map.Add(valueName, ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - } - } - - // private static void MapValue(object? value, string valueName, string separator, IDictionary map) - // { - // if (null != value) - // { - // Type valueType = value.GetType(); - // if (valueType.IsPrimitive || - // valueType.IsEnum || - // typeof(Guid) == valueType || - // typeof(string) == valueType || - // typeof(TimeSpan) == valueType) - // { - // map.Add( - // valueName, - // ConvertUtils.ToString(value, CultureInfo.InvariantCulture)); - // } - // else - // { - // string prefix = FormattableString.Invariant($"{valueName}{separator}"); - // if (value is IDictionary dictionary) - // { - // MapDictionary(dictionary, prefix, separator, map); - // } - // else if (value is IList list) - // { - // MapList(list, prefix, separator, map); - // } - // else - // { - // MapObject(value, prefix, separator, map); - // } - // } - // } - // } - - // private static string ToHexString(byte[] data) - // { - // StringBuilder builder = new(2 * data.Length); - // foreach (byte b in data) - // { - // builder.Append(b.ToString("X2", CultureInfo.InvariantCulture)); - // } - // return builder.ToString(); - // } - } -} diff --git a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs index 16ff1eae159..327c256981b 100644 --- a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs +++ b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs @@ -64,12 +64,12 @@ public ConfigurationTokenParser(ILogger logger) _logger = logger; } - public object? SubstituteOptionValues(object? originalSettings, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type settingsType, TokenContext context) + public object? SubstituteOptionValues(object? originalSettings, TokenContext context) { object? settings = originalSettings; - foreach (PropertyInfo propertyInfo in GetPropertiesFromSettings(settingsType)) + foreach (PropertyInfo propertyInfo in GetPropertiesFromSettings(settings)) { string? originalPropertyValue = (string?)propertyInfo.GetValue(settings); if (string.IsNullOrEmpty(originalPropertyValue)) @@ -124,12 +124,11 @@ public bool TryCloneSettings(object? originalSettings, ref object? settings) return true; } - public static IEnumerable GetPropertiesFromSettings([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type, Predicate? predicate = null) - { - return type.GetProperties(BindingFlags.Public | BindingFlags.Instance) - .Where(p => p.PropertyType == typeof(string) && (predicate?.Invoke(p) ?? true)) - .ToArray(); - } + public static IEnumerable GetPropertiesFromSettings(object? settings, Predicate? predicate = null) => + settings?.GetType() + .GetProperties(BindingFlags.Public | BindingFlags.Instance) + .Where(p => p.PropertyType == typeof(string) && (predicate?.Invoke(p) ?? true)) ?? + Enumerable.Empty(); private static string CreateTokenReference(string category, string token) => FormattableString.Invariant($"{SubstitutionPrefix}{category}{Separator}{token}{SubstitutionSuffix}"); diff --git a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs index fe56dc95e1c..286e8959dc6 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs @@ -20,18 +20,16 @@ internal class OutputParser : IDisposable where TResult : class, IExten { private readonly ILogger _logger; private readonly TaskCompletionSource _resultCompletionSource; - private readonly JsonTypeInfo _jsonTypeInfo; private readonly EventWaitHandle _beginReadsHandle; private readonly Process _process; // We need to store the process ID for logging because we can't access it after the process exits private int _processId = -1; - public OutputParser(Process process, ILogger logger, JsonTypeInfo jsonTypeInfo) + public OutputParser(Process process, ILogger logger) { _process = process; _logger = logger; _resultCompletionSource = new TaskCompletionSource(); - _jsonTypeInfo = jsonTypeInfo; _beginReadsHandle = new EventWaitHandle(false, EventResetMode.AutoReset); _process.OutputDataReceived += ParseStdOut; @@ -71,7 +69,7 @@ private void ParseStdOut(object sender, DataReceivedEventArgs eventArgs) try { // Check if the object is a TResult - TResult result = JsonSerializer.Deserialize(eventArgs.Data, _jsonTypeInfo); + TResult result = JsonSerializer.Deserialize(eventArgs.Data); if (result.IsValid()) { _resultCompletionSource.TrySetResult(result); diff --git a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs index 622c21828cc..205044a9d7d 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs @@ -180,7 +180,7 @@ public async Task EgressArtifact( }; var parserLogger = mode == ExtensionMode.Execute ? _logger : NullLogger.Instance; - using OutputParser parser = new(p, parserLogger, EgressArtifactResultContext.Default.EgressArtifactResult); + using OutputParser parser = new(p, parserLogger); _logger.ExtensionStarting(_manifest.Name); if (!p.Start()) @@ -192,7 +192,7 @@ public async Task EgressArtifact( // p.StandardInput.BaseStream Format: Version (int), Payload Length (long), Payload, Artifact using Stream intermediateStream = new MemoryStream(); - await JsonSerializer.SerializeAsync(intermediateStream, payload, ExtensionEgressPayloadContext.Default.ExtensionEgressPayload, token); + await JsonSerializer.SerializeAsync(intermediateStream, payload, options: null, token); using (BinaryWriter writer = new BinaryWriter(p.StandardInput.BaseStream, Encoding.UTF8, leaveOpen: true)) { @@ -293,14 +293,4 @@ private Dictionary GetConfigurationSection(string providerName, return configAsDict; } } - - [JsonSerializable(typeof(EgressArtifactResult))] - partial class EgressArtifactResultContext : JsonSerializerContext - { - } - - [JsonSerializable(typeof(ExtensionEgressPayload))] - partial class ExtensionEgressPayloadContext : JsonSerializerContext - { - } } diff --git a/src/Tools/dotnet-monitor/Egress/Extension/ExtensionEgressPayload.cs b/src/Tools/dotnet-monitor/Egress/Extension/ExtensionEgressPayload.cs index 0bad8fa4e73..2cdc68dc933 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/ExtensionEgressPayload.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/ExtensionEgressPayload.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. + // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable disable @@ -15,7 +15,7 @@ internal sealed class ExtensionEgressPayload public IDictionary Properties { get; set; } public IDictionary Configuration { get; set; } public string ProviderName { get; set; } - [JsonConverter(typeof(JsonStringEnumConverter))] + [JsonConverter(typeof(JsonStringEnumConverter))] public LogLevel LogLevel { get; set; } } } diff --git a/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs b/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs index c5d87ce36a9..a8e3f209b2e 100644 --- a/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs +++ b/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs @@ -160,7 +160,7 @@ private async Task WriteJsonInstance(Stream stream, IExceptionInstance instance, }; } - await JsonSerializer.SerializeAsync(stream, model, ExceptionInstanceContext.Default.ExceptionInstance, cancellationToken: token); + await JsonSerializer.SerializeAsync(stream, model, cancellationToken: token); await stream.WriteAsync(JsonRecordDelimiter, token); } @@ -327,8 +327,4 @@ private static bool IncludeActivityId(IExceptionInstance instance) return !string.IsNullOrEmpty(instance.ActivityId); } } - - [JsonSerializable(typeof(Models.ExceptionInstance))] - partial class ExceptionInstanceContext : JsonSerializerContext{ - } } diff --git a/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs b/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs index 39190d80b54..faaab28ac3f 100644 --- a/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs +++ b/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs @@ -16,13 +16,13 @@ namespace Microsoft.Diagnostics.Tools.Monitor.Extensibility { - [JsonSerializable(typeof(ExtensionManifest))] - internal partial class ExtensionManifestContext : JsonSerializerContext - { - } - internal class ExtensionManifest : IValidatableObject { + private static readonly JsonSerializerOptions _serializerOptions = new() + { + Converters = { new JsonStringEnumConverter() } + }; + public const string DefaultFileName = "extension.json"; /// @@ -63,7 +63,7 @@ public static ExtensionManifest FromPath(string path) try { - return JsonSerializer.Deserialize(stream, ExtensionManifestContext.Default.ExtensionManifest); + return JsonSerializer.Deserialize(stream, _serializerOptions); } catch (JsonException ex) { diff --git a/src/Tools/dotnet-monitor/Extensibility/ExtensionMode.cs b/src/Tools/dotnet-monitor/Extensibility/ExtensionMode.cs index b023587a529..5a964518860 100644 --- a/src/Tools/dotnet-monitor/Extensibility/ExtensionMode.cs +++ b/src/Tools/dotnet-monitor/Extensibility/ExtensionMode.cs @@ -1,11 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Text.Json.Serialization; - namespace Microsoft.Diagnostics.Tools.Monitor.Extensibility { - [JsonConverter(typeof(JsonStringEnumConverter))] internal enum ExtensionMode { Execute, diff --git a/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs b/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs index 0024823d9d2..eea4de2f83e 100644 --- a/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs +++ b/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs @@ -115,6 +115,8 @@ public static IHostBuilder CreateHostBuilder(HostBuilderSettings settings) //is not added until WebHostDefaults are added. .ConfigureWebHostDefaults(webBuilder => { + TestAssemblies.AddHostingStartup(webBuilder); + // ASP.NET will initially create a configuration that primarily contains // the ASPNETCORE_* environment variables. This IWebHostBuilder configuration callback // is invoked before any of the usual configuration phases (host, app, service, container) diff --git a/src/Tools/dotnet-monitor/Program.cs b/src/Tools/dotnet-monitor/Program.cs index e8c2fff128e..2547446eba4 100644 --- a/src/Tools/dotnet-monitor/Program.cs +++ b/src/Tools/dotnet-monitor/Program.cs @@ -217,6 +217,8 @@ public static Task Main(string[] args) // Prevent child processes from inheriting startup hooks Environment.SetEnvironmentVariable(ToolIdentifiers.EnvironmentVariables.StartupHooks, null); + TestAssemblies.SimulateStartupHook(); + RootCommand root = new() { CollectCommand(), diff --git a/src/Tools/dotnet-monitor/Startup.cs b/src/Tools/dotnet-monitor/Startup.cs index f1009d4779a..e035dab1dcd 100644 --- a/src/Tools/dotnet-monitor/Startup.cs +++ b/src/Tools/dotnet-monitor/Startup.cs @@ -14,7 +14,6 @@ using System.IO.Compression; using System.Text.Json.Serialization; using System.Reflection; -using Microsoft.AspNetCore.Http.Validation.Generated; namespace Microsoft.Diagnostics.Tools.Monitor { @@ -32,7 +31,6 @@ public void ConfigureServices(IServiceCollection services) { services.ConfigureHttpJsonOptions(options => { options.SerializerOptions.Converters.Add(new JsonStringEnumConverter()); - options.SerializerOptions.TypeInfoResolverChain.Add(MonitorJsonSerializerContext.Default); }); services.Configure(options => diff --git a/src/Tools/dotnet-monitor/TestAssemblies.cs b/src/Tools/dotnet-monitor/TestAssemblies.cs index f90ae87eef7..c5e7d1cafa2 100644 --- a/src/Tools/dotnet-monitor/TestAssemblies.cs +++ b/src/Tools/dotnet-monitor/TestAssemblies.cs @@ -19,6 +19,31 @@ internal static class TestAssemblies { private const string ArtifactsDirectoryName = "artifacts"; private const string TestHostingStartupAssemblyName = "Microsoft.Diagnostics.Monitoring.Tool.TestHostingStartup"; + private const string TestStartupHookAssemblyName = "Microsoft.Diagnostics.Monitoring.Tool.TestStartupHook"; +#nullable disable + [Conditional("DEBUG")] + public static void SimulateStartupHook() + { + // This code is to aid loading the TestStartupHook assembly when debug launching dotnet-monitor + // so that additional manual configuration is not necessary. The functional tests already bootstrap + // loading this assembly and initialize the hosting startup using standard dotnet environment variables. + + AssemblyLoadContext alc = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()); + // Skip attempting to load if it is already loaded + if (!alc.Assemblies.Any(a => TestStartupHookAssemblyName.Equals(a.GetName().Name))) + { + // Only load if can compute the path correctly + if (TryComputeBuildOutputAssemblyPath(TestStartupHookAssemblyName, out string startupHookAssemblyPath)) + { + // Load and simulate startup hook initialization + Assembly startupHookAssembly = alc.LoadFromAssemblyPath(startupHookAssemblyPath); + Type startupHookType = startupHookAssembly.GetType("StartupHook"); + MethodInfo initializeMethod = startupHookType.GetMethod("Initialize", BindingFlags.Public | BindingFlags.Static); + initializeMethod.Invoke(null, Array.Empty()); + } + } + } +#nullable restore [Conditional("DEBUG")] public static void AddHostingStartup(IWebHostBuilder builder) diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index 75c3716eea3..90c47084913 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -27,7 +27,6 @@ namespace Microsoft.AspNetCore.Http.Validation.Generated file sealed class GeneratedValidatablePropertyInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatablePropertyInfo { public GeneratedValidatablePropertyInfo( - [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] global::System.Type containingType, global::System.Type propertyType, string name, @@ -37,7 +36,6 @@ public GeneratedValidatablePropertyInfo( Name = name; } - [global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] internal global::System.Type ContainingType { get; } internal string Name { get; } @@ -1563,9 +1561,7 @@ internal static class GeneratedServiceCollectionExtensions [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] file static class ValidationAttributeCache { - private sealed record CacheKey( - [property: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties| global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] - global::System.Type ContainingType, string PropertyName); + private sealed record CacheKey(global::System.Type ContainingType, string PropertyName); private static readonly global::System.Collections.Concurrent.ConcurrentDictionary _cache = new(); public static global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes( From f51eda2a14abbc0b7e2465ad1f945b70aea544c8 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 28 Apr 2025 22:03:04 +0000 Subject: [PATCH 158/174] Clean up projects --- src/Directory.Build.targets | 9 ++++ ...nostics.Monitoring.Extension.Common.csproj | 16 +------- ...soft.Diagnostics.Monitoring.Options.csproj | 21 +--------- .../CollectionRuleActions.UnitTests.csproj | 30 +------------- .../GenerateDotNetHost.targets | 10 +++++ ...t.Diagnostics.Monitoring.TestCommon.csproj | 7 +--- ...ics.Monitoring.Tool.FunctionalTests.csproj | 1 - ...tics.Monitoring.Tool.UnitTestCommon.csproj | 13 +----- ...agnostics.Monitoring.Tool.UnitTests.csproj | 11 ----- ...ics.Monitoring.Tool.UnitTestsSample.csproj | 19 --------- ....Diagnostics.Monitoring.UnitTestApp.csproj | 20 +-------- .../Auth/ApiKey/MonitorApiKeyPostConfigure.cs | 1 - .../ActionOptionsDependencyAnalyzer.cs | 1 - .../ICollectionRuleActionOperations.cs | 1 - .../CollectionRuleBindingHelper.cs | 4 -- ...CollectionRulePostConfigureNamedOptions.cs | 1 - .../Commands/CollectCommandHandler.cs | 1 - .../Commands/GenerateApiKeyCommandHandler.cs | 1 - .../ConfigurationTokenParser.cs | 4 -- .../Extension/EgressExtension.OutputParser.cs | 1 - .../Egress/Extension/EgressExtension.cs | 1 - .../Extension/EgressExtensionFactory.cs | 2 - .../Exceptions/ExceptionsOperation.cs | 1 - src/Tools/dotnet-monitor/ValidatableTypes.cs | 1 - .../dotnet-monitor/dotnet-monitor.csproj | 41 +------------------ 25 files changed, 28 insertions(+), 190 deletions(-) diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 5e5cbcab61e..633466b70f7 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -136,4 +136,13 @@ + + + + + + + diff --git a/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj b/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj index 85b1a8f36a7..54a3df6eb2a 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj +++ b/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj @@ -3,7 +3,7 @@ Library false - $(LatestTargetFramework) + $(ToolTargetFrameworks) $(DefineConstants);EXTENSION true true @@ -40,18 +40,4 @@ - - - - - - diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj b/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj index c3fb05d3ab0..57aa89bd71b 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj +++ b/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj @@ -1,6 +1,4 @@ - - - + + + $(IntermediateOutputPath)/$(TargetFramework)/TestDotNetHost.g.cs + $(MicrosoftNETCoreApp80Version) + $(MicrosoftNETCoreApp90Version) + $(MicrosoftNETCoreApp100Version) + $(MicrosoftAspNetCoreApp80Version) + $(MicrosoftAspNetCoreApp90Version) + $(MicrosoftAspNetCoreApp100Version) + + $([System.IO.File]::ReadAllText('TestDotNetHost.cs.template')) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Microsoft.Diagnostics.Monitoring.TestCommon.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Microsoft.Diagnostics.Monitoring.TestCommon.csproj index 2334234588c..7ebf9551f29 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Microsoft.Diagnostics.Monitoring.TestCommon.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.TestCommon/Microsoft.Diagnostics.Monitoring.TestCommon.csproj @@ -1,11 +1,8 @@ - - - + $(TestTargetFrameworks) $(DefineConstants);UNITTEST - false @@ -38,8 +35,6 @@ - - diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj index 546274c7a7c..32c177dd04b 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.csproj @@ -3,7 +3,6 @@ $(TestTargetFrameworks) $(DefineConstants);UNITTEST - $(NoWarn);NU1603 diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj index 57a98113d2d..5f0b9f3f651 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj @@ -3,7 +3,7 @@ $(ToolTargetFrameworks) true - true + true @@ -29,15 +29,4 @@ - - - - - - - - - - - diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj index 16f07d8a328..c0a65ed571a 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj @@ -185,15 +185,4 @@ - - - - - - - - - - - diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj index 45472d5924c..9e515f84c12 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj @@ -6,27 +6,8 @@ enable - - - - - - - - - - - diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Microsoft.Diagnostics.Monitoring.UnitTestApp.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Microsoft.Diagnostics.Monitoring.UnitTestApp.csproj index c3b4483e1b7..185ac82e527 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Microsoft.Diagnostics.Monitoring.UnitTestApp.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.UnitTestApp/Microsoft.Diagnostics.Monitoring.UnitTestApp.csproj @@ -1,6 +1,4 @@ - - - + Exe @@ -26,20 +24,4 @@ - - - - - - - - diff --git a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs index f3b3daf0846..0401c9e7bcc 100644 --- a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs +++ b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs @@ -12,7 +12,6 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; -using System.Threading; namespace Microsoft.Diagnostics.Tools.Monitor.Auth.ApiKey { diff --git a/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs b/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs index 3f167ef603b..1e43a50e044 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs @@ -7,7 +7,6 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Globalization; using System.Linq; using System.Reflection; using System.Text; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs index 11cc5b7f616..075f3195f0c 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/ICollectionRuleActionOperations.cs @@ -4,7 +4,6 @@ #nullable disable using Microsoft.Extensions.Configuration; -using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs index 5529fbc78fa..bcca3241d62 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs @@ -1,12 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Triggers; using Microsoft.Extensions.Configuration; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs index 6cdda996dde..06b48f77ac6 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs @@ -3,7 +3,6 @@ #nullable disable -using System; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; diff --git a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs index 69a6a3ffa4c..6a0ac020fe0 100644 --- a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs +++ b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.Auth; diff --git a/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs b/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs index 03e955be72f..a13b184fcdc 100644 --- a/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs +++ b/src/Tools/dotnet-monitor/Commands/GenerateApiKeyCommandHandler.cs @@ -12,7 +12,6 @@ using System.IO; using System.Text; using System.Text.Json; -using System.Text.Json.Serialization; namespace Microsoft.Diagnostics.Tools.Monitor.Commands { diff --git a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs index 327c256981b..dc7416e3023 100644 --- a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs +++ b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs @@ -1,14 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; diff --git a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs index 286e8959dc6..a95ab55d174 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.OutputParser.cs @@ -8,7 +8,6 @@ using System; using System.Diagnostics; using System.Text.Json; -using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; diff --git a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs index 205044a9d7d..aebb2074656 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs @@ -20,7 +20,6 @@ using System.Runtime.InteropServices; using System.Text; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; diff --git a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs index 0d1079a944b..eafe34882e3 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs @@ -2,11 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Tools.Monitor.Egress.Configuration; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; namespace Microsoft.Diagnostics.Tools.Monitor.Egress.Extension { diff --git a/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs b/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs index a8e3f209b2e..dacc9bc9049 100644 --- a/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs +++ b/src/Tools/dotnet-monitor/Exceptions/ExceptionsOperation.cs @@ -17,7 +17,6 @@ using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; using Models = Microsoft.Diagnostics.Monitoring.WebApi.Models; using NameFormatter = Microsoft.Diagnostics.Monitoring.WebApi.Stacks.NameFormatter; -using System.Text.Json.Serialization; namespace Microsoft.Diagnostics.Tools.Monitor.Exceptions { diff --git a/src/Tools/dotnet-monitor/ValidatableTypes.cs b/src/Tools/dotnet-monitor/ValidatableTypes.cs index 1e9e43246cf..334d2ed733b 100644 --- a/src/Tools/dotnet-monitor/ValidatableTypes.cs +++ b/src/Tools/dotnet-monitor/ValidatableTypes.cs @@ -5,7 +5,6 @@ using Microsoft.AspNetCore.Http.Validation.Generated; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; -using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; diff --git a/src/Tools/dotnet-monitor/dotnet-monitor.csproj b/src/Tools/dotnet-monitor/dotnet-monitor.csproj index 391f453db5a..8ae38588b22 100644 --- a/src/Tools/dotnet-monitor/dotnet-monitor.csproj +++ b/src/Tools/dotnet-monitor/dotnet-monitor.csproj @@ -1,6 +1,4 @@ - - - + $(ToolTargetFrameworks) @@ -12,17 +10,9 @@ false false enable - false - true - false - true + true $(InterceptorsNamespaces);Microsoft.AspNetCore.Http.Validation.Generated - $(NoWarn);IDE0005 - - - - $(NoWarn);NU1603 @@ -144,31 +134,4 @@ - - - - - - - - - - - - - - - - - From ad2e43080aef34f573e4f24d77f1c1adcc4e3116 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 28 Apr 2025 22:12:18 +0000 Subject: [PATCH 159/174] More cleanup --- src/Directory.Build.targets | 10 ---------- ...soft.Diagnostics.Monitoring.Extension.Common.csproj | 1 - .../Microsoft.Diagnostics.Monitoring.Options.csproj | 3 +-- .../Microsoft.Diagnostics.Monitoring.OpenApiGen.csproj | 2 -- .../ExtensionManifestTests.cs | 3 ++- ...rosoft.Diagnostics.Monitoring.Tool.UnitTests.csproj | 3 +-- .../Program.cs | 4 ++-- src/Tools/Directory.Build.props | 2 +- .../Auth/ApiKey/MonitorApiKeyPostConfigure.cs | 1 - src/Tools/dotnet-monitor/dotnet-monitor.csproj | 1 - 10 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 633466b70f7..f79f7d13d44 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -13,16 +13,6 @@ - - $(IntermediateOutputPath)/$(TargetFramework)/TestDotNetHost.g.cs - $(MicrosoftNETCoreApp80Version) - $(MicrosoftNETCoreApp90Version) - $(MicrosoftNETCoreApp100Version) - $(MicrosoftAspNetCoreApp80Version) - $(MicrosoftAspNetCoreApp90Version) - $(MicrosoftAspNetCoreApp100Version) - - diff --git a/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj b/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj index 54a3df6eb2a..e97b2a71018 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj +++ b/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj @@ -39,5 +39,4 @@ ResXFileCodeGenerator - diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj b/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj index 57aa89bd71b..5b3cf3c3805 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj +++ b/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj @@ -1,4 +1,4 @@ - + + true $(SignOnlyRuntimeIdentifiers) $(OutputPath) diff --git a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs index 0401c9e7bcc..b4bc75216e8 100644 --- a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs +++ b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs @@ -44,7 +44,6 @@ public void PostConfigure(string? name, MonitorApiKeyConfiguration options) List errors = new List(); - // If nothing is set, lets not attach an error and instead pass along the blank config if (sourceOptions.Subject == null && sourceOptions.PublicKey == null) { diff --git a/src/Tools/dotnet-monitor/dotnet-monitor.csproj b/src/Tools/dotnet-monitor/dotnet-monitor.csproj index 8ae38588b22..4856f2580db 100644 --- a/src/Tools/dotnet-monitor/dotnet-monitor.csproj +++ b/src/Tools/dotnet-monitor/dotnet-monitor.csproj @@ -1,5 +1,4 @@  - $(ToolTargetFrameworks) Microsoft.Diagnostics.Tools.Monitor From 0791d94eed10bd609c0a29b4dccb104b0c944ca4 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 28 Apr 2025 22:30:06 +0000 Subject: [PATCH 160/174] Revert more non-validation changes --- .../ActionDependencyAnalyzerTests.cs | 38 +++++++++---------- .../CollectionRules/ActionListExecutor.cs | 4 +- .../ActionOptionsDependencyAnalyzer.cs | 11 ++---- ...CollectionRulePostConfigureNamedOptions.cs | 3 +- .../Options/CollectionRuleOptions.Validate.cs | 6 +-- .../Options/CollectionRuleOptions.cs | 2 +- 6 files changed, 27 insertions(+), 37 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs index 0644ea01ab5..5e55d62eecf 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ActionDependencyAnalyzerTests.cs @@ -142,14 +142,14 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => [Fact] public async Task ProcessInfoTest() { - CollectionRuleActionOptions actionOptions = null; + PassThroughOptions settings = null; await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { CollectionRuleOptions options = rootOptions.CreateCollectionRule(DefaultRuleName) .AddPassThroughAction("a1", ConfigurationTokenParser.ProcessNameReference, ConfigurationTokenParser.ProcessIdReference, ConfigurationTokenParser.CommandLineReference) .SetStartupTrigger(); - actionOptions = options.Actions.Last(); + settings = (PassThroughOptions)options.Actions.Last().Settings; }, host => { using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TimeoutMs); @@ -157,7 +157,6 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => CollectionRuleOptions ruleOptions = host.Services.GetRequiredService>().Get(DefaultRuleName); ILogger logger = host.Services.GetRequiredService>(); TimeProvider timeProvider = host.Services.GetRequiredService(); - ICollectionRuleActionOperations actionOperations = host.Services.GetRequiredService(); const string processName = "actionProcess"; const int processId = 123; @@ -166,8 +165,8 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => Guid instanceId = Guid.NewGuid(); CollectionRuleContext context = new(DefaultRuleName, ruleOptions, new TestProcessInfo(instanceId, processId: processId, commandLine: commandLine), HostInfo.GetCurrent(timeProvider), logger); - ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context, actionOperations); - PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, actionOptions); + ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); + PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, settings); Assert.Equal(processName, newSettings.Input1); Assert.Equal(processId.ToString(CultureInfo.InvariantCulture), newSettings.Input2); @@ -182,14 +181,14 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => [Fact] public async Task HostInfoTest() { - CollectionRuleActionOptions actionOptions = null; + PassThroughOptions settings = null; await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { CollectionRuleOptions options = rootOptions.CreateCollectionRule(DefaultRuleName) .AddPassThroughAction("a1", ConfigurationTokenParser.HostNameReference, ConfigurationTokenParser.UnixTimeReference, "test") .SetStartupTrigger(); - actionOptions = options.Actions.Last(); + settings = (PassThroughOptions)options.Actions.Last().Settings; }, host => { using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TimeoutMs); @@ -197,15 +196,14 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => CollectionRuleOptions ruleOptions = host.Services.GetRequiredService>().Get(DefaultRuleName); ILogger logger = host.Services.GetRequiredService>(); MockTimeProvider timeProvider = host.Services.GetRequiredService() as MockTimeProvider; - ICollectionRuleActionOperations actionOperations = host.Services.GetRequiredService(); const string hostName = "exampleHost"; Guid instanceId = Guid.NewGuid(); HostInfo hostInfo = new HostInfo(hostName, timeProvider); CollectionRuleContext context = new(DefaultRuleName, ruleOptions, new TestProcessInfo(instanceId), hostInfo, logger); - ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context, actionOperations); - PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, actionOptions); + ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); + PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, settings); Assert.Equal(hostName, newSettings.Input1); Assert.Equal(hostInfo.TimeProvider.GetUtcNow().ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture), newSettings.Input2); @@ -225,7 +223,7 @@ public async Task InvalidTokenReferenceTest() string a2input3 = "$(Actions.a1.MissingResult)"; LogRecord record = new LogRecord(); - CollectionRuleActionOptions actionOptions = null; + PassThroughOptions settings = null; await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { CollectionRuleOptions options = rootOptions.CreateCollectionRule(DefaultRuleName) @@ -233,7 +231,7 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => .AddPassThroughAction("a2", a2input1, a2input2, a2input3) .SetStartupTrigger(); - actionOptions = options.Actions.Last(); + settings = (PassThroughOptions)options.Actions.Last().Settings; }, host => { using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TimeoutMs); @@ -241,14 +239,13 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => CollectionRuleOptions ruleOptions = host.Services.GetRequiredService>().Get(DefaultRuleName); ILogger logger = host.Services.GetRequiredService>(); TimeProvider timeProvider = host.Services.GetRequiredService(); - ICollectionRuleActionOperations actionOperations = host.Services.GetRequiredService(); Guid instanceId = Guid.NewGuid(); CollectionRuleContext context = new(DefaultRuleName, ruleOptions, new TestProcessInfo(instanceId), HostInfo.GetCurrent(timeProvider), logger); - ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context, actionOperations); + ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); analyzer.GetActionDependencies(1); - analyzer.SubstituteOptionValues(new Dictionary(), 1, actionOptions); + analyzer.SubstituteOptionValues(new Dictionary(), 1, settings); Assert.Equal(3, record.Events.Count); Assert.Equal(LoggingEventIds.InvalidActionReferenceToken.Id(), record.Events[0].EventId.Id); @@ -267,28 +264,27 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => [Fact] public async Task RuntimeIdReferenceTest() { - CollectionRuleActionOptions actionOptions = null; + PassThroughOptions settings = null; await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { CollectionRuleOptions options = rootOptions.CreateCollectionRule(DefaultRuleName) .AddPassThroughAction("a1", ConfigurationTokenParser.RuntimeIdReference, "test", "test") .SetStartupTrigger(); - actionOptions = options.Actions.Last(); - }, host => + settings = (PassThroughOptions)options.Actions.Last().Settings; + }, host => { using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TimeoutMs); CollectionRuleOptions ruleOptions = host.Services.GetRequiredService>().Get(DefaultRuleName); ILogger logger = host.Services.GetRequiredService>(); TimeProvider timeProvider = host.Services.GetRequiredService(); - ICollectionRuleActionOperations actionOperations = host.Services.GetRequiredService(); Guid instanceId = Guid.NewGuid(); CollectionRuleContext context = new(DefaultRuleName, ruleOptions, new TestProcessInfo(instanceId), HostInfo.GetCurrent(timeProvider), logger); - ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context, actionOperations); - PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, actionOptions); + ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); + PassThroughOptions newSettings = (PassThroughOptions)analyzer.SubstituteOptionValues(new Dictionary(), 1, settings); Assert.Equal(instanceId.ToString("D"), newSettings.Input1); diff --git a/src/Tools/dotnet-monitor/CollectionRules/ActionListExecutor.cs b/src/Tools/dotnet-monitor/CollectionRules/ActionListExecutor.cs index 00ed55d906c..bafe19a5390 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/ActionListExecutor.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/ActionListExecutor.cs @@ -49,7 +49,7 @@ public async Task> ExecuteAction List deferredCompletions = new(context.Options.Actions.Count); var actionResults = new Dictionary(StringComparer.Ordinal); - var dependencyAnalyzer = ActionOptionsDependencyAnalyzer.Create(context, _actionOperations); + var dependencyAnalyzer = ActionOptionsDependencyAnalyzer.Create(context); try { @@ -91,7 +91,7 @@ public async Task> ExecuteAction )); } - object? newSettings = dependencyAnalyzer.SubstituteOptionValues(actionResults, actionIndex, actionOption); + object? newSettings = dependencyAnalyzer.SubstituteOptionValues(actionResults, actionIndex, actionOption.Settings); ICollectionRuleAction? action = factory.Create(context.ProcessInfo, newSettings); try diff --git a/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs b/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs index 1e43a50e044..2efb134cf1f 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/ActionOptionsDependencyAnalyzer.cs @@ -34,7 +34,6 @@ internal sealed class ActionOptionsDependencyAnalyzer private readonly CollectionRuleContext _ruleContext; private readonly ConfigurationTokenParser _tokenParser; - private readonly ICollectionRuleActionOperations _actionOperations; //Use action index instead of name, since it's possible for an unnamed action to have named dependencies. #nullable disable @@ -78,18 +77,17 @@ public string GetActionResultToken() => string.Concat(ActionReferencePrefix, Action.Name, ConfigurationTokenParser.Separator, ResultName, ConfigurationTokenParser.SubstitutionSuffix); } - public static ActionOptionsDependencyAnalyzer Create(CollectionRuleContext context, ICollectionRuleActionOperations actionOperations) + public static ActionOptionsDependencyAnalyzer Create(CollectionRuleContext context) { - var analyzer = new ActionOptionsDependencyAnalyzer(context, new ConfigurationTokenParser(context.Logger), actionOperations); + var analyzer = new ActionOptionsDependencyAnalyzer(context, new ConfigurationTokenParser(context.Logger)); analyzer.EnsureDependencies(); return analyzer; } - private ActionOptionsDependencyAnalyzer(CollectionRuleContext context, ConfigurationTokenParser tokenParser, ICollectionRuleActionOperations actionOperations) + private ActionOptionsDependencyAnalyzer(CollectionRuleContext context, ConfigurationTokenParser tokenParser) { _ruleContext = context ?? throw new ArgumentNullException(nameof(context)); _tokenParser = tokenParser ?? throw new ArgumentNullException(nameof(tokenParser)); - _actionOperations = actionOperations ?? throw new ArgumentNullException(nameof(actionOperations)); } #nullable disable @@ -114,9 +112,8 @@ public IList GetActionDependencies(int actionIndex) } #nullable restore - public object? SubstituteOptionValues(IDictionary actionResults, int actionIndex, CollectionRuleActionOptions actionOptions) + public object? SubstituteOptionValues(IDictionary actionResults, int actionIndex, object? settings) { - object? settings = actionOptions.Settings; //Attempt to substitute context properties. object? originalSettings = settings; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs index 06b48f77ac6..2a4a0817113 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Globalization; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration @@ -132,7 +133,7 @@ private void ResolveLimits(CollectionRuleOptions ruleOptions, IConfigurationSect if (!templatesOptions.TryGetValue(templateKey, out templatesValue)) { templatesValue = new(); - ruleOptions.ErrorList.Add((string.Format(CultureInfo.CurrentCulture, Strings.ErrorMessage_TemplateNotFound, templateKey), memberName)); + ruleOptions.ErrorList.Add(new ValidationResult(string.Format(CultureInfo.CurrentCulture, Strings.ErrorMessage_TemplateNotFound, templateKey), [memberName])); return false; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs index 010f745ece2..84d91b56130 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs @@ -17,11 +17,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali List results = new(); // ErrorList is populated by incorrectly using templates - this will be empty if all templates names can be resolved or if templates are not used. - // results.AddRange(ErrorList); - foreach (var error in ErrorList) - { - results.Add(new ValidationResult(error.Error, [error.MemberName])); - } + results.AddRange(ErrorList); if (results.Count > 0) { diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs index 06ac0cb12ff..128848d3bd3 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.cs @@ -37,6 +37,6 @@ internal sealed partial class CollectionRuleOptions Description = nameof(OptionsDisplayStrings.DisplayAttributeDescription_CollectionRuleOptions_Limits))] public CollectionRuleLimitsOptions? Limits { get; set; } - internal List<(string Error, string MemberName)> ErrorList { get; } = new List<(string Error, string MemberName)>(); + internal List ErrorList { get; } = new List(); } } From b676215977728667a70af62bc1f2653f847d0e10 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 28 Apr 2025 23:03:42 +0000 Subject: [PATCH 161/174] Revert options validation changes --- .../Options/Actions/CollectExceptionsOptions.cs | 5 +---- .../Options/Triggers/AspNetRequestCountOptions.cs | 7 ++----- .../Options/Triggers/AspNetRequestDurationOptions.cs | 7 ++----- .../Options/Triggers/AspNetResponseStatusOptions.cs | 7 ++----- .../Options/Triggers/EventCounterOptions.cs | 4 +--- .../Triggers/EventCounterShortcuts/CPUUsageOptions.cs | 4 +--- .../Triggers/EventCounterShortcuts/GCHeapSizeOptions.cs | 4 +--- .../EventCounterShortcuts/ThreadpoolQueueLengthOptions.cs | 4 +--- .../CollectionRules/Options/Triggers/EventMeterOptions.cs | 4 +--- 9 files changed, 12 insertions(+), 34 deletions(-) diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs index 34ea08dc30b..6b21f1c8320 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs @@ -17,10 +17,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions [NJsonSchema.Annotations.JsonSchemaFlatten] #endif - internal sealed partial record class CollectExceptionsOptions : - BaseRecordOptions, - // IValidateOptions, - IEgressProviderProperties + internal sealed partial record class CollectExceptionsOptions : BaseRecordOptions, IEgressProviderProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs index 75990365de3..adb6868e8fa 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestCountOptions.cs @@ -5,7 +5,6 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; -using Microsoft.Extensions.Options; using System; using System.ComponentModel.DataAnnotations; @@ -14,10 +13,8 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers /// /// Options for the AspNetRequestCount trigger. /// - [OptionsValidator] - internal sealed partial class AspNetRequestCountOptions : - IAspNetActionPathFilters, ISlidingWindowDurationProperties, IRequestCountProperties, - IValidateOptions + internal sealed class AspNetRequestCountOptions : + IAspNetActionPathFilters, ISlidingWindowDurationProperties, IRequestCountProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs index 3ccf968de4f..1967a34f1f8 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetRequestDurationOptions.cs @@ -5,7 +5,6 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; -using Microsoft.Extensions.Options; using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; @@ -15,10 +14,8 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers /// /// Options for the AspNetRequestDuration trigger. /// - [OptionsValidator] - internal sealed partial class AspNetRequestDurationOptions : - IAspNetActionPathFilters, ISlidingWindowDurationProperties, IRequestCountProperties, - IValidateOptions + internal sealed class AspNetRequestDurationOptions : + IAspNetActionPathFilters, ISlidingWindowDurationProperties, IRequestCountProperties { public const string RequestDuration_MaxValue = "01:00:00"; public const string RequestDuration_MinValue = "00:00:00"; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs index 16eb550b870..9f998a007cf 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/AspNetResponseStatusOptions.cs @@ -5,7 +5,6 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; -using Microsoft.Extensions.Options; using System; using System.ComponentModel.DataAnnotations; @@ -14,10 +13,8 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers /// /// Options for the AspNetResponseStatus trigger. /// - [OptionsValidator] - internal sealed partial class AspNetResponseStatusOptions : - IAspNetActionPathFilters, ISlidingWindowDurationProperties, - IValidateOptions + internal sealed class AspNetResponseStatusOptions : + IAspNetActionPathFilters, ISlidingWindowDurationProperties { private const string StatusCodeRegex = "[1-5][0-9]{2}"; private const string StatusCodesRegex = StatusCodeRegex + "(-" + StatusCodeRegex + ")?"; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs index 9132dc98b9b..3c02bcd03cf 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.cs @@ -3,7 +3,6 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; -using Microsoft.Extensions.Options; using System; using System.ComponentModel.DataAnnotations; @@ -12,8 +11,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers /// /// Options for the EventCounter trigger. /// - [OptionsValidator] - internal sealed partial class EventCounterOptions : IValidateOptions, ISlidingWindowDurationProperties + internal sealed partial class EventCounterOptions : ISlidingWindowDurationProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs index 3ba654e1faf..59878ace042 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/CPUUsageOptions.cs @@ -3,7 +3,6 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; -using Microsoft.Extensions.Options; using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; @@ -13,8 +12,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.E /// /// Options for the CPUUsage trigger. /// - [OptionsValidator] - internal sealed partial class CPUUsageOptions : IValidateOptions, IEventCounterShortcuts, ISlidingWindowDurationProperties + internal sealed partial class CPUUsageOptions : IEventCounterShortcuts, ISlidingWindowDurationProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/GCHeapSizeOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/GCHeapSizeOptions.cs index 47884db3875..1411ea183d0 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/GCHeapSizeOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/GCHeapSizeOptions.cs @@ -3,7 +3,6 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; -using Microsoft.Extensions.Options; using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; @@ -13,8 +12,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.E /// /// Options for the GCHeapSize trigger. /// - [OptionsValidator] - internal sealed partial class GCHeapSizeOptions : IValidateOptions, IEventCounterShortcuts, ISlidingWindowDurationProperties + internal sealed partial class GCHeapSizeOptions : IEventCounterShortcuts, ISlidingWindowDurationProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/ThreadpoolQueueLengthOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/ThreadpoolQueueLengthOptions.cs index 050430a47d8..6d42e99a1b8 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/ThreadpoolQueueLengthOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/ThreadpoolQueueLengthOptions.cs @@ -3,7 +3,6 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; -using Microsoft.Extensions.Options; using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; @@ -13,8 +12,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.E /// /// Options for the ThreadpoolQueueLength trigger. /// - [OptionsValidator] - internal sealed partial class ThreadpoolQueueLengthOptions : IValidateOptions, IEventCounterShortcuts, ISlidingWindowDurationProperties + internal sealed partial class ThreadpoolQueueLengthOptions : IEventCounterShortcuts, ISlidingWindowDurationProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.cs index e5224657f01..cc22561940f 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.cs @@ -3,7 +3,6 @@ using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsInterfaces; -using Microsoft.Extensions.Options; using System; using System.ComponentModel.DataAnnotations; @@ -12,8 +11,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers /// /// Options for the EventMeter trigger. /// - [OptionsValidator] - internal sealed partial class EventMeterOptions : IValidateOptions, ISlidingWindowDurationProperties + internal sealed partial class EventMeterOptions : ISlidingWindowDurationProperties { [Display( ResourceType = typeof(OptionsDisplayStrings), From 92b9104a1dd9e4e57040e946475d5c2a0b440b8d Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 28 Apr 2025 23:03:52 +0000 Subject: [PATCH 162/174] More cleanup --- ...nostics.Monitoring.Extension.Common.csproj | 2 ++ ...soft.Diagnostics.Monitoring.Options.csproj | 1 - ...tics.Monitoring.ConfigurationSchema.csproj | 1 + .../TestValidatableType.cs | 4 --- .../CollectionRuleDescriptionPipelineTests.cs | 1 - .../ExtensionManifestTests.cs | 1 - ...ics.Monitoring.Tool.UnitTestsSample.csproj | 2 +- .../Auth/ApiKey/MonitorApiKeyPostConfigure.cs | 7 ++++- .../Actions/CollectExceptionsAction.cs | 9 +------ .../CollectionRuleBindingHelper.cs | 27 ------------------- .../Actions/CollectExceptionsOptions.cs | 1 - .../Actions/CollectTraceOptions.Validate.cs | 2 -- .../Options/CollectionRuleOptions.Validate.cs | 17 +----------- .../Options/ValidationHelper.cs | 5 ++-- .../dotnet-monitor/CommonOptionsExtensions.cs | 4 +-- .../ConfigurationTokenParser.cs | 1 - .../DataAnnotationValidateOptions.cs | 6 +---- .../DynamicNamedOptionsCache.cs | 2 +- .../Extension/ExtensionEgressPayload.cs | 2 +- .../EndpointInfo/ServerEndpointInfoSource.cs | 1 + .../OpenApi/OpenApiOptionsExtensions.cs | 1 + ...FailureContentTypesOperationTransformer.cs | 1 + src/Tools/dotnet-monitor/RootOptions.cs | 1 + 23 files changed, 24 insertions(+), 75 deletions(-) diff --git a/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj b/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj index e97b2a71018..f9ada28f3cc 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj +++ b/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj @@ -21,6 +21,8 @@ + + diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj b/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj index 5b3cf3c3805..f11b2d63e0e 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj +++ b/src/Microsoft.Diagnostics.Monitoring.Options/Microsoft.Diagnostics.Monitoring.Options.csproj @@ -39,5 +39,4 @@ PublicResXFileCodeGenerator - \ No newline at end of file diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj index 5252a66798e..2ec74e69f6c 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.ConfigurationSchema/Microsoft.Diagnostics.Monitoring.ConfigurationSchema.csproj @@ -76,6 +76,7 @@ + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs index b21f9deddfb..f2b2bd4ead0 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs @@ -7,10 +7,6 @@ namespace Microsoft.Diagnostics.Monitoring.TestCommon { - // The Validation source generator doesn't run for libraries that don't call AddValidation, - // so we can't generate IValidatableInfo by using [ValidatableType] directly on types defined - // in ProjectReferences. This is a workaround to force the generator running in this project to - // generate IValidatableInfo for the referenced types. The containing class is not used otherwise. [ValidatableType] internal sealed class TestValidatableTypes { diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs index 585a788847f..895306ea951 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleDescriptionPipelineTests.cs @@ -7,7 +7,6 @@ using Microsoft.Diagnostics.Monitoring.Tool.UnitTests.CollectionRules.Triggers; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; -using Strings = Microsoft.Diagnostics.Monitoring.WebApi.Strings; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Extensions.DependencyInjection; diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs index f02998bf488..1dd630b3384 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs @@ -179,7 +179,6 @@ public void ExtensionManifest_NameAndAssembly_Valid() Assert.Equal(ExpectedAssemblyName, manifest.AssemblyFileName); Assert.Null(manifest.ExecutableFileName); - var validationOptions = _fixture.Services.GetRequiredService>().Value; manifest.Validate(_fixture.Services, validationOptions); } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj index 9e515f84c12..6b94db64edf 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj @@ -1,7 +1,7 @@ - net10.0 + $(ToolTargetFrameworks) enable enable diff --git a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs index b4bc75216e8..1746ba63581 100644 --- a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs +++ b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs @@ -56,7 +56,12 @@ public void PostConfigure(string? name, MonitorApiKeyConfiguration options) // Some options are configured (but may not be valid) options.Configured = true; - ValidationHelper.TryValidateObject(sourceOptions, typeof(MonitorApiKeyOptions), _validationOptions, _serviceProvider, errors); + ValidationHelper.TryValidateObject( + sourceOptions, + typeof(MonitorApiKeyOptions), + _validationOptions, + _serviceProvider, + errors); string? jwkJson = null; try diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs index 3d8e3516d87..54d507def57 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs @@ -10,8 +10,6 @@ using Microsoft.Extensions.Options; using Microsoft.Extensions.Configuration; using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions @@ -34,12 +32,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectExceptionsO throw new ArgumentNullException(nameof(options)); } - List result = new(); - if (!ValidationHelper.TryValidateObject(options, typeof(CollectExceptionsOptions), _validationOptions, _serviceProvider, result)) - { - throw new ValidationException( - string.Join(Environment.NewLine, result.ConvertAll(r => r.ErrorMessage))); - } + ValidationHelper.ValidateObject(options, typeof(CollectExceptionsOptions), _validationOptions, _serviceProvider); return new CollectExceptionsAction(processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs index bcca3241d62..7e4ec3aca29 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRuleBindingHelper.cs @@ -10,33 +10,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration { internal static class CollectionRuleBindingHelper { - // public static object CreateActionSettings( - // string actionType, - // Func collectDump, - // Func collectExceptions - // ) => actionType switch { - // KnownCollectionRuleActions.CollectDump => collectDump(), - // KnownCollectionRuleActions.CollectExceptions => collectExceptions(), - // _ => throw new ArgumentException($"Unknown action type: {actionType}", nameof(actionType)) - // }; - - // public static object NewActionSettings(string actionType) => - // actionType switch { - // KnownCollectionRuleActions.CollectDump => new CollectDumpOptions(), - // KnownCollectionRuleActions.CollectExceptions => new CollectExceptionsOptions(), - // _ => null - // }; - - // public static Action SelectAction( - // string actionType, - // Action collectDump, - // Action collectExceptions - // ) => actionType switch { - // KnownCollectionRuleActions.CollectDump => collectDump, - // KnownCollectionRuleActions.CollectExceptions => collectExceptions, - // }; - - public static void BindActionSettings(IConfigurationSection actionSection, CollectionRuleActionOptions actionOptions, ICollectionRuleActionOperations actionOperations) { if (null != actionOptions && diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs index 6b21f1c8320..c9913707cf4 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.cs @@ -16,7 +16,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions #if SCHEMAGEN [NJsonSchema.Annotations.JsonSchemaFlatten] #endif - internal sealed partial record class CollectExceptionsOptions : BaseRecordOptions, IEgressProviderProperties { [Display( diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs index 8878daa5470..70f4601c622 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs @@ -91,8 +91,6 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali ValidationContext providerContext = new(provider, nameof(Providers), validationContext, validationContext.Items); providerContext.MemberName = nameof(Providers) + "[" + index.ToString(CultureInfo.InvariantCulture) + "]"; - // Note: generated validation logic doesn't recurse into members of T for List, when List is not required. - // Need to do the recursion ourselves. var validationOptions = validationContext.GetRequiredService>().Value; ValidationHelper.TryValidateObject(provider, typeof(EventPipeProvider), validationOptions, providerContext, results); diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs index 84d91b56130..52ec0082a67 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs @@ -24,21 +24,6 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali return results; } - // ValidationContext filtersContext = new(Filters, validationContext, validationContext.Items); - // filtersContext.MemberName = nameof(Filters); - // ValidationHelper.TryValidateItems(Filters, filtersContext, results); - - // if (null != Trigger) - // { - // ValidationContext triggerContext = new(Trigger, validationContext, validationContext.Items); - // triggerContext.MemberName = nameof(Trigger); - // Validator.TryValidateObject(Trigger, triggerContext, results); - // } - - // ValidationContext actionsContext = new(Actions, validationContext, validationContext.Items); - // actionsContext.MemberName = nameof(Actions); - // ValidationHelper.TryValidateItems(Actions, actionsContext, results); - var actionNames = new HashSet(StringComparer.Ordinal); foreach (CollectionRuleActionOptions option in Actions) { @@ -53,4 +38,4 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali return results; } } -} \ No newline at end of file +} diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs index a197698808f..c6fd02c9f80 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs @@ -98,9 +98,10 @@ public static bool TryValidateObject(object options, Type type, ValidationOption public static void ValidateObject(object options, Type type, ValidationOptions validationOptions, IServiceProvider serviceProvider) { - if (!TryValidateObject(options, type, validationOptions, serviceProvider, new List())) + List results = new(); + if (!TryValidateObject(options, type, validationOptions, serviceProvider, results)) { - throw new ValidationException("Validation failed for " + type.FullName); + throw new ValidationException(string.Join(Environment.NewLine, results.ConvertAll(r => r.ErrorMessage))); } } } diff --git a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs b/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs index 286250c3d2f..718ffa4f27a 100644 --- a/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/CommonOptionsExtensions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable enable @@ -153,4 +153,4 @@ private static string ToHexString(byte[] data) return builder.ToString(); } } -} \ No newline at end of file +} diff --git a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs index dc7416e3023..a672c46b097 100644 --- a/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs +++ b/src/Tools/dotnet-monitor/ConfigurationTokenParser.cs @@ -64,7 +64,6 @@ public ConfigurationTokenParser(ILogger logger) { object? settings = originalSettings; - foreach (PropertyInfo propertyInfo in GetPropertiesFromSettings(settings)) { string? originalPropertyValue = (string?)propertyInfo.GetValue(settings); diff --git a/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs b/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs index 22c70745dc4..56c1583a83c 100644 --- a/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs +++ b/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs @@ -35,11 +35,7 @@ public DataAnnotationValidateOptions(IServiceProvider serviceProvider) public ValidateOptionsResult Validate(string? name, TOptions options) { var results = new List(); - var typeName = typeof(TOptions).Name; - var validationContext = new ValidationContext(options, typeName, _serviceProvider, items: null) { - MemberName = typeName - }; - if (!ValidationHelper.TryValidateObject(options, typeof(TOptions), _validationOptions, validationContext, results)) + if (!ValidationHelper.TryValidateObject(options, typeof(TOptions), _validationOptions, _serviceProvider, results)) { IList failures = new List(); foreach (ValidationResult result in results) diff --git a/src/Tools/dotnet-monitor/DynamicNamedOptionsCache.cs b/src/Tools/dotnet-monitor/DynamicNamedOptionsCache.cs index a56f1badc22..8efbcff1595 100644 --- a/src/Tools/dotnet-monitor/DynamicNamedOptionsCache.cs +++ b/src/Tools/dotnet-monitor/DynamicNamedOptionsCache.cs @@ -20,7 +20,7 @@ namespace Microsoft.Diagnostics.Tools.Monitor /// internal sealed class DynamicNamedOptionsCache : OptionsCache - where TOptions : class, new() + where TOptions : class { public override TOptions GetOrAdd(string name, Func createOptions) { diff --git a/src/Tools/dotnet-monitor/Egress/Extension/ExtensionEgressPayload.cs b/src/Tools/dotnet-monitor/Egress/Extension/ExtensionEgressPayload.cs index 2cdc68dc933..429ee50a786 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/ExtensionEgressPayload.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/ExtensionEgressPayload.cs @@ -1,4 +1,4 @@ - // Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable disable diff --git a/src/Tools/dotnet-monitor/EndpointInfo/ServerEndpointInfoSource.cs b/src/Tools/dotnet-monitor/EndpointInfo/ServerEndpointInfoSource.cs index bd063845848..4e9f9a17e8d 100644 --- a/src/Tools/dotnet-monitor/EndpointInfo/ServerEndpointInfoSource.cs +++ b/src/Tools/dotnet-monitor/EndpointInfo/ServerEndpointInfoSource.cs @@ -184,6 +184,7 @@ private async Task ListenAsync(ReversedDiagnosticsServer server, CancellationTok try { IpcEndpointInfo info = await server.AcceptAsync(token).ConfigureAwait(false); + _ = Task.Run(async () => { try diff --git a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs index 2b488129b22..967c1a5ebac 100644 --- a/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs +++ b/src/Tools/dotnet-monitor/OpenApi/OpenApiOptionsExtensions.cs @@ -119,6 +119,7 @@ public static void ConfigureMonitorOpenApiGen(this OpenApiOptions options) { includeSchema.Type |= JsonSchemaType.Null; } + if (schema.Properties["exclude"] is OpenApiSchema excludeSchema) { excludeSchema.Type |= JsonSchemaType.Null; diff --git a/src/Tools/dotnet-monitor/OpenApi/Transformers/RemoveFailureContentTypesOperationTransformer.cs b/src/Tools/dotnet-monitor/OpenApi/Transformers/RemoveFailureContentTypesOperationTransformer.cs index d37ac936df9..a7398e2dd7a 100644 --- a/src/Tools/dotnet-monitor/OpenApi/Transformers/RemoveFailureContentTypesOperationTransformer.cs +++ b/src/Tools/dotnet-monitor/OpenApi/Transformers/RemoveFailureContentTypesOperationTransformer.cs @@ -28,6 +28,7 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform } } } + return Task.CompletedTask; } } diff --git a/src/Tools/dotnet-monitor/RootOptions.cs b/src/Tools/dotnet-monitor/RootOptions.cs index 3ee1691a5da..f3a42b42575 100644 --- a/src/Tools/dotnet-monitor/RootOptions.cs +++ b/src/Tools/dotnet-monitor/RootOptions.cs @@ -38,5 +38,6 @@ internal sealed partial class RootOptions public TemplateOptions? Templates { get; set; } public DotnetMonitorDebugOptions? DotnetMonitorDebug { get; set; } + } } From eefe4b217762d63f019de429b53015c19abb4725 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 29 Apr 2025 00:00:40 +0000 Subject: [PATCH 163/174] Simplify custom type info --- .../dotnet-monitor/CustomValidationInfo.cs | 111 ++++++------------ 1 file changed, 35 insertions(+), 76 deletions(-) diff --git a/src/Tools/dotnet-monitor/CustomValidationInfo.cs b/src/Tools/dotnet-monitor/CustomValidationInfo.cs index e06f4e5e510..546dbdb4c22 100644 --- a/src/Tools/dotnet-monitor/CustomValidationInfo.cs +++ b/src/Tools/dotnet-monitor/CustomValidationInfo.cs @@ -23,7 +23,7 @@ public bool TryGetValidatableTypeInfo(Type type, [NotNullWhen(true)] out IValida { if (type == typeof(CollectionRuleOptions)) { - validatableInfo = CreateCollectionRuleOptions(); + validatableInfo = new CollectionRuleOptionsTypeInfo(); return true; } @@ -37,49 +37,42 @@ public bool TryGetValidatableParameterInfo(ParameterInfo parameterInfo, [NotNull return false; } - private static ValidatableTypeInfo CreateCollectionRuleOptions() + sealed class CollectionRuleOptionsTypeInfo : ValidatableTypeInfo { - return new ShortCircuitingValidatableTypeInfo( - type: typeof(CollectionRuleOptions), - members: [ - new CustomValidatablePropertyInfo( - containingType: typeof(CollectionRuleOptions), - propertyType: typeof(CollectionRuleTriggerOptions), - name: "Trigger", - displayName: "Trigger" - ), - new CustomValidatablePropertyInfo( - containingType: typeof(CollectionRuleOptions), - propertyType: typeof(List), - name: "Actions", - displayName: "Actions" - ), - new CustomValidatablePropertyInfo( - containingType: typeof(CollectionRuleOptions), - propertyType: typeof(CollectionRuleLimitsOptions), - name: "Limits", - displayName: "Limits" - ), - ] - ); - } + public CollectionRuleOptionsTypeInfo() + : this( + [ + new CustomValidatablePropertyInfo( + containingType: typeof(CollectionRuleOptions), + propertyType: typeof(CollectionRuleTriggerOptions), + name: "Trigger", + displayName: "Trigger" + ), + new CustomValidatablePropertyInfo( + containingType: typeof(CollectionRuleOptions), + propertyType: typeof(List), + name: "Actions", + displayName: "Actions" + ), + new CustomValidatablePropertyInfo( + containingType: typeof(CollectionRuleOptions), + propertyType: typeof(CollectionRuleLimitsOptions), + name: "Limits", + displayName: "Limits" + ) + ]) + { + } - sealed class ShortCircuitingValidatableTypeInfo : ValidatableTypeInfo - { - public ShortCircuitingValidatableTypeInfo( - [param: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] - Type type, - ValidatablePropertyInfo[] members) : base(type, members) { - Type = type; + private CollectionRuleOptionsTypeInfo(ValidatablePropertyInfo[] members) + : base(typeof(CollectionRuleOptions), members) + { Members = members; _membersCount = members.Length; - _subTypes = type.GetAllImplementedTypes(); } private readonly int _membersCount; - private readonly List _subTypes; - internal Type Type { get; } internal IReadOnlyList Members { get; } public override async Task ValidateAsync(object? value, ValidateContext context, CancellationToken cancellationToken) @@ -94,7 +87,7 @@ public override async Task ValidateAsync(object? value, ValidateContext context, if (context.CurrentDepth >= context.ValidationOptions.MaxDepth) { throw new InvalidOperationException( - $"Maximum validation depth of {context.ValidationOptions.MaxDepth} exceeded at '{context.CurrentValidationPath}' in '{Type.Name}'. " + + $"Maximum validation depth of {context.ValidationOptions.MaxDepth} exceeded at '{context.CurrentValidationPath}' in '{nameof(CollectionRuleOptions)}'. " + "This is likely caused by a circular reference in the object graph. " + "Consider increasing the MaxDepth in ValidationOptions if deeper validation is required."); } @@ -104,7 +97,7 @@ public override async Task ValidateAsync(object? value, ValidateContext context, try { // Finally validate IValidatableObject if implemented - if (Type.ImplementsInterface(typeof(IValidatableObject)) && value is IValidatableObject validatable) + if (value is IValidatableObject validatable) { // Important: Set the DisplayName to the type name for top-level validations // and restore the original validation context properties @@ -112,7 +105,7 @@ public override async Task ValidateAsync(object? value, ValidateContext context, var originalMemberName = context.ValidationContext.MemberName; // Set the display name to the class name for IValidatableObject validation - context.ValidationContext.DisplayName = Type.Name; + context.ValidationContext.DisplayName = nameof(CollectionRuleOptions); context.ValidationContext.MemberName = null; var validationResults = validatable.Validate(context.ValidationContext); @@ -140,29 +133,12 @@ public override async Task ValidateAsync(object? value, ValidateContext context, } } - var actualType = value.GetType(); - - // First validate members + // Validate members for (var i = 0; i < _membersCount; i++) { await Members[i].ValidateAsync(value, context, cancellationToken); context.CurrentValidationPath = originalPrefix; } - - // Then validate sub-types if any - foreach (var subType in _subTypes) - { - // Check if the actual type is assignable to the sub-type - // and validate it if it is - if (subType.IsAssignableFrom(actualType)) - { - if (context.ValidationOptions.TryGetValidatableTypeInfo(subType, out var subTypeInfo)) - { - await subTypeInfo.ValidateAsync(value, context, cancellationToken); - context.CurrentValidationPath = originalPrefix; - } - } - } } finally { @@ -171,19 +147,9 @@ public override async Task ValidateAsync(object? value, ValidateContext context, } } - - sealed class CustomValidatableTypeInfo : ValidatableTypeInfo - { - public CustomValidatableTypeInfo( - [param: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] - Type type, - ValidatablePropertyInfo[] members) : base(type, members) { } - } - sealed class CustomValidatablePropertyInfo : ValidatablePropertyInfo { public CustomValidatablePropertyInfo( - [param: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type containingType, Type propertyType, string name, @@ -193,7 +159,6 @@ public CustomValidatablePropertyInfo( Name = name; } - [global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties | global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] internal Type ContainingType { get; } internal string Name { get; } @@ -203,16 +168,10 @@ protected override ValidationAttribute[] GetValidationAttributes() static class ValidationAttributeCache { - private sealed record CacheKey( - [property: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties | global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] - Type ContainingType, - string PropertyName); + private sealed record CacheKey(Type ContainingType, string PropertyName); private static readonly ConcurrentDictionary _cache = new(); - public static ValidationAttribute[] GetValidationAttributes( - [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties | global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] - Type containingType, - string propertyName) + public static ValidationAttribute[] GetValidationAttributes(Type containingType, string propertyName) { var key = new CacheKey(containingType, propertyName); return _cache.GetOrAdd(key, static k => From 35497ab849ea67c5cdcb7b7d0820254a4091471e Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 29 Apr 2025 00:00:53 +0000 Subject: [PATCH 164/174] Revert configuration binding changes --- .../ServiceCollectionExtensions.cs | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs index 1dd32c59e4b..ea8cb23f561 100644 --- a/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs +++ b/src/Tools/dotnet-monitor/ServiceCollectionExtensions.cs @@ -40,7 +40,6 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; -using System.Diagnostics.CodeAnalysis; using System.IO; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; @@ -50,43 +49,43 @@ internal static class ServiceCollectionExtensions { public static IServiceCollection ConfigureCors(this IServiceCollection services, IConfiguration configuration) { - return services.Configure(configuration.GetSection(ConfigurationKeys.CorsConfiguration)); + return ConfigureOptions(services, configuration, ConfigurationKeys.CorsConfiguration); } public static IServiceCollection ConfigureDotnetMonitorDebug(this IServiceCollection services, IConfiguration configuration) { - return services.Configure(configuration.GetSection(ConfigurationKeys.DotnetMonitorDebug)); + return ConfigureOptions(services, configuration, ConfigurationKeys.DotnetMonitorDebug); } public static IServiceCollection ConfigureGlobalCounter(this IServiceCollection services, IConfiguration configuration) { - return services.Configure(configuration.GetSection(ConfigurationKeys.GlobalCounter)) + return ConfigureOptions(services, configuration, ConfigurationKeys.GlobalCounter) .AddSingleton, DataAnnotationValidateOptions>(); } public static IServiceCollection ConfigureCollectionRuleDefaults(this IServiceCollection services, IConfiguration configuration) { - return services.Configure(configuration.GetSection(ConfigurationKeys.CollectionRuleDefaults)); + return ConfigureOptions(services, configuration, ConfigurationKeys.CollectionRuleDefaults); } public static IServiceCollection ConfigureTemplates(this IServiceCollection services, IConfiguration configuration) { - return services.Configure(configuration.GetSection(ConfigurationKeys.Templates)); + return ConfigureOptions(services, configuration, ConfigurationKeys.Templates); } public static IServiceCollection ConfigureInProcessFeatures(this IServiceCollection services, IConfiguration configuration) { - services.Configure(configuration.GetSection(ConfigurationKeys.InProcessFeatures_CallStacks)) + ConfigureOptions(services, configuration, ConfigurationKeys.InProcessFeatures_CallStacks) .AddSingleton, CallStacksPostConfigureOptions>(); - services.Configure(configuration.GetSection(ConfigurationKeys.InProcessFeatures_Exceptions)) + ConfigureOptions(services, configuration, ConfigurationKeys.InProcessFeatures_Exceptions) .AddSingleton, ExceptionsPostConfigureOptions>(); - services.Configure(configuration.GetSection(ConfigurationKeys.InProcessFeatures_ParameterCapturing)) - .AddSingleton, ParameterCapturingPostConfigureOptions>(); + ConfigureOptions(services, configuration, ConfigurationKeys.InProcessFeatures_ParameterCapturing) + .AddSingleton, ParameterCapturingPostConfigureOptions>(); - services.Configure(configuration.GetSection(ConfigurationKeys.InProcessFeatures)) + ConfigureOptions(services, configuration, ConfigurationKeys.InProcessFeatures) .AddSingleton() .AddSingleton(); @@ -95,7 +94,7 @@ public static IServiceCollection ConfigureInProcessFeatures(this IServiceCollect public static IServiceCollection ConfigureMetrics(this IServiceCollection services, IConfiguration configuration) { - return services.Configure(configuration.GetSection(ConfigurationKeys.Metrics)) + return ConfigureOptions(services, configuration, ConfigurationKeys.Metrics) .AddSingleton, DataAnnotationValidateOptions>() .AddSingleton() .AddHostedService() @@ -104,7 +103,7 @@ public static IServiceCollection ConfigureMetrics(this IServiceCollection servic public static IServiceCollection ConfigureMonitorApiKeyOptions(this IServiceCollection services, IConfiguration configuration, bool allowConfigurationUpdates) { - services.Configure(configuration.GetSection(ConfigurationKeys.MonitorApiKey)); + ConfigureOptions(services, configuration, ConfigurationKeys.MonitorApiKey); // Loads and validates MonitorApiKeyOptions into MonitorApiKeyConfiguration services.AddSingleton, MonitorApiKeyPostConfigure>(); @@ -197,7 +196,7 @@ public static IServiceCollection ConfigureCollectionRules(this IServiceCollectio return services; } - public static IServiceCollection RegisterCollectionRuleAction<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFactory, TOptions, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TDescriptor>(this IServiceCollection services) + public static IServiceCollection RegisterCollectionRuleAction(this IServiceCollection services) where TFactory : class, ICollectionRuleActionFactory where TOptions : BaseRecordOptions, new() where TDescriptor : class, ICollectionRuleActionDescriptor @@ -211,7 +210,7 @@ public static IServiceCollection ConfigureCollectionRules(this IServiceCollectio return services; } - public static IServiceCollection RegisterCollectionRuleTrigger<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFactory, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TDescriptor>(this IServiceCollection services) + public static IServiceCollection RegisterCollectionRuleTrigger(this IServiceCollection services) where TFactory : class, ICollectionRuleTriggerFactory where TDescriptor : class, ICollectionRuleTriggerDescriptor { @@ -221,7 +220,7 @@ public static IServiceCollection ConfigureCollectionRules(this IServiceCollectio return services; } - public static IServiceCollection RegisterCollectionRuleTrigger<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TFactory, TOptions, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TDescriptor>(this IServiceCollection services) + public static IServiceCollection RegisterCollectionRuleTrigger(this IServiceCollection services) where TFactory : class, ICollectionRuleTriggerFactory where TOptions : class, new() where TDescriptor : class, ICollectionRuleTriggerDescriptor @@ -238,7 +237,7 @@ public static IServiceCollection ConfigureCollectionRules(this IServiceCollectio public static IServiceCollection ConfigureStorage(this IServiceCollection services, IConfiguration configuration) { - services.Configure(configuration.GetSection(ConfigurationKeys.Storage)); + ConfigureOptions(services, configuration, ConfigurationKeys.Storage); services.AddSingleton, StoragePostConfigureOptions>(); return services; } @@ -256,7 +255,12 @@ public static IServiceCollection ConfigureCapabilities(this IServiceCollection s public static IServiceCollection ConfigureDefaultProcess(this IServiceCollection services, IConfiguration configuration) { - return services.Configure(configuration.GetSection(ConfigurationKeys.DefaultProcess)); + return ConfigureOptions(services, configuration, ConfigurationKeys.DefaultProcess); + } + + private static IServiceCollection ConfigureOptions(IServiceCollection services, IConfiguration configuration, string key) where T : class + { + return services.Configure(configuration.GetSection(key)); } public static IServiceCollection ConfigureExtensions(this IServiceCollection services) From dc301801b677789e3ed811a2a9d20fb98a9f9e08 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 29 Apr 2025 21:55:18 +0000 Subject: [PATCH 165/174] Clean up ValidatableTypes --- .../Actions/CollectTraceOptions.Validate.cs | 2 + .../dotnet-monitor/CustomValidationInfo.cs | 36 +- src/Tools/dotnet-monitor/TestAssemblies.cs | 1 + .../dotnet-monitor/ValidatableInfoResolver.cs | 1200 +++++++---------- src/Tools/dotnet-monitor/ValidatableTypes.cs | 61 +- 5 files changed, 564 insertions(+), 736 deletions(-) diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs index 70f4601c622..9107de46d08 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs @@ -85,6 +85,8 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali } // Validate that each provider is valid. + // Necessary to work around the generated validation code not recursing into List? members: + // https://github.com/dotnet/aspnetcore/issues/61737 int index = 0; foreach (EventPipeProvider provider in Providers) { diff --git a/src/Tools/dotnet-monitor/CustomValidationInfo.cs b/src/Tools/dotnet-monitor/CustomValidationInfo.cs index 546dbdb4c22..3ecc73149d5 100644 --- a/src/Tools/dotnet-monitor/CustomValidationInfo.cs +++ b/src/Tools/dotnet-monitor/CustomValidationInfo.cs @@ -178,35 +178,35 @@ public static ValidationAttribute[] GetValidationAttributes(Type containingType, { var results = new List(); - // Get attributes from the property + // Get attributes from the property var property = k.ContainingType.GetProperty(k.PropertyName); if (property != null) { - var propertyAttributes = CustomAttributeExtensions.GetCustomAttributes(property, inherit: true); + var propertyAttributes = CustomAttributeExtensions.GetCustomAttributes(property, inherit: true); - results.AddRange(propertyAttributes); + results.AddRange(propertyAttributes); } - // Check constructors for parameters that match the property name - // to handle record scenarios - foreach (var constructor in k.ContainingType.GetConstructors()) - { - // Look for parameter with matching name (case insensitive) - var parameter = Enumerable.FirstOrDefault( - constructor.GetParameters(), - p => string.Equals(p.Name, k.PropertyName, global::System.StringComparison.OrdinalIgnoreCase)); - - if (parameter != null) + // Check constructors for parameters that match the property name + // to handle record scenarios + foreach (var constructor in k.ContainingType.GetConstructors()) { - var paramAttributes = CustomAttributeExtensions.GetCustomAttributes(parameter, inherit: true); + // Look for parameter with matching name (case insensitive) + var parameter = Enumerable.FirstOrDefault( + constructor.GetParameters(), + p => string.Equals(p.Name, k.PropertyName, global::System.StringComparison.OrdinalIgnoreCase)); + + if (parameter != null) + { + var paramAttributes = CustomAttributeExtensions.GetCustomAttributes(parameter, inherit: true); - results.AddRange(paramAttributes); + results.AddRange(paramAttributes); - break; + break; + } } - } - return results.ToArray(); + return results.ToArray(); }); } } diff --git a/src/Tools/dotnet-monitor/TestAssemblies.cs b/src/Tools/dotnet-monitor/TestAssemblies.cs index c5e7d1cafa2..92aab047af5 100644 --- a/src/Tools/dotnet-monitor/TestAssemblies.cs +++ b/src/Tools/dotnet-monitor/TestAssemblies.cs @@ -20,6 +20,7 @@ internal static class TestAssemblies private const string ArtifactsDirectoryName = "artifacts"; private const string TestHostingStartupAssemblyName = "Microsoft.Diagnostics.Monitoring.Tool.TestHostingStartup"; private const string TestStartupHookAssemblyName = "Microsoft.Diagnostics.Monitoring.Tool.TestStartupHook"; + #nullable disable [Conditional("DEBUG")] public static void SimulateStartupHook() diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index 90c47084913..4696458db86 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -27,6 +27,7 @@ namespace Microsoft.AspNetCore.Http.Validation.Generated file sealed class GeneratedValidatablePropertyInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatablePropertyInfo { public GeneratedValidatablePropertyInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] global::System.Type containingType, global::System.Type propertyType, string name, @@ -58,16 +59,6 @@ public GeneratedValidatableTypeInfo( public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) { validatableInfo = null; - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider)) - { - validatableInfo = CreateMetricProvider(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions)) - { - validatableInfo = CreateMetricsOptions(); - return true; - } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions)) { validatableInfo = CreateMonitorApiKeyOptions(); @@ -83,154 +74,154 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateAuthenticationOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions)) { - validatableInfo = CreateCollectionRuleTriggerOptions(); + validatableInfo = CreateGlobalCounterOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration)) { - validatableInfo = CreateCollectionRuleActionOptions(); + validatableInfo = CreateExceptionsConfiguration(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions)) { - validatableInfo = CreateCollectionRuleLimitsOptions(); + validatableInfo = CreateExceptionsOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions)) { - validatableInfo = CreateCollectionRuleOptions(); + validatableInfo = CreateInProcessFeaturesOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter)) + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions)) { - validatableInfo = CreateTraceEventFilter(); + validatableInfo = CreateCorsConfigurationOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions)) { - validatableInfo = CreateCollectTraceOptions(); + validatableInfo = CreateEgressOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider)) { - validatableInfo = CreateExecuteOptions(); + validatableInfo = CreateMetricProvider(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions)) { - validatableInfo = CreateSetEnvironmentVariableOptions(); + validatableInfo = CreateMetricsOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions)) { - validatableInfo = CreateGetEnvironmentVariableOptions(); + validatableInfo = CreateCollectionRuleTriggerDefaultsOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions)) { - validatableInfo = CreateGlobalCounterOptions(); + validatableInfo = CreateCollectionRuleLimitsDefaultsOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions)) { - validatableInfo = CreateCollectGCDumpOptions(); + validatableInfo = CreateCollectionRuleDefaultsOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions)) { - validatableInfo = CreateCollectLiveMetricsOptions(); + validatableInfo = CreateTemplateOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions)) { - validatableInfo = CreateCollectStacksOptions(); + validatableInfo = CreateRootOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions)) { - validatableInfo = CreateCollectLogsOptions(); + validatableInfo = CreateCollectDumpOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions)) { - validatableInfo = CreateExceptionsConfiguration(); + validatableInfo = CreateCollectExceptionsOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions)) { - validatableInfo = CreateExceptionsOptions(); + validatableInfo = CreateCollectGCDumpOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions)) { - validatableInfo = CreateInProcessFeaturesOptions(); + validatableInfo = CreateCollectLiveMetricsOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions)) { - validatableInfo = CreateCorsConfigurationOptions(); + validatableInfo = CreateCollectLogsOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions)) { - validatableInfo = CreateEgressOptions(); + validatableInfo = CreateCollectStacksOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter)) { - validatableInfo = CreateProcessFilterOptions(); + validatableInfo = CreateTraceEventFilter(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions)) { - validatableInfo = CreateCollectionRuleTriggerDefaultsOptions(); + validatableInfo = CreateCollectTraceOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider)) { - validatableInfo = CreateCollectionRuleLimitsDefaultsOptions(); + validatableInfo = CreateEventPipeProvider(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions)) { - validatableInfo = CreateCollectionRuleDefaultsOptions(); + validatableInfo = CreateExecuteOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions)) { - validatableInfo = CreateTemplateOptions(); + validatableInfo = CreateGetEnvironmentVariableOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions)) + if (type == typeof(global::System.Guid)) { - validatableInfo = CreateRootOptions(); + validatableInfo = CreateGuid(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions)) { - validatableInfo = CreateFileSystemEgressProviderOptions(); + validatableInfo = CreateLoadProfilerOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions)) { - validatableInfo = CreateCollectDumpOptions(); + validatableInfo = CreateSetEnvironmentVariableOptions(); return true; } - if (type == typeof(global::System.Guid)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions)) { - validatableInfo = CreateGuid(); + validatableInfo = CreateCPUUsageOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions)) { - validatableInfo = CreateLoadProfilerOptions(); + validatableInfo = CreateGCHeapSizeOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions)) { - validatableInfo = CreateCollectExceptionsOptions(); + validatableInfo = CreateThreadpoolQueueLengthOptions(); return true; } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions)) @@ -253,29 +244,14 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateEventCounterOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions)) - { - validatableInfo = CreateCPUUsageOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions)) - { - validatableInfo = CreateGCHeapSizeOptions(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions)) - { - validatableInfo = CreateThreadpoolQueueLengthOptions(); - return true; - } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions)) { validatableInfo = CreateEventMeterOptions(); return true; } - if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider)) + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions)) { - validatableInfo = CreateEventPipeProvider(); + validatableInfo = CreateFileSystemEgressProviderOptions(); return true; } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest)) @@ -299,40 +275,6 @@ public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterIn return false; } - private ValidatableTypeInfo CreateMetricProvider() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), - propertyType: typeof(string), - name: "ProviderName", - displayName: "ProviderName" - ), - ] - ); - } - private ValidatableTypeInfo CreateMetricsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - propertyType: typeof(int?), - name: "MetricCount", - displayName: "MetricCount" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - propertyType: typeof(global::System.Collections.Generic.List), - name: "Providers", - displayName: "Providers" - ), - ] - ); - } private ValidatableTypeInfo CreateMonitorApiKeyOptions() { return new GeneratedValidatableTypeInfo( @@ -405,614 +347,566 @@ private ValidatableTypeInfo CreateAuthenticationOptions() ] ); } - private ValidatableTypeInfo CreateCollectionRuleTriggerOptions() + private ValidatableTypeInfo CreateGlobalCounterOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), - propertyType: typeof(string), - name: "Type", - displayName: "Type" + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(float?), + name: "IntervalSeconds", + displayName: "IntervalSeconds" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(int?), + name: "MaxHistograms", + displayName: "MaxHistograms" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(int?), + name: "MaxTimeSeries", + displayName: "MaxTimeSeries" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Providers", + displayName: "Providers" ), ] ); } - private ValidatableTypeInfo CreateCollectionRuleActionOptions() + private ValidatableTypeInfo CreateExceptionsConfiguration() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), - propertyType: typeof(string), - name: "Type", - displayName: "Type" + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Exclude", + displayName: "Exclude" ), ] ); } - private ValidatableTypeInfo CreateCollectionRuleLimitsOptions() + private ValidatableTypeInfo CreateExceptionsOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), propertyType: typeof(int?), - name: "ActionCount", - displayName: "ActionCount" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "ActionCountSlidingWindowDuration", - displayName: "ActionCountSlidingWindowDuration" + name: "TopLevelLimit", + displayName: "TopLevelLimit" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "RuleDuration", - displayName: "RuleDuration" + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + name: "CollectionFilters", + displayName: "CollectionFilters" ), ] ); } - private ValidatableTypeInfo CreateCollectionRuleOptions() + private ValidatableTypeInfo CreateInProcessFeaturesOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), - name: "Trigger", - displayName: "Trigger" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - propertyType: typeof(global::System.Collections.Generic.List), - name: "Actions", - displayName: "Actions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), - name: "Limits", - displayName: "Limits" + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + name: "Exceptions", + displayName: "Exceptions" ), ] ); } - private ValidatableTypeInfo CreateTraceEventFilter() + private ValidatableTypeInfo CreateCorsConfigurationOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - propertyType: typeof(string), - name: "ProviderName", - displayName: "ProviderName" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), propertyType: typeof(string), - name: "EventName", - displayName: "EventName" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "PayloadFilter", - displayName: "PayloadFilter" + name: "AllowedOrigins", + displayName: "AllowedOrigins" ), ] ); } - private ValidatableTypeInfo CreateCollectTraceOptions() + private ValidatableTypeInfo CreateEgressOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.TraceProfile?), - name: "Profile", - displayName: "Profile" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(int?), - name: "BufferSizeMegabytes", - displayName: "BufferSizeMegabytes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "Duration", - displayName: "Duration" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "FileSystem", + displayName: "FileSystem" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), - name: "StoppingEvent", - displayName: "StoppingEvent" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Properties", + displayName: "Properties" ), ] ); } - private ValidatableTypeInfo CreateExecuteOptions() + private ValidatableTypeInfo CreateMetricProvider() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), propertyType: typeof(string), - name: "Path", - displayName: "Path" + name: "ProviderName", + displayName: "ProviderName" ), ] ); } - private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() + private ValidatableTypeInfo CreateMetricsOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), - propertyType: typeof(string), - name: "Name", - displayName: "Name" + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + propertyType: typeof(int?), + name: "MetricCount", + displayName: "MetricCount" ), - ] - ); - } - private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), - members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), - propertyType: typeof(string), - name: "Name", - displayName: "Name" + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Providers", + displayName: "Providers" ), ] ); } - private ValidatableTypeInfo CreateGlobalCounterOptions() + private ValidatableTypeInfo CreateCollectionRuleTriggerDefaultsOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - propertyType: typeof(float?), - name: "IntervalSeconds", - displayName: "IntervalSeconds" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), propertyType: typeof(int?), - name: "MaxHistograms", - displayName: "MaxHistograms" + name: "RequestCount", + displayName: "RequestCount" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), propertyType: typeof(int?), - name: "MaxTimeSeries", - displayName: "MaxTimeSeries" + name: "ResponseCount", + displayName: "ResponseCount" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "Providers", - displayName: "Providers" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" ), ] ); } - private ValidatableTypeInfo CreateCollectGCDumpOptions() + private ValidatableTypeInfo CreateCollectionRuleLimitsDefaultsOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(int?), + name: "ActionCount", + displayName: "ActionCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "ActionCountSlidingWindowDuration", + displayName: "ActionCountSlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RuleDuration", + displayName: "RuleDuration" ), ] ); } - private ValidatableTypeInfo CreateCollectLiveMetricsOptions() + private ValidatableTypeInfo CreateCollectionRuleDefaultsOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "Duration", - displayName: "Duration" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + name: "Triggers", + displayName: "Triggers" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + name: "Limits", + displayName: "Limits" ), ] ); } - private ValidatableTypeInfo CreateCollectStacksOptions() + private ValidatableTypeInfo CreateTemplateOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleFilters", + displayName: "CollectionRuleFilters" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleTriggers", + displayName: "CollectionRuleTriggers" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleActions", + displayName: "CollectionRuleActions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleLimits", + displayName: "CollectionRuleLimits" ), ] ); } - private ValidatableTypeInfo CreateCollectLogsOptions() + private ValidatableTypeInfo CreateRootOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - propertyType: typeof(global::Microsoft.Extensions.Logging.LogLevel?), - name: "DefaultLevel", - displayName: "DefaultLevel" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + name: "Authentication", + displayName: "Authentication" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - propertyType: typeof(global::System.Collections.Generic.Dictionary), - name: "FilterSpecs", - displayName: "FilterSpecs" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRules", + displayName: "CollectionRules" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "Duration", - displayName: "Duration" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + name: "GlobalCounter", + displayName: "GlobalCounter" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + name: "InProcessFeatures", + displayName: "InProcessFeatures" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.LogFormat?), - name: "Format", - displayName: "Format" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + name: "CorsConfiguration", + displayName: "CorsConfiguration" ), - ] - ); - } - private ValidatableTypeInfo CreateExceptionsConfiguration() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), - members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), - propertyType: typeof(global::System.Collections.Generic.List), - name: "Exclude", - displayName: "Exclude" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + name: "Egress", + displayName: "Egress" ), - ] - ); - } - private ValidatableTypeInfo CreateExceptionsOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), - members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), - propertyType: typeof(int?), - name: "TopLevelLimit", - displayName: "TopLevelLimit" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + name: "Metrics", + displayName: "Metrics" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), - name: "CollectionFilters", - displayName: "CollectionFilters" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + name: "CollectionRuleDefaults", + displayName: "CollectionRuleDefaults" ), - ] - ); - } - private ValidatableTypeInfo CreateInProcessFeaturesOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), - members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), - name: "Exceptions", - displayName: "Exceptions" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + name: "Templates", + displayName: "Templates" ), ] ); } - private ValidatableTypeInfo CreateCorsConfigurationOptions() + private ValidatableTypeInfo CreateCollectDumpOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.DumpType?), + name: "Type", + displayName: "Type" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), propertyType: typeof(string), - name: "AllowedOrigins", - displayName: "AllowedOrigins" + name: "Egress", + displayName: "Egress" ), ] ); } - private ValidatableTypeInfo CreateEgressOptions() + private ValidatableTypeInfo CreateCollectExceptionsOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "FileSystem", - displayName: "FileSystem" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "Properties", - displayName: "Properties" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + name: "Filters", + displayName: "Filters" ), ] ); } - private ValidatableTypeInfo CreateProcessFilterOptions() + private ValidatableTypeInfo CreateCollectGCDumpOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), - propertyType: typeof(global::System.Collections.Generic.List), - name: "Filters", - displayName: "Filters" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" ), ] ); } - private ValidatableTypeInfo CreateCollectionRuleTriggerDefaultsOptions() + private ValidatableTypeInfo CreateCollectLiveMetricsOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - propertyType: typeof(int?), - name: "RequestCount", - displayName: "RequestCount" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - propertyType: typeof(int?), - name: "ResponseCount", - displayName: "ResponseCount" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Duration" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" ), ] ); } - private ValidatableTypeInfo CreateCollectionRuleLimitsDefaultsOptions() + private ValidatableTypeInfo CreateCollectLogsOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - propertyType: typeof(int?), - name: "ActionCount", - displayName: "ActionCount" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::Microsoft.Extensions.Logging.LogLevel?), + name: "DefaultLevel", + displayName: "DefaultLevel" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::System.Collections.Generic.Dictionary), + name: "FilterSpecs", + displayName: "FilterSpecs" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Duration" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "ActionCountSlidingWindowDuration", - displayName: "ActionCountSlidingWindowDuration" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "RuleDuration", - displayName: "RuleDuration" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.LogFormat?), + name: "Format", + displayName: "Format" ), ] ); } - private ValidatableTypeInfo CreateCollectionRuleDefaultsOptions() + private ValidatableTypeInfo CreateCollectStacksOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), - name: "Triggers", - displayName: "Triggers" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), - name: "Limits", - displayName: "Limits" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" ), ] ); } - private ValidatableTypeInfo CreateTemplateOptions() + private ValidatableTypeInfo CreateTraceEventFilter() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRuleFilters", - displayName: "CollectionRuleFilters" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRuleTriggers", - displayName: "CollectionRuleTriggers" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(string), + name: "ProviderName", + displayName: "ProviderName" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRuleActions", - displayName: "CollectionRuleActions" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(string), + name: "EventName", + displayName: "EventName" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRuleLimits", - displayName: "CollectionRuleLimits" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "PayloadFilter", + displayName: "PayloadFilter" ), ] ); } - private ValidatableTypeInfo CreateRootOptions() + private ValidatableTypeInfo CreateCollectTraceOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), - name: "Authentication", - displayName: "Authentication" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "CollectionRules", - displayName: "CollectionRules" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - name: "GlobalCounter", - displayName: "GlobalCounter" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.TraceProfile?), + name: "Profile", + displayName: "Profile" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), - name: "InProcessFeatures", - displayName: "InProcessFeatures" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(int?), + name: "BufferSizeMegabytes", + displayName: "BufferSizeMegabytes" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), - name: "CorsConfiguration", - displayName: "CorsConfiguration" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Duration" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(string), name: "Egress", displayName: "Egress" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - name: "Metrics", - displayName: "Metrics" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + name: "StoppingEvent", + displayName: "StoppingEvent" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventPipeProvider() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(string), + name: "Name", + displayName: "Name" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.ProcessFilterOptions), - name: "DefaultProcess", - displayName: "DefaultProcess" + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(string), + name: "Keywords", + displayName: "Keywords" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), - name: "CollectionRuleDefaults", - displayName: "CollectionRuleDefaults" + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(global::System.Diagnostics.Tracing.EventLevel), + name: "EventLevel", + displayName: "EventLevel" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), - name: "Templates", - displayName: "Templates" + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Arguments", + displayName: "Arguments" ), ] ); } - private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() + private ValidatableTypeInfo CreateExecuteOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), propertyType: typeof(string), - name: "DirectoryPath", - displayName: "DirectoryPath" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - propertyType: typeof(int?), - name: "CopyBufferSize", - displayName: "CopyBufferSize" + name: "Path", + displayName: "Path" ), ] ); } - private ValidatableTypeInfo CreateCollectDumpOptions() + private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.DumpType?), - name: "Type", - displayName: "Type" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), propertyType: typeof(string), - name: "Egress", - displayName: "Egress" + name: "Name", + displayName: "Name" ), ] ); @@ -1051,22 +945,94 @@ private ValidatableTypeInfo CreateLoadProfilerOptions() ] ); } - private ValidatableTypeInfo CreateCollectExceptionsOptions() + private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + propertyType: typeof(string), + name: "Name", + displayName: "Name" + ), + ] + ); + } + private ValidatableTypeInfo CreateCPUUsageOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + propertyType: typeof(double?), + name: "GreaterThan", + displayName: "GreaterThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + propertyType: typeof(double?), + name: "LessThan", + displayName: "LessThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateGCHeapSizeOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + propertyType: typeof(double?), + name: "GreaterThan", + displayName: "GreaterThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + propertyType: typeof(double?), + name: "LessThan", + displayName: "LessThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateThreadpoolQueueLengthOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), - propertyType: typeof(string), - name: "Egress", - displayName: "Egress" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + propertyType: typeof(double?), + name: "GreaterThan", + displayName: "GreaterThan" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), - name: "Filters", - displayName: "Filters" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + propertyType: typeof(double?), + name: "LessThan", + displayName: "LessThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" ), ] ); @@ -1205,84 +1171,6 @@ private ValidatableTypeInfo CreateEventCounterOptions() ] ); } - private ValidatableTypeInfo CreateCPUUsageOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), - propertyType: typeof(double?), - name: "GreaterThan", - displayName: "GreaterThan" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), - propertyType: typeof(double?), - name: "LessThan", - displayName: "LessThan" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" - ), - ] - ); - } - private ValidatableTypeInfo CreateGCHeapSizeOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), - propertyType: typeof(double?), - name: "GreaterThan", - displayName: "GreaterThan" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), - propertyType: typeof(double?), - name: "LessThan", - displayName: "LessThan" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" - ), - ] - ); - } - private ValidatableTypeInfo CreateThreadpoolQueueLengthOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), - propertyType: typeof(double?), - name: "GreaterThan", - displayName: "GreaterThan" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), - propertyType: typeof(double?), - name: "LessThan", - displayName: "LessThan" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), - propertyType: typeof(global::System.TimeSpan?), - name: "SlidingWindowDuration", - displayName: "SlidingWindowDuration" - ), - ] - ); - } private ValidatableTypeInfo CreateEventMeterOptions() { return new GeneratedValidatableTypeInfo( @@ -1315,34 +1203,22 @@ private ValidatableTypeInfo CreateEventMeterOptions() ] ); } - private ValidatableTypeInfo CreateEventPipeProvider() + private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() { return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), members: [ new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), - propertyType: typeof(string), - name: "Name", - displayName: "Name" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), propertyType: typeof(string), - name: "Keywords", - displayName: "Keywords" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), - propertyType: typeof(global::System.Diagnostics.Tracing.EventLevel), - name: "EventLevel", - displayName: "EventLevel" + name: "DirectoryPath", + displayName: "DirectoryPath" ), new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), - propertyType: typeof(global::System.Collections.Generic.IDictionary), - name: "Arguments", - displayName: "Arguments" + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + propertyType: typeof(int?), + name: "CopyBufferSize", + displayName: "CopyBufferSize" ), ] ); @@ -1368,51 +1244,21 @@ private ValidatableTypeInfo CreateValidatableTypes() members: [ new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), - name: "MetricsOptions", - displayName: "MetricsOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), - name: "AuthenticationOptions", - displayName: "AuthenticationOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), - name: "CollectionRuleOptions", - displayName: "CollectionRuleOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), - name: "CollectTraceOptions", - displayName: "CollectTraceOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), - name: "ExecuteOptions", - displayName: "ExecuteOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), - name: "SetEnvironmentVariableOptions", - displayName: "SetEnvironmentVariableOptions" + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + name: "RootOptions", + displayName: "RootOptions" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), - name: "GetEnvironmentVariableOptions", - displayName: "GetEnvironmentVariableOptions" + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + name: "CollectDumpOptions", + displayName: "CollectDumpOptions" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), - name: "GlobalCounterOptions", - displayName: "GlobalCounterOptions" + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + name: "CollectExceptionsOptions", + displayName: "CollectExceptionsOptions" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), @@ -1426,6 +1272,12 @@ private ValidatableTypeInfo CreateValidatableTypes() name: "CollectLiveMetricsOptions", displayName: "CollectLiveMetricsOptions" ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + name: "CollectLogsOptions", + displayName: "CollectLogsOptions" + ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), @@ -1434,27 +1286,27 @@ private ValidatableTypeInfo CreateValidatableTypes() ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), - name: "CollectLogsOptions", - displayName: "CollectLogsOptions" + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + name: "CollectTraceOptions", + displayName: "CollectTraceOptions" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), - name: "RootOptions", - displayName: "RootOptions" + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + name: "EventPipeProvider", + displayName: "EventPipeProvider" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), - name: "FileSystemEgressProviderOptions", - displayName: "FileSystemEgressProviderOptions" + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + name: "ExecuteOptions", + displayName: "ExecuteOptions" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), - name: "CollectDumpOptions", - displayName: "CollectDumpOptions" + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + name: "GetEnvironmentVariableOptions", + displayName: "GetEnvironmentVariableOptions" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), @@ -1464,9 +1316,27 @@ private ValidatableTypeInfo CreateValidatableTypes() ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), - name: "CollectExceptionsOptions", - displayName: "CollectExceptionsOptions" + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + name: "SetEnvironmentVariableOptions", + displayName: "SetEnvironmentVariableOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + name: "CPUUsageOptions", + displayName: "CPUUsageOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + name: "GCHeapSizeOptions", + displayName: "GCHeapSizeOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + name: "ThreadpoolQueueLengthOptions", + displayName: "ThreadpoolQueueLengthOptions" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), @@ -1492,24 +1362,6 @@ private ValidatableTypeInfo CreateValidatableTypes() name: "EventCounterOptions", displayName: "EventCounterOptions" ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), - name: "CPUUsageOptions", - displayName: "CPUUsageOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), - name: "GCHeapSizeOptions", - displayName: "GCHeapSizeOptions" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), - name: "ThreadpoolQueueLengthOptions", - displayName: "ThreadpoolQueueLengthOptions" - ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), @@ -1518,9 +1370,9 @@ private ValidatableTypeInfo CreateValidatableTypes() ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), - name: "EventPipeProvider", - displayName: "EventPipeProvider" + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + name: "FileSystemEgressProviderOptions", + displayName: "FileSystemEgressProviderOptions" ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), @@ -1528,12 +1380,6 @@ private ValidatableTypeInfo CreateValidatableTypes() name: "ExtensionManifest", displayName: "ExtensionManifest" ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), - propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), - name: "AzureAdOptions", - displayName: "AzureAdOptions" - ), ] ); } @@ -1543,7 +1389,7 @@ private ValidatableTypeInfo CreateValidatableTypes() [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] internal static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "D6nh8/WlpPzAY1xLUbepOblXAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "2VxCaedDCgd5rLwA0WSiOmZdAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. @@ -1607,4 +1453,4 @@ private sealed record CacheKey(global::System.Type ContainingType, string Proper }); } } -} +} \ No newline at end of file diff --git a/src/Tools/dotnet-monitor/ValidatableTypes.cs b/src/Tools/dotnet-monitor/ValidatableTypes.cs index 334d2ed733b..b3c5b833163 100644 --- a/src/Tools/dotnet-monitor/ValidatableTypes.cs +++ b/src/Tools/dotnet-monitor/ValidatableTypes.cs @@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Http.Validation; using Microsoft.AspNetCore.Http.Validation.Generated; -using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; @@ -19,66 +18,46 @@ namespace Microsoft.Diagnostics.Tools.Monitor // so we can't generate IValidatableInfo by using [ValidatableType] directly on types defined // in ProjectReferences. This is a workaround to force the generator running in this project to // generate IValidatableInfo for the referenced types. The containing class is not used otherwise. + // We use the same pattern for all types, including those defined in the same project. [ValidatableType] internal class ValidatableTypes { - public required MetricsOptions MetricsOptions { get; init; } - - public required AuthenticationOptions AuthenticationOptions { get; init; } - - public required CollectionRuleOptions CollectionRuleOptions { get; init; } - - public required CollectTraceOptions CollectTraceOptions { get; init; } - - public required ExecuteOptions ExecuteOptions { get; init; } + public required RootOptions RootOptions { get; init; } - public required SetEnvironmentVariableOptions SetEnvironmentVariableOptions { get; init; } - - public required GetEnvironmentVariableOptions GetEnvironmentVariableOptions { get; init; } - - public required GlobalCounterOptions GlobalCounterOptions { get; init; } + // Action options + public required CollectDumpOptions CollectDumpOptions { get; init; } + public required CollectExceptionsOptions CollectExceptionsOptions { get; init; } public required CollectGCDumpOptions CollectGCDumpOptions { get; init; } - public required CollectLiveMetricsOptions CollectLiveMetricsOptions { get; init; } - - public required CollectStacksOptions CollectStacksOptions { get; init; } - public required CollectLogsOptions CollectLogsOptions { get; init; } - - public required RootOptions RootOptions { get; init; } - - public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } - - public required CollectDumpOptions CollectDumpOptions { get; init; } - + public required CollectStacksOptions CollectStacksOptions { get; init; } + public required CollectTraceOptions CollectTraceOptions { get; init; } + // Necessary to work around the generated validation code not recursing into List? members: + // https://github.com/dotnet/aspnetcore/issues/61737 + public required EventPipeProvider EventPipeProvider { get; init; } + public required ExecuteOptions ExecuteOptions { get; init; } + public required GetEnvironmentVariableOptions GetEnvironmentVariableOptions { get; init; } public required LoadProfilerOptions LoadProfilerOptions { get; init; } + public required SetEnvironmentVariableOptions SetEnvironmentVariableOptions { get; init; } - public required CollectExceptionsOptions CollectExceptionsOptions { get; init; } - // Triggers... + // Trigger options + // EventCounterShortcuts + public required CPUUsageOptions CPUUsageOptions { get; init; } + public required GCHeapSizeOptions GCHeapSizeOptions { get; init; } + public required ThreadpoolQueueLengthOptions ThreadpoolQueueLengthOptions { get; init; } + // Other trigger options public required AspNetRequestCountOptions AspNetRequestCountOptions { get; init; } public required AspNetRequestDurationOptions AspNetRequestDurationOptions { get; init; } public required AspNetResponseStatusOptions AspNetResponseStatusOptions { get; init; } public required EventCounterOptions EventCounterOptions { get; init; } - public required CPUUsageOptions CPUUsageOptions { get; init; } - public required GCHeapSizeOptions GCHeapSizeOptions { get; init; } - public required ThreadpoolQueueLengthOptions ThreadpoolQueueLengthOptions { get; init; } public required EventMeterOptions EventMeterOptions { get; init; } - // Nested member - public required EventPipeProvider EventPipeProvider { get; init; } + public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } public required ExtensionManifest ExtensionManifest { get; init; } - // public RootOptions RootOptions { get; init; } // TODO: this hits bad generated code. - // Take a more granular approach for now. - - - public required AzureAdOptions AzureAdOptions { get; init; } - - // TODO: only one resolver per project? Generate this for tests, for now. Maybe want to separate this one out - // by test later. public static void AddValidation(IServiceCollection services) { GeneratedServiceCollectionExtensions.AddValidation(services); From 375438da89e7028acdd9e72f1dbc2e491fdf2626 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 29 Apr 2025 22:02:26 +0000 Subject: [PATCH 166/174] Use interceptor --- src/Tools/dotnet-monitor/ValidatableInfoResolver.cs | 6 +++--- src/Tools/dotnet-monitor/ValidatableTypes.cs | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index 4696458db86..2c72dc447b2 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -1387,10 +1387,10 @@ private ValidatableTypeInfo CreateValidatableTypes() } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - internal static class GeneratedServiceCollectionExtensions + file static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "2VxCaedDCgd5rLwA0WSiOmZdAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "YPWMHSw2t9m2EKEnnFoL6ysOAABWYWxpZGF0YWJsZVR5cGVzLmNz")] + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => diff --git a/src/Tools/dotnet-monitor/ValidatableTypes.cs b/src/Tools/dotnet-monitor/ValidatableTypes.cs index b3c5b833163..02b00a319c2 100644 --- a/src/Tools/dotnet-monitor/ValidatableTypes.cs +++ b/src/Tools/dotnet-monitor/ValidatableTypes.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http.Validation; -using Microsoft.AspNetCore.Http.Validation.Generated; using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; @@ -60,8 +59,7 @@ internal class ValidatableTypes public static void AddValidation(IServiceCollection services) { - GeneratedServiceCollectionExtensions.AddValidation(services); - ValidationServiceCollectionExtensions.AddValidation(services, options => + services.AddValidation(options => { options.Resolvers.Insert(0, new CustomValidatableInfoResolver()); }); From 38f44c6c4280cafa2af70a860542faf41c17d5ad Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 29 Apr 2025 23:38:34 +0000 Subject: [PATCH 167/174] Remove interceptor This doesn't work for windows and linux with checked-in sources --- .../ValidatableInfoResolver.cs | 1 - src/Tools/dotnet-monitor/ValidatableInfoResolver.cs | 3 +-- src/Tools/dotnet-monitor/ValidatableTypes.cs | 3 ++- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs index e85fa33860c..4a06b0908ac 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs @@ -685,7 +685,6 @@ internal static class TestGeneratedServiceCollectionExtensions [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] file static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "PAnjif+NkJ3ztrKunTBG39nHAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index 2c72dc447b2..372e3c0a249 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -1387,9 +1387,8 @@ private ValidatableTypeInfo CreateValidatableTypes() } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] - file static class GeneratedServiceCollectionExtensions + internal static class GeneratedServiceCollectionExtensions { - [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "YPWMHSw2t9m2EKEnnFoL6ysOAABWYWxpZGF0YWJsZVR5cGVzLmNz")] public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. diff --git a/src/Tools/dotnet-monitor/ValidatableTypes.cs b/src/Tools/dotnet-monitor/ValidatableTypes.cs index 02b00a319c2..85e670b184c 100644 --- a/src/Tools/dotnet-monitor/ValidatableTypes.cs +++ b/src/Tools/dotnet-monitor/ValidatableTypes.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http.Validation; +using Microsoft.AspNetCore.Http.Validation.Generated; using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; @@ -59,7 +60,7 @@ internal class ValidatableTypes public static void AddValidation(IServiceCollection services) { - services.AddValidation(options => + GeneratedServiceCollectionExtensions.AddValidation(services, options => { options.Resolvers.Insert(0, new CustomValidatableInfoResolver()); }); From c3af09dd50d5e4e9033b34dfeeb034c90191cea9 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 29 Apr 2025 23:57:54 +0000 Subject: [PATCH 168/174] Use validation source generator This uses the new model for source generated validation from https://github.com/dotnet/aspnetcore/issues/46349. --- Directory.Packages.props | 3 +- src/Directory.Build.targets | 9 + ...nostics.Monitoring.Extension.Common.csproj | 3 +- .../AuthenticationOptions.Validate.cs | 2 +- .../GlobalCounterOptions.cs | 3 +- .../CollectionRuleActions.UnitTests.csproj | 2 + .../ExecuteActionTests.cs | 19 +- .../AuthenticationTests.cs | 22 +- ...tics.Monitoring.Tool.UnitTestCommon.csproj | 1 + .../TestHostHelper.cs | 2 + .../TestValidatableType.cs | 20 + .../ValidatableInfoResolver.cs | 752 +++++++++ .../CollectionRuleOptionsTests.cs | 11 +- .../CollectionRulePipelineTests.cs | 4 +- .../ExtensionManifestTests.cs | 29 +- .../FileSystemEgressExtensionTests.cs | 17 +- ...agnostics.Monitoring.Tool.UnitTests.csproj | 2 + .../Options/AzureAdOptionsTests.cs | 27 +- ...ics.Monitoring.Tool.UnitTestsSample.csproj | 13 + .../Program.cs | 14 + .../Auth/ApiKey/MonitorApiKeyPostConfigure.cs | 19 +- .../Auth/AuthConfiguratorFactory.cs | 15 +- .../Actions/CollectDumpAction.cs | 9 +- .../Actions/CollectExceptionsAction.cs | 16 +- .../Actions/CollectGCDumpAction.cs | 10 +- .../Actions/CollectLiveMetricsAction.cs | 8 +- .../Actions/CollectLogsAction.cs | 9 +- .../Actions/CollectStacksAction.cs | 9 +- .../Actions/CollectTraceAction.cs | 8 +- .../Actions/CollectionRuleActionOperations.cs | 2 +- .../CollectionRules/Actions/ExecuteAction.cs | 16 +- .../Actions/GetEnvironmentVariableAction.cs | 12 +- .../Actions/LoadProfilerAction.cs | 10 +- .../Actions/SetEnvironmentVariableAction.cs | 12 +- ...CollectionRulePostConfigureNamedOptions.cs | 13 +- .../CollectExceptionsOptions.Validate.cs | 2 +- .../Actions/CollectLogsOptions.Validate.cs | 4 +- .../Actions/CollectStacksOptions.Validate.cs | 2 +- .../Actions/CollectTraceOptions.Validate.cs | 18 +- .../Options/Actions/RequiredGuidAttribute.cs | 8 +- .../ValidateEgressProviderAttribute.cs | 8 +- .../CollectionRuleActionOptions.Validate.cs | 4 + .../Options/CollectionRuleOptions.Validate.cs | 17 +- .../Triggers/EventCounterOptions.Validate.cs | 4 +- .../IEventCounterShortcuts.Validate.cs | 2 +- .../Triggers/EventMeterOptions.Validate.cs | 4 +- .../Options/ValidationHelper.cs | 76 +- .../CollectionRuleTriggerOperations.cs | 2 +- .../Commands/CollectCommandHandler.cs | 2 +- .../dotnet-monitor/CustomValidationInfo.cs | 271 +++ .../DataAnnotationValidateOptions.cs | 25 +- .../Egress/Extension/EgressExtension.cs | 12 +- .../Extension/EgressExtensionFactory.cs | 8 +- .../Extensibility/ExtensionManifest.cs | 14 +- .../HostBuilder/HostBuilderHelper.cs | 1 + .../dotnet-monitor/ValidatableInfoResolver.cs | 1455 +++++++++++++++++ src/Tools/dotnet-monitor/ValidatableTypes.cs | 69 + .../dotnet-monitor/dotnet-monitor.csproj | 3 + 58 files changed, 2972 insertions(+), 162 deletions(-) create mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs create mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs create mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj create mode 100644 src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs create mode 100644 src/Tools/dotnet-monitor/CustomValidationInfo.cs create mode 100644 src/Tools/dotnet-monitor/ValidatableInfoResolver.cs create mode 100644 src/Tools/dotnet-monitor/ValidatableTypes.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index f37bd594e4c..7923f760fc8 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,8 +7,9 @@ - + + diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index b75f72b30b1..f79f7d13d44 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -126,4 +126,13 @@ + + + + + + + diff --git a/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj b/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj index 8879d6f8eb6..f9ada28f3cc 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj +++ b/src/Microsoft.Diagnostics.Monitoring.Extension.Common/Microsoft.Diagnostics.Monitoring.Extension.Common.csproj @@ -1,4 +1,4 @@ - + Library @@ -11,6 +11,7 @@ + diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.Validate.cs b/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.Validate.cs index d684f739526..6b11722b7a1 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.Validate.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/AuthenticationOptions.Validate.cs @@ -20,7 +20,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali results.Add( new ValidationResult( string.Format( - OptionsDisplayStrings.ErrorMessage_MultipleAuthenticationModesSpecified))); + OptionsDisplayStrings.ErrorMessage_MultipleAuthenticationModesSpecified), [nameof(MonitorApiKey), nameof(AzureAd)])); } return results; diff --git a/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs b/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs index c360b5184d1..ff3c222d629 100644 --- a/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs +++ b/src/Microsoft.Diagnostics.Monitoring.Options/GlobalCounterOptions.cs @@ -64,7 +64,8 @@ public IEnumerable Validate(ValidationContext validationContex { // We prefix the validation error with the provider. results.AddRange(providerResults.Select(r => new ValidationResult( - string.Format(CultureInfo.CurrentCulture, OptionsDisplayStrings.ErrorMessage_NestedProviderValidationError, provider, r.ErrorMessage)))); + string.Format(CultureInfo.CurrentCulture, OptionsDisplayStrings.ErrorMessage_NestedProviderValidationError, provider, r.ErrorMessage), + [nameof(Providers)]))); } } } diff --git a/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj b/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj index aa0591b54fc..f98166d3e64 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj +++ b/src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj @@ -7,6 +7,7 @@ + @@ -14,6 +15,7 @@ + diff --git a/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs b/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs index e5bf473507b..5c062e23516 100644 --- a/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs +++ b/src/Tests/CollectionRuleActions.UnitTests/ExecuteActionTests.cs @@ -1,11 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; +using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Exceptions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; using System.Globalization; using System.IO; @@ -18,17 +22,23 @@ namespace CollectionRuleActions.UnitTests { + public class ExecuteActionFixture : WebApplicationFactory + { + } + [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] [Collection(TestCollections.CollectionRuleActions)] - public sealed class ExecuteActionTests + public sealed class ExecuteActionTests : IClassFixture { private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30); private readonly ITestOutputHelper _outputHelper; + private readonly ExecuteActionFixture _fixture; - public ExecuteActionTests(ITestOutputHelper outputHelper) + public ExecuteActionTests(ITestOutputHelper outputHelper, ExecuteActionFixture fixture) { _outputHelper = outputHelper; + _fixture = fixture; } [Fact] @@ -173,9 +183,10 @@ private static void ValidateActionResult(CollectionRuleActionResult result, stri Assert.Equal(expectedExitCode, actualExitCode); } - private static async Task ValidateAction(Action optionsCallback, Func actionCallback) + private async Task ValidateAction(Action optionsCallback, Func actionCallback) { - ExecuteActionFactory factory = new(); + var validationOptions = _fixture.Services.GetService>(); + ExecuteActionFactory factory = new(_fixture.Services, validationOptions); ExecuteOptions options = new(); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/AuthenticationTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/AuthenticationTests.cs index e13ae742e76..555348cba9d 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/AuthenticationTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests/AuthenticationTests.cs @@ -472,9 +472,6 @@ public async Task AllowsConfiguredIssuer() [Theory] // Guids that don't match should get rejected [InlineData("980d2b17-71e1-4313-a084-c077e962680c", "10253b7a-454d-41bb-a3f5-5f2e6b26ed93", HttpStatusCode.Forbidden)] - // Empty string isn't valid even when signed and configured correctly - [InlineData("", "", HttpStatusCode.Unauthorized)] - [InlineData("10253b7a-454d-41bb-a3f5-5f2e6b26ed93", "", HttpStatusCode.Unauthorized)] [InlineData("", "10253b7a-454d-41bb-a3f5-5f2e6b26ed93", HttpStatusCode.Forbidden)] public async Task RejectsBadSubject(string jwtSubject, string configSubject, HttpStatusCode expectedError) { @@ -501,6 +498,25 @@ public async Task RejectsBadSubject(string jwtSubject, string configSubject, Htt Assert.Equal(expectedError, statusCodeException.StatusCode); } + /// + /// This tests that an empty configured subject fails on startup. + /// + [Fact] + public async Task DoesNotStart_With_EmptySubject() + { + var configSubject = ""; + await using MonitorCollectRunner toolRunner = new(_outputHelper); + toolRunner.DisableMetricsViaCommandLine = true; + + _outputHelper.WriteLine("Generating API key."); + + JwtPayload newPayload = GetJwtPayload(AuthConstants.ApiKeyJwtAudience, configSubject, AuthConstants.ApiKeyJwtInternalIssuer, AuthConstants.ApiKeyJwtDefaultExpiration); + + toolRunner.ConfigurationFromEnvironment.UseApiKey(SecurityAlgorithms.EcdsaSha384, configSubject, newPayload, out string token); + + await Assert.ThrowsAsync(toolRunner.StartAsync); + } + [Fact] public async Task RejectsMissingExpiration() { diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj index d8db2356aea..5f0b9f3f651 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon.csproj @@ -3,6 +3,7 @@ $(ToolTargetFrameworks) true + true diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs index 02c48fa9433..795b4fb01e9 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestHostHelper.cs @@ -124,6 +124,8 @@ public static IHost CreateHost( services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + ValidatableTypes.AddValidation(services); + TestValidatableTypes.AddValidation(services); servicesCallback?.Invoke(services); }) .Build(); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs new file mode 100644 index 00000000000..f2b2bd4ead0 --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/TestValidatableType.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Http.Validation; +using Microsoft.AspNetCore.Http.Validation.Generated; +using Microsoft.Extensions.DependencyInjection; + +namespace Microsoft.Diagnostics.Monitoring.TestCommon +{ + [ValidatableType] + internal sealed class TestValidatableTypes + { + public required PassThroughOptions PassThroughOptions { get; init; } + + public static void AddValidation(IServiceCollection services) + { + TestGeneratedServiceCollectionExtensions.AddValidation(services); + } + } +} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs new file mode 100644 index 00000000000..4a06b0908ac --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs @@ -0,0 +1,752 @@ +#nullable enable annotations +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ +#nullable enable + +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; + +namespace System.Runtime.CompilerServices +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : System.Attribute + { + public InterceptsLocationAttribute(int version, string data) + { + } + } +} + +namespace Microsoft.AspNetCore.Http.Validation.Generated +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file sealed class GeneratedValidatablePropertyInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatablePropertyInfo + { + public GeneratedValidatablePropertyInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] + global::System.Type containingType, + global::System.Type propertyType, + string name, + string displayName) : base(containingType, propertyType, name, displayName) + { + ContainingType = containingType; + Name = name; + } + + internal global::System.Type ContainingType { get; } + internal string Name { get; } + + protected override global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes() + => ValidationAttributeCache.GetValidationAttributes(ContainingType, Name); + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file sealed class GeneratedValidatableTypeInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatableTypeInfo + { + public GeneratedValidatableTypeInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.Interfaces)] + global::System.Type type, + ValidatablePropertyInfo[] members) : base(type, members) { } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file class GeneratedValidatableInfoResolver : global::Microsoft.AspNetCore.Http.Validation.IValidatableInfoResolver + { + public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) + { + validatableInfo = null; + if (type == typeof(global::System.Reflection.MethodBase)) + { + validatableInfo = CreateMethodBase(); + return true; + } + if (type == typeof(global::System.Reflection.ConstructorInfo)) + { + validatableInfo = CreateConstructorInfo(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeTypedArgument)) + { + validatableInfo = CreateCustomAttributeTypedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeNamedArgument)) + { + validatableInfo = CreateCustomAttributeNamedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeData)) + { + validatableInfo = CreateCustomAttributeData(); + return true; + } + if (type == typeof(global::System.Reflection.ParameterInfo)) + { + validatableInfo = CreateParameterInfo(); + return true; + } + if (type == typeof(global::System.Reflection.MethodInfo)) + { + validatableInfo = CreateMethodInfo(); + return true; + } + if (type == typeof(global::System.Reflection.EventInfo)) + { + validatableInfo = CreateEventInfo(); + return true; + } + if (type == typeof(global::System.Reflection.FieldInfo)) + { + validatableInfo = CreateFieldInfo(); + return true; + } + if (type == typeof(global::System.Reflection.PropertyInfo)) + { + validatableInfo = CreatePropertyInfo(); + return true; + } + if (type == typeof(global::System.Reflection.TypeInfo)) + { + validatableInfo = CreateTypeInfo(); + return true; + } + if (type == typeof(global::System.Reflection.Assembly)) + { + validatableInfo = CreateAssembly(); + return true; + } + if (type == typeof(global::System.Guid)) + { + validatableInfo = CreateGuid(); + return true; + } + if (type == typeof(global::System.Reflection.Module)) + { + validatableInfo = CreateModule(); + return true; + } + if (type == typeof(global::System.Reflection.MemberInfo)) + { + validatableInfo = CreateMemberInfo(); + return true; + } + if (type == typeof(global::System.Type)) + { + validatableInfo = CreateType(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions)) + { + validatableInfo = CreateBaseRecordOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions)) + { + validatableInfo = CreatePassThroughOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes)) + { + validatableInfo = CreateTestValidatableTypes(); + return true; + } + + return false; + } + + // No-ops, rely on runtime code for ParameterInfo-based resolution + public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterInfo parameterInfo, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) + { + validatableInfo = null; + return false; + } + + private ValidatableTypeInfo CreateMethodBase() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodBase), + members: [] + ); + } + private ValidatableTypeInfo CreateConstructorInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ConstructorInfo), + members: [] + ); + } + private ValidatableTypeInfo CreateCustomAttributeTypedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeTypedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + propertyType: typeof(global::System.Type), + name: "ArgumentType", + displayName: "ArgumentType" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeNamedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeNamedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "MemberInfo", + displayName: "MemberInfo" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + name: "TypedValue", + displayName: "TypedValue" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeData() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeData), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Type), + name: "AttributeType", + displayName: "AttributeType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "Constructor", + displayName: "Constructor" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "ConstructorArguments", + displayName: "ConstructorArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "NamedArguments", + displayName: "NamedArguments" + ), + ] + ); + } + private ValidatableTypeInfo CreateParameterInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ParameterInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "Member", + displayName: "Member" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Type), + name: "ParameterType", + displayName: "ParameterType" + ), + ] + ); + } + private ValidatableTypeInfo CreateMethodInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.ParameterInfo), + name: "ReturnParameter", + displayName: "ReturnParameter" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Type), + name: "ReturnType", + displayName: "ReturnType" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.EventInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "AddMethod", + displayName: "AddMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Type), + name: "EventHandlerType", + displayName: "EventHandlerType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RaiseMethod", + displayName: "RaiseMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RemoveMethod", + displayName: "RemoveMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateFieldInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.FieldInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Type), + name: "FieldType", + displayName: "FieldType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + ] + ); + } + private ValidatableTypeInfo CreatePropertyInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.PropertyInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "GetMethod", + displayName: "GetMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Type), + name: "PropertyType", + displayName: "PropertyType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "SetMethod", + displayName: "SetMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateTypeInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.TypeInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredConstructors", + displayName: "DeclaredConstructors" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredEvents", + displayName: "DeclaredEvents" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredFields", + displayName: "DeclaredFields" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMembers", + displayName: "DeclaredMembers" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMethods", + displayName: "DeclaredMethods" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredNestedTypes", + displayName: "DeclaredNestedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredProperties", + displayName: "DeclaredProperties" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ImplementedInterfaces", + displayName: "ImplementedInterfaces" + ), + ] + ); + } + private ValidatableTypeInfo CreateAssembly() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Assembly), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DefinedTypes", + displayName: "DefinedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "EntryPoint", + displayName: "EntryPoint" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ExportedTypes", + displayName: "ExportedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.Module), + name: "ManifestModule", + displayName: "ManifestModule" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "Modules", + displayName: "Modules" + ), + ] + ); + } + private ValidatableTypeInfo CreateGuid() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Guid), + members: [ + // https://github.com/dotnet/aspnetcore/issues/61525 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::System.Guid), + // propertyType: typeof(global::System.Guid), + // name: "AllBitsSet", + // displayName: "AllBitsSet" + // ), + ] + ); + } + private ValidatableTypeInfo CreateModule() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Module), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Guid), + name: "ModuleVersionId", + displayName: "ModuleVersionId" + ), + ] + ); + } + private ValidatableTypeInfo CreateMemberInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MemberInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + ] + ); + } + private ValidatableTypeInfo CreateType() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Type), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "BaseType", + displayName: "BaseType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MethodBase), + name: "DeclaringMethod", + displayName: "DeclaringMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type[]), + name: "GenericTypeArguments", + displayName: "GenericTypeArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Guid), + name: "GUID", + displayName: "GUID" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "TypeInitializer", + displayName: "TypeInitializer" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "UnderlyingSystemType", + displayName: "UnderlyingSystemType" + ), + ] + ); + } + private ValidatableTypeInfo CreateBaseRecordOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + members: [ + ] + ); + } + private ValidatableTypeInfo CreatePassThroughOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), + members: [] + ); + } + private ValidatableTypeInfo CreateTestValidatableTypes() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.TestValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), + name: "PassThroughOptions", + displayName: "PassThroughOptions" + ), + ] + ); + } + + } + + internal static class TestGeneratedServiceCollectionExtensions + { + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(global::Microsoft.Extensions.DependencyInjection.IServiceCollection services) + { + return GeneratedServiceCollectionExtensions.AddValidation(services); + } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file static class GeneratedServiceCollectionExtensions + { + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + { + // Use non-extension method to avoid infinite recursion. + return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => + { + options.Resolvers.Insert(0, new GeneratedValidatableInfoResolver()); + options.Resolvers.Add(new CustomValidatableInfoResolver()); + if (configureOptions is not null) + { + configureOptions(options); + } + }); + } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file static class ValidationAttributeCache + { + private sealed record CacheKey(global::System.Type ContainingType, string PropertyName); + private static readonly global::System.Collections.Concurrent.ConcurrentDictionary _cache = new(); + + public static global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes( + global::System.Type containingType, + string propertyName) + { + var key = new CacheKey(containingType, propertyName); + return _cache.GetOrAdd(key, static k => + { + var results = new global::System.Collections.Generic.List(); + + // Get attributes from the property + var property = k.ContainingType.GetProperty(k.PropertyName); + if (property != null) + { + var propertyAttributes = global::System.Reflection.CustomAttributeExtensions + .GetCustomAttributes(property, inherit: true); + + results.AddRange(propertyAttributes); + } + + // Check constructors for parameters that match the property name + // to handle record scenarios + foreach (var constructor in k.ContainingType.GetConstructors()) + { + // Look for parameter with matching name (case insensitive) + var parameter = global::System.Linq.Enumerable.FirstOrDefault( + constructor.GetParameters(), + p => string.Equals(p.Name, k.PropertyName, global::System.StringComparison.OrdinalIgnoreCase)); + + if (parameter != null) + { + var paramAttributes = global::System.Reflection.CustomAttributeExtensions + .GetCustomAttributes(parameter, inherit: true); + + results.AddRange(paramAttributes); + + break; + } + } + + return results.ToArray(); + }); + } + } +} diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs index 31cbb996d67..ed3ba328fda 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRuleOptionsTests.cs @@ -195,14 +195,12 @@ public Task CollectionRuleOptions_EventCounterTrigger_PropertyValidation() ex => { string[] failures = ex.Failures.ToArray(); - // Property validation failures will short-circuit the remainder of the validation - // rules, thus only observe 3 errors when one might expect 4 (the fourth being that - // either GreaterThan or LessThan should be specified). - Assert.Equal(3, failures.Length); + Assert.Equal(4, failures.Length); VerifyRequiredMessage(failures, 0, nameof(EventCounterOptions.ProviderName)); VerifyRequiredMessage(failures, 1, nameof(EventCounterOptions.CounterName)); VerifyRangeMessage(failures, 2, nameof(EventCounterOptions.SlidingWindowDuration), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue); + VerifyEitherRequiredMessage(failures, 3, nameof(EventCounterOptions.GreaterThan), nameof(EventCounterOptions.LessThan)); }); } @@ -362,13 +360,12 @@ public Task CollectionRuleOptions_EventMeterTrigger_PropertyValidation() ex => { string[] failures = ex.Failures.ToArray(); - // Property validation failures will short-circuit the remainder of the validation - // rules, thus only observe 3 errors when one might expect 4 (GreaterThan or LessThan should be specified). - Assert.Equal(3, failures.Length); + Assert.Equal(4, failures.Length); VerifyRequiredMessage(failures, 0, nameof(EventMeterOptions.MeterName)); VerifyRequiredMessage(failures, 1, nameof(EventMeterOptions.InstrumentName)); VerifyRangeMessage(failures, 2, nameof(EventMeterOptions.SlidingWindowDuration), TriggerOptionsConstants.SlidingWindowDuration_MinValue, TriggerOptionsConstants.SlidingWindowDuration_MaxValue); + VerifyEitherRequiredMessage(failures, 3, nameof(EventMeterOptions.GreaterThan), nameof(EventMeterOptions.LessThan)); }); } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs index 75ca11aca3d..a3889d34d03 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/CollectionRulePipelineTests.cs @@ -473,8 +473,8 @@ public Task CollectionRulePipeline_ActionCountLimitSlidingDurationTest(TargetFra { const int IterationCount = 5; const int ExpectedActionExecutionCount = 3; - TimeSpan SlidingWindowDuration = TimeSpan.FromMilliseconds(100); - TimeSpan ClockIncrementDuration = TimeSpan.FromMilliseconds(10); + TimeSpan SlidingWindowDuration = TimeSpan.FromMilliseconds(1000); + TimeSpan ClockIncrementDuration = TimeSpan.FromMilliseconds(100); MockTimeProvider timeProvider = new(); ManualTriggerService triggerService = new(); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs index b3794d70476..1dd630b3384 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/ExtensionManifestTests.cs @@ -1,8 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.AspNetCore.Mvc.Testing; using System.IO; using System.Text.Json; using Xunit; @@ -10,18 +14,24 @@ namespace Microsoft.Diagnostics.Monitoring.Tool.UnitTests { + public class ExtensionManifestFixture : WebApplicationFactory + { + } + [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] - public sealed class ExtensionManifestTests + public sealed class ExtensionManifestTests : IClassFixture { private const string ExpectedName = "CustomEgress"; private const string ExpectedExecutableName = "CustomExecutable"; private const string ExpectedAssemblyName = "CustomAssembly"; private readonly ITestOutputHelper _outputHelper; + private readonly ExtensionManifestFixture _fixture; - public ExtensionManifestTests(ITestOutputHelper outputHelper) + public ExtensionManifestTests(ITestOutputHelper outputHelper, ExtensionManifestFixture fixture) { _outputHelper = outputHelper; + _fixture = fixture; } [Fact] @@ -91,7 +101,8 @@ public void ExtensionManifest_EmptyObject_ThrowOnValidate() Assert.Null(manifest.AssemblyFileName); Assert.Null(manifest.ExecutableFileName); - ExtensionException ex = Assert.Throws(manifest.Validate); + var validationOptions = _fixture.Services.GetRequiredService>().Value; + ExtensionException ex = Assert.Throws(() => manifest.Validate(_fixture.Services, validationOptions)); Assert.Null(ex.InnerException); } @@ -115,7 +126,8 @@ public void ExtensionManifest_NameOnly_ThrowOnValidate() Assert.Null(manifest.AssemblyFileName); Assert.Null(manifest.ExecutableFileName); - ExtensionException ex = Assert.Throws(manifest.Validate); + var validationOptions = _fixture.Services.GetRequiredService>().Value; + ExtensionException ex = Assert.Throws(() => manifest.Validate(_fixture.Services, validationOptions)); Assert.Null(ex.InnerException); } @@ -141,7 +153,8 @@ public void ExtensionManifest_ExecutableAndAssembly_ThrowOnValidate() Assert.Equal(ExpectedAssemblyName, manifest.AssemblyFileName); Assert.Equal(ExpectedExecutableName, manifest.ExecutableFileName); - ExtensionException ex = Assert.Throws(manifest.Validate); + var validationOptions = _fixture.Services.GetRequiredService>().Value; + ExtensionException ex = Assert.Throws(() => manifest.Validate(_fixture.Services, validationOptions)); Assert.Null(ex.InnerException); } @@ -166,7 +179,8 @@ public void ExtensionManifest_NameAndAssembly_Valid() Assert.Equal(ExpectedAssemblyName, manifest.AssemblyFileName); Assert.Null(manifest.ExecutableFileName); - manifest.Validate(); + var validationOptions = _fixture.Services.GetRequiredService>().Value; + manifest.Validate(_fixture.Services, validationOptions); } [Fact] @@ -190,7 +204,8 @@ public void ExtensionManifest_NameAndExecutable_Valid() Assert.Null(manifest.AssemblyFileName); Assert.Equal(ExpectedExecutableName, manifest.ExecutableFileName); - manifest.Validate(); + var validationOptions = _fixture.Services.GetRequiredService>().Value; + manifest.Validate(_fixture.Services, validationOptions); } private static Stream CreateManifestStream(TemporaryDirectory dir, out string path) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/FileSystemEgressExtensionTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/FileSystemEgressExtensionTests.cs index 9a9ba33bf8b..5989905b166 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/FileSystemEgressExtensionTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/FileSystemEgressExtensionTests.cs @@ -1,12 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; +using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Tools.Monitor; using Microsoft.Diagnostics.Tools.Monitor.Egress; using Microsoft.Diagnostics.Tools.Monitor.Egress.Configuration; using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Moq; @@ -22,8 +25,12 @@ namespace Microsoft.Diagnostics.Monitoring.Tool.UnitTests { + public class FileSystemEgressExtensionFixture : WebApplicationFactory + { + } + [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] - public sealed class FileSystemEgressExtensionTests + public sealed class FileSystemEgressExtensionTests : IClassFixture { const string ProviderName = "TestProvider"; const string ExpectedFileName = "EgressedData.txt"; @@ -35,10 +42,12 @@ public sealed class FileSystemEgressExtensionTests FileSystemEgressProviderOptions.CopyBufferSize_MaxValue.ToString()); private readonly ITestOutputHelper _outputHelper; + private readonly FileSystemEgressExtensionFixture _fixture; - public FileSystemEgressExtensionTests(ITestOutputHelper outputHelper) + public FileSystemEgressExtensionTests(ITestOutputHelper outputHelper, FileSystemEgressExtensionFixture fixture) { _outputHelper = outputHelper; + _fixture = fixture; } [Fact] @@ -145,7 +154,7 @@ public async Task FileSystemEgressExtension_IntermediateDirectoryPath_Success() Assert.False(intermediateDirInfo.EnumerateFiles().Any(), "Intermediate directory should not contain any files."); } - private static IEgressExtension CreateExtension(Action callback = null) + private IEgressExtension CreateExtension(Action callback = null) { List configProviders = new() { @@ -163,6 +172,8 @@ private static IEgressExtension CreateExtension(Action cal Mock> mockLogger = new(); Mock mockServiceProvider = new(); + mockServiceProvider.Setup(provider => provider.GetService(typeof(IOptions))) + .Returns(_fixture.Services.GetRequiredService>()); return new FileSystemEgressExtension(mockServiceProvider.Object, mockConfigurationProvider.Object, mockLogger.Object); } diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj index cb44deedb4b..43d46599cc9 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests.csproj @@ -8,6 +8,7 @@ + @@ -15,6 +16,7 @@ + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Options/AzureAdOptionsTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Options/AzureAdOptionsTests.cs index 95966d09f04..3ab0b08d058 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Options/AzureAdOptionsTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/Options/AzureAdOptionsTests.cs @@ -1,8 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; +using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Diagnostics.Monitoring.TestCommon; using Microsoft.Diagnostics.Tools.Monitor; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -10,9 +15,20 @@ namespace Microsoft.Diagnostics.Monitoring.Tool.UnitTests.Options { + public class AzureAdOptionsTestsFixture : WebApplicationFactory + { + } + [TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)] - public class AzureAdOptionsTests + public class AzureAdOptionsTests : IClassFixture { + private readonly AzureAdOptionsTestsFixture _fixture; + + public AzureAdOptionsTests(AzureAdOptionsTestsFixture fixture) + { + _fixture = fixture; + } + private static AzureAdOptions GetDefaultOptions() { return new AzureAdOptions @@ -32,9 +48,10 @@ public void AzureAdOptions_Requires_Role() options.RequiredRole = null; List results = new(); + var validationOptions = _fixture.Services.GetRequiredService>().Value; // Act - bool isValid = Validator.TryValidateObject(options, new(options), results, validateAllProperties: true); + bool isValid = ValidationHelper.TryValidateObject(options, typeof(AzureAdOptions), validationOptions, _fixture.Services, results); // Assert Assert.False(isValid); @@ -50,9 +67,10 @@ public void AzureAdOptions_Requires_TenantId() options.TenantId = null; List results = new(); + var validationOptions = _fixture.Services.GetRequiredService>().Value; // Act - bool isValid = Validator.TryValidateObject(options, new(options), results, validateAllProperties: true); + bool isValid = ValidationHelper.TryValidateObject(options, typeof(AzureAdOptions), validationOptions, _fixture.Services, results); // Assert Assert.False(isValid); @@ -68,9 +86,10 @@ public void AzureAdOptions_Requires_ClientId() options.ClientId = null; List results = new(); + var validationOptions = _fixture.Services.GetRequiredService>().Value; // Act - bool isValid = Validator.TryValidateObject(options, new(options), results, validateAllProperties: true); + bool isValid = ValidationHelper.TryValidateObject(options, typeof(AzureAdOptions), validationOptions, _fixture.Services, results); // Assert Assert.False(isValid); diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj new file mode 100644 index 00000000000..6b94db64edf --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample.csproj @@ -0,0 +1,13 @@ + + + + $(ToolTargetFrameworks) + enable + enable + + + + + + + diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs new file mode 100644 index 00000000000..00b3a88b98f --- /dev/null +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestsSample/Program.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Diagnostics.Tools.Monitor; + +var builder = WebApplication.CreateBuilder(new WebApplicationOptions +{ + ContentRootPath = AppContext.BaseDirectory +}); + +ValidatableTypes.AddValidation(builder.Services); +builder.Build(); + +public partial class Program {} diff --git a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs index 2cae0a91b75..1746ba63581 100644 --- a/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs +++ b/src/Tools/dotnet-monitor/Auth/ApiKey/MonitorApiKeyPostConfigure.cs @@ -1,7 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; @@ -21,20 +24,25 @@ internal sealed class MonitorApiKeyPostConfigure : { private readonly ILogger _logger; private readonly IOptionsMonitor _apiKeyOptions; + private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public MonitorApiKeyPostConfigure( + IServiceProvider serviceProvider, ILogger logger, IOptionsMonitor apiKeyOptions) { _logger = logger; _apiKeyOptions = apiKeyOptions; + _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public void PostConfigure(string? name, MonitorApiKeyConfiguration options) { MonitorApiKeyOptions sourceOptions = _apiKeyOptions.CurrentValue; - IList errors = new List(); + List errors = new List(); // If nothing is set, lets not attach an error and instead pass along the blank config if (sourceOptions.Subject == null && sourceOptions.PublicKey == null) @@ -48,11 +56,12 @@ public void PostConfigure(string? name, MonitorApiKeyConfiguration options) // Some options are configured (but may not be valid) options.Configured = true; - Validator.TryValidateObject( + ValidationHelper.TryValidateObject( sourceOptions, - new ValidationContext(sourceOptions, null, null), - errors, - validateAllProperties: true); + typeof(MonitorApiKeyOptions), + _validationOptions, + _serviceProvider, + errors); string? jwkJson = null; try diff --git a/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs b/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs index c4dbc2bab83..c2fb4aa8be5 100644 --- a/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs +++ b/src/Tools/dotnet-monitor/Auth/AuthConfiguratorFactory.cs @@ -1,10 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Tools.Monitor.Auth.ApiKey; using Microsoft.Diagnostics.Tools.Monitor.Auth.AzureAd; using Microsoft.Diagnostics.Tools.Monitor.Auth.NoAuth; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Extensions.Hosting; using System; using System.Collections.Generic; @@ -21,7 +25,7 @@ internal enum StartupAuthenticationMode internal static class AuthConfiguratorFactory { - public static IAuthenticationConfigurator Create(StartupAuthenticationMode startupAuthMode, HostBuilderContext context) + public static IAuthenticationConfigurator Create(StartupAuthenticationMode startupAuthMode, HostBuilderContext context, IServiceProvider services) { switch (startupAuthMode) { @@ -46,12 +50,12 @@ public static IAuthenticationConfigurator Create(StartupAuthenticationMode start if (authConfigSection.Exists()) { authConfigSection.Bind(authOptions); - ValidateAuthConfigSection(authOptions, authConfigSection.Path); + ValidateAuthConfigSection(authOptions, authConfigSection.Path, services); } if (authOptions.AzureAd != null) { - ValidateAuthConfigSection(authOptions.AzureAd, ConfigurationPath.Combine(authConfigSection.Path, ConfigurationKeys.AzureAd)); + ValidateAuthConfigSection(authOptions.AzureAd, ConfigurationPath.Combine(authConfigSection.Path, ConfigurationKeys.AzureAd), services); return new AzureAdAuthConfigurator(authOptions.AzureAd); } @@ -62,10 +66,11 @@ public static IAuthenticationConfigurator Create(StartupAuthenticationMode start } } - private static void ValidateAuthConfigSection(T options, string configurationPath) where T : notnull + private static void ValidateAuthConfigSection(T options, string configurationPath, IServiceProvider services) where T : notnull { + var validationOptions = services.GetRequiredService>().Value; List results = new(); - if (!Validator.TryValidateObject(options, new ValidationContext(options), results, validateAllProperties: true)) + if (!ValidationHelper.TryValidateObject(options, typeof(T), validationOptions, services, results)) { throw new DeferredAuthenticationValidationException(configurationPath, results); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs index e4a3debe39a..5ac03df9147 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectDumpAction.cs @@ -1,14 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions @@ -17,10 +19,12 @@ internal sealed class CollectDumpActionFactory : ICollectionRuleActionFactory { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public CollectDumpActionFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, CollectDumpOptions options) @@ -30,8 +34,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectDumpOptions throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectDumpOptions), _validationOptions, _serviceProvider); return new CollectDumpAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs index f9156e83d77..54d507def57 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectExceptionsAction.cs @@ -1,19 +1,30 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Microsoft.Extensions.Configuration; using System; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions { internal sealed class CollectExceptionsActionFactory : ICollectionRuleActionFactory { + private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; + + public CollectExceptionsActionFactory(IServiceProvider serviceProvider, IOptions validationOptions) + { + _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = validationOptions?.Value ?? throw new ArgumentNullException(nameof(validationOptions)); + } + public ICollectionRuleAction Create(IProcessInfo processInfo, CollectExceptionsOptions options) { if (null == options) @@ -21,8 +32,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectExceptionsO throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, processInfo.EndpointInfo.ServiceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectExceptionsOptions), _validationOptions, _serviceProvider); return new CollectExceptionsAction(processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs index b2ab4445160..c6c802d18ed 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectGCDumpAction.cs @@ -5,9 +5,11 @@ using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using System; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions @@ -16,10 +18,12 @@ internal sealed class CollectGCDumpActionFactory : ICollectionRuleActionFactory { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public CollectGCDumpActionFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, CollectGCDumpOptions options) @@ -28,9 +32,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectGCDumpOptio { throw new ArgumentNullException(nameof(options)); } - - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectGCDumpOptions), _validationOptions, _serviceProvider); return new CollectGCDumpAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs index 26200990c76..b089b6fb95b 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLiveMetricsAction.cs @@ -1,16 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.EventPipe; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions @@ -19,10 +20,12 @@ internal sealed class CollectLiveMetricsActionFactory : ICollectionRuleActionFactory { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public CollectLiveMetricsActionFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, CollectLiveMetricsOptions options) @@ -32,8 +35,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectLiveMetrics throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectLiveMetricsOptions), _validationOptions, _serviceProvider); return new CollectLiveMetricsAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs index c76deac2531..eb1593d3270 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectLogsAction.cs @@ -1,17 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.EventPipe; using Microsoft.Diagnostics.Monitoring.Options; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions @@ -20,10 +22,12 @@ internal sealed class CollectLogsActionFactory : ICollectionRuleActionFactory { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public CollectLogsActionFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, CollectLogsOptions options) @@ -33,8 +37,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectLogsOptions throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectLogsOptions), _validationOptions, _serviceProvider); return new CollectLogsAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs index 8001d0e99d7..c18372eb01a 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectStacksAction.cs @@ -1,13 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Microsoft.Extensions.Configuration; using System; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions @@ -15,10 +17,12 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions internal sealed class CollectStacksActionFactory : ICollectionRuleActionFactory { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public CollectStacksActionFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, CollectStacksOptions options) @@ -28,8 +32,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectStacksOptio throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectStacksOptions), _validationOptions, _serviceProvider); return new CollectStacksAction(_serviceProvider, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs index 92b7f9c43f4..8fe4df71ce9 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectTraceAction.cs @@ -1,16 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.EventPipe; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Microsoft.Extensions.Configuration; using System; -using System.ComponentModel.DataAnnotations; using Utils = Microsoft.Diagnostics.Monitoring.WebApi.Utilities; namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions @@ -19,6 +20,7 @@ internal sealed class CollectTraceActionFactory : ICollectionRuleActionFactory { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public ICollectionRuleAction Create(IProcessInfo processInfo, CollectTraceOptions options) { @@ -27,8 +29,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectTraceOption throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(CollectTraceOptions), _validationOptions, _serviceProvider); return new CollectTraceAction(_serviceProvider, processInfo, options); } @@ -36,6 +37,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, CollectTraceOption public CollectTraceActionFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } private sealed class CollectTraceAction : diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs index 746af4f906a..e92f1510ff9 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/CollectionRuleActionOperations.cs @@ -89,7 +89,7 @@ public bool TryValidateOptions( } else { - results.Add(new ValidationResult(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownActionType, actionName))); + results.Add(new ValidationResult(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownActionType, actionName), [actionName])); return false; } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs index 000120179a0..4b5a331a482 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/ExecuteAction.cs @@ -1,14 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.EventPipe; using Microsoft.Diagnostics.Monitoring.WebApi; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Extensions.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.Globalization; using System.IO; @@ -20,6 +22,15 @@ namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Actions internal sealed class ExecuteActionFactory : ICollectionRuleActionFactory { + private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; + + public ExecuteActionFactory(IServiceProvider serviceProvider, IOptions validationOptions) + { + _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = validationOptions?.Value ?? throw new ArgumentNullException(nameof(validationOptions)); + } + public ICollectionRuleAction Create(IProcessInfo processInfo, ExecuteOptions options) { if (null == options) @@ -27,8 +38,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, ExecuteOptions opt throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, null, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(ExecuteOptions), _validationOptions, _serviceProvider); return new ExecuteAction(processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs index b7a8fe7d44f..9c3cfd17d41 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/GetEnvironmentVariableAction.cs @@ -1,15 +1,18 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.NETCore.Client; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; using System.Threading; using System.Threading.Tasks; @@ -20,11 +23,13 @@ internal sealed partial class GetEnvironmentVariableActionFactory : { private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; + private readonly ValidationOptions _validationOptions; public GetEnvironmentVariableActionFactory(IServiceProvider serviceProvider, ILogger logger) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); _logger = logger ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, GetEnvironmentVariableOptions options) @@ -34,8 +39,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, GetEnvironmentVari throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(GetEnvironmentVariableOptions), _validationOptions, _serviceProvider); return new GetEnvironmentVariableAction(_logger, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs index 7f9770c9428..0aea0697b97 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/LoadProfilerAction.cs @@ -1,14 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.NETCore.Client; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Configuration; using System; -using System.ComponentModel.DataAnnotations; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System.Threading; using System.Threading.Tasks; @@ -19,11 +22,13 @@ internal sealed class LoadProfilerActionFactory : { private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; + private readonly ValidationOptions _validationOptions; public LoadProfilerActionFactory(IServiceProvider serviceProvider, ILogger logger) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); _logger = logger ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, LoadProfilerOptions options) @@ -33,8 +38,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, LoadProfilerOption throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(LoadProfilerOptions), _validationOptions, _serviceProvider); return new LoadProfilerAction(_logger, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs b/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs index b40b78a4041..59b3f8a3ae1 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Actions/SetEnvironmentVariableAction.cs @@ -1,14 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.NETCore.Client; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Configuration; using Microsoft.Extensions.Configuration; using System; -using System.ComponentModel.DataAnnotations; using System.Threading; using System.Threading.Tasks; @@ -19,11 +22,13 @@ internal sealed partial class SetEnvironmentVariableActionFactory : { private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; + private readonly ValidationOptions _validationOptions; public SetEnvironmentVariableActionFactory(IServiceProvider serviceProvider, ILogger logger) { _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ICollectionRuleAction Create(IProcessInfo processInfo, SetEnvironmentVariableOptions options) @@ -33,8 +38,7 @@ public ICollectionRuleAction Create(IProcessInfo processInfo, SetEnvironmentVari throw new ArgumentNullException(nameof(options)); } - ValidationContext context = new(options, _serviceProvider, items: null); - Validator.ValidateObject(options, context, validateAllProperties: true); + ValidationHelper.ValidateObject(options, typeof(SetEnvironmentVariableOptions), _validationOptions, _serviceProvider); return new SetEnvironmentVariableAction(_logger, processInfo, options); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs index 1c412f58eaf..2a4a0817113 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Configuration/CollectionRulePostConfigureNamedOptions.cs @@ -56,7 +56,8 @@ private void ResolveActionList(CollectionRuleOptions ruleOptions, IConfiguration // The Section Key is the action index; the value (if present) is the name of the template if (SectionHasValue(actionSection)) { - TryGetTemplate(ruleOptions, _templateOptions.CollectionRuleActions, actionSection.Value, out CollectionRuleActionOptions templateActionOptions); + var memberName = nameof(ruleOptions.Actions) + "[" + ruleOptions.Actions.Count.ToString(CultureInfo.InvariantCulture) + "]"; + TryGetTemplate(ruleOptions, memberName, _templateOptions.CollectionRuleActions, actionSection.Value, out CollectionRuleActionOptions templateActionOptions); ruleOptions.Actions.Add(templateActionOptions); } @@ -79,7 +80,7 @@ private void ResolveTrigger(CollectionRuleOptions ruleOptions, IConfigurationSec if (SectionHasValue(section)) { - TryGetTemplate(ruleOptions, _templateOptions.CollectionRuleTriggers, section.Value, out CollectionRuleTriggerOptions triggerOptions); + TryGetTemplate(ruleOptions, nameof(ruleOptions.Trigger), _templateOptions.CollectionRuleTriggers, section.Value, out CollectionRuleTriggerOptions triggerOptions); ruleOptions.Trigger = triggerOptions; } @@ -100,7 +101,7 @@ private void ResolveFilterList(CollectionRuleOptions ruleOptions, IConfiguration // The Section Key is the filter index; the value (if present) is the name of the template if (SectionHasValue(filterSection)) { - TryGetTemplate(ruleOptions, _templateOptions.CollectionRuleFilters, filterSection.Value, out ProcessFilterDescriptor templateFilterOptions); + TryGetTemplate(ruleOptions, nameof(ruleOptions.Filters), _templateOptions.CollectionRuleFilters, filterSection.Value, out ProcessFilterDescriptor templateFilterOptions); ruleOptions.Filters.Add(templateFilterOptions); } @@ -121,18 +122,18 @@ private void ResolveLimits(CollectionRuleOptions ruleOptions, IConfigurationSect if (SectionHasValue(section)) { - TryGetTemplate(ruleOptions, _templateOptions.CollectionRuleLimits, section.Value, out CollectionRuleLimitsOptions limitsOptions); + TryGetTemplate(ruleOptions, nameof(ruleOptions.Limits), _templateOptions.CollectionRuleLimits, section.Value, out CollectionRuleLimitsOptions limitsOptions); ruleOptions.Limits = limitsOptions; } } - private static bool TryGetTemplate(CollectionRuleOptions ruleOptions, IDictionary templatesOptions, string templateKey, out T templatesValue) where T : new() + private static bool TryGetTemplate(CollectionRuleOptions ruleOptions, string memberName, IDictionary templatesOptions, string templateKey, out T templatesValue) where T : new() { if (!templatesOptions.TryGetValue(templateKey, out templatesValue)) { templatesValue = new(); - ruleOptions.ErrorList.Add(new ValidationResult(string.Format(CultureInfo.CurrentCulture, Strings.ErrorMessage_TemplateNotFound, templateKey))); + ruleOptions.ErrorList.Add(new ValidationResult(string.Format(CultureInfo.CurrentCulture, Strings.ErrorMessage_TemplateNotFound, templateKey), [memberName])); return false; } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.Validate.cs index 05cf725f5f4..01f2d44124d 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectExceptionsOptions.Validate.cs @@ -27,7 +27,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( CultureInfo.InvariantCulture, Strings.ErrorMessage_DisabledFeature, - nameof(CollectExceptionsAction)))); + nameof(CollectExceptionsAction)), [nameof(CollectExceptionsAction)])); } return results; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs index e8ede3ded8c..624db8b4c86 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectLogsOptions.Validate.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Extensions.Logging; @@ -23,7 +23,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali RequiredAttribute requiredAttribute = new(); EnumDataTypeAttribute enumValidationAttribute = new(typeof(LogLevel)); - ValidationContext filterSpecsContext = new(FilterSpecs, validationContext, validationContext.Items); + ValidationContext filterSpecsContext = new(FilterSpecs, nameof(FilterSpecs), validationContext, validationContext.Items); filterSpecsContext.MemberName = nameof(FilterSpecs); // Validate that the category is not null and that the level is a valid level value. diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.Validate.cs index 362985a54c8..27eee18bf69 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectStacksOptions.Validate.cs @@ -26,7 +26,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( CultureInfo.InvariantCulture, Strings.ErrorMessage_DisabledFeature, - nameof(CollectionRules.Actions.CollectStacksAction)))); + nameof(CollectionRules.Actions.CollectStacksAction)), [nameof(CollectionRules.Actions.CollectStacksAction)])); } return results; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs index 6874ec2354b..9107de46d08 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/CollectTraceOptions.Validate.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Monitoring.WebApi; using Microsoft.Diagnostics.Monitoring.WebApi.Models; using Microsoft.Diagnostics.Monitoring.WebApi.Validation; @@ -53,7 +54,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali CultureInfo.InvariantCulture, Strings.ErrorMessage_TwoFieldsCannotBeSpecified, nameof(Profile), - nameof(StoppingEvent)))); + nameof(StoppingEvent)), [nameof(Profile), nameof(StoppingEvent)])); } if (HasProviders()) @@ -66,7 +67,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali CultureInfo.InvariantCulture, Strings.ErrorMessage_TwoFieldsCannotBeSpecified, nameof(Profile), - nameof(Providers)))); + nameof(Providers)), [nameof(Profile), nameof(Providers)])); } } else if (HasProviders()) @@ -80,17 +81,20 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali } catch (OptionsValidationException e) { - results.AddRange(e.Failures.Select((string failure) => new ValidationResult(e.Message))); + results.AddRange(e.Failures.Select((string failure) => new ValidationResult(e.Message, [e.OptionsType.Name]))); } // Validate that each provider is valid. + // Necessary to work around the generated validation code not recursing into List? members: + // https://github.com/dotnet/aspnetcore/issues/61737 int index = 0; foreach (EventPipeProvider provider in Providers) { - ValidationContext providerContext = new(provider, validationContext, validationContext.Items); + ValidationContext providerContext = new(provider, nameof(Providers), validationContext, validationContext.Items); providerContext.MemberName = nameof(Providers) + "[" + index.ToString(CultureInfo.InvariantCulture) + "]"; - Validator.TryValidateObject(provider, providerContext, results, validateAllProperties: true); + var validationOptions = validationContext.GetRequiredService>().Value; + ValidationHelper.TryValidateObject(provider, typeof(EventPipeProvider), validationOptions, providerContext, results); if (counterOptions != null && !CounterValidator.ValidateProvider(counterOptions, provider, out string? errorMessage)) { @@ -108,7 +112,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali CultureInfo.InvariantCulture, Strings.ErrorMessage_TwoFieldsMissing, nameof(Profile), - nameof(Providers)))); + nameof(Providers)), [nameof(Profile), nameof(Providers)])); } if (HasStoppingEvent()) @@ -124,7 +128,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali Strings.ErrorMessage_MissingStoppingEventProvider, nameof(StoppingEvent), StoppingEvent.ProviderName, - nameof(Providers)))); + nameof(Providers)), [nameof(StoppingEvent), nameof(Providers)])); } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/RequiredGuidAttribute.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/RequiredGuidAttribute.cs index e23e9a230a4..117674c27f1 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/RequiredGuidAttribute.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/RequiredGuidAttribute.cs @@ -20,10 +20,14 @@ public override string FormatErrorMessage(string name) protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) { + if (validationContext.MemberName is null) + { + throw new ArgumentNullException(nameof(validationContext.MemberName)); + } if (!(value is Guid)) { return new ValidationResult( - FormatErrorMessage(validationContext.DisplayName)); + FormatErrorMessage(validationContext.DisplayName), [validationContext.MemberName]); } Guid guidVal = (Guid)value; @@ -31,7 +35,7 @@ public override string FormatErrorMessage(string name) if (guidVal == Guid.Empty) { return new ValidationResult( - FormatErrorMessage(validationContext.DisplayName)); + FormatErrorMessage(validationContext.DisplayName), [validationContext.MemberName]); } return ValidationResult.Success; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ValidateEgressProviderAttribute.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ValidateEgressProviderAttribute.cs index 5e77e45e06c..6743a5395a0 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ValidateEgressProviderAttribute.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Actions/ValidateEgressProviderAttribute.cs @@ -14,10 +14,14 @@ internal sealed class ValidateEgressProviderAttribute : { protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) { + if (validationContext.MemberName is null) + { + throw new ArgumentNullException(nameof(validationContext.MemberName)); + } if (!(value is string)) { return new ValidationResult( - FormatErrorMessage(validationContext.DisplayName)); + FormatErrorMessage(validationContext.DisplayName), [validationContext.MemberName]); } string egressProvider = (string)value; @@ -33,7 +37,7 @@ internal sealed class ValidateEgressProviderAttribute : string.Format( CultureInfo.InvariantCulture, Strings.ErrorMessage_EgressProviderDoesNotExist, - egressProvider)); + egressProvider), [validationContext.MemberName]); } return ValidationResult.Success; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.Validate.cs index 45d41c6977a..ede73aff565 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleActionOptions.Validate.cs @@ -18,6 +18,10 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali if (!string.IsNullOrEmpty(Type)) { + validationContext = new ValidationContext(this, displayName: nameof(Settings), validationContext, items: null) + { + MemberName = nameof(Settings) + }; actionOperations.TryValidateOptions(Type, Settings, validationContext, results); } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs index 141f2d4c30b..52ec0082a67 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/CollectionRuleOptions.Validate.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable disable @@ -24,21 +24,6 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali return results; } - ValidationContext filtersContext = new(Filters, validationContext, validationContext.Items); - filtersContext.MemberName = nameof(Filters); - ValidationHelper.TryValidateItems(Filters, filtersContext, results); - - if (null != Trigger) - { - ValidationContext triggerContext = new(Trigger, validationContext, validationContext.Items); - triggerContext.MemberName = nameof(Trigger); - Validator.TryValidateObject(Trigger, triggerContext, results); - } - - ValidationContext actionsContext = new(Actions, validationContext, validationContext.Items); - actionsContext.MemberName = nameof(Actions); - ValidationHelper.TryValidateItems(Actions, actionsContext, results); - var actionNames = new HashSet(StringComparer.Ordinal); foreach (CollectionRuleActionOptions option in Actions) { diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.Validate.cs index 44c132c45ee..689ba328238 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterOptions.Validate.cs @@ -19,7 +19,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( Strings.ErrorMessage_TwoFieldsMissing, nameof(GreaterThan), - nameof(LessThan)))); + nameof(LessThan)), [nameof(GreaterThan), nameof(LessThan)])); } else if (GreaterThan.HasValue && LessThan.HasValue && LessThan.Value < GreaterThan.Value) { @@ -28,7 +28,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( Strings.ErrorMessage_FieldMustBeLessThanOtherField, nameof(GreaterThan), - nameof(LessThan)))); + nameof(LessThan)), [nameof(GreaterThan), nameof(LessThan)])); } return results; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/IEventCounterShortcuts.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/IEventCounterShortcuts.Validate.cs index 5f81bfb93ca..8081f9df8d3 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/IEventCounterShortcuts.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventCounterShortcuts/IEventCounterShortcuts.Validate.cs @@ -19,7 +19,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( Strings.ErrorMessage_FieldMustBeLessThanOtherField, nameof(GreaterThan), - nameof(LessThan)))); + nameof(LessThan)), [nameof(GreaterThan), nameof(LessThan)])); } return results; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.Validate.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.Validate.cs index 3ac644373fb..30952baf8dd 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.Validate.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/Triggers/EventMeterOptions.Validate.cs @@ -19,7 +19,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( Strings.ErrorMessage_TwoFieldsMissing, nameof(GreaterThan), - nameof(LessThan)))); + nameof(LessThan)), [nameof(GreaterThan), nameof(LessThan)])); } else if (GreaterThan.HasValue && LessThan.HasValue && LessThan.Value < GreaterThan.Value) { @@ -28,7 +28,7 @@ IEnumerable IValidatableObject.Validate(ValidationContext vali string.Format( Strings.ErrorMessage_FieldMustBeLessThanOtherField, nameof(GreaterThan), - nameof(LessThan)))); + nameof(LessThan)), [nameof(GreaterThan), nameof(LessThan)])); } return results; diff --git a/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs b/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs index c99543df9c0..c6fd02c9f80 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs @@ -1,31 +1,23 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Reflection; +using System.Threading; +#if EXTENSION +namespace Microsoft.Diagnostics.Monitoring.Extension.Common +#else namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options +#endif { internal static class ValidationHelper { - public static void TryValidateItems(IEnumerable items, ValidationContext validationContext, ICollection results) - { - int index = 0; - foreach (object item in items) - { - ValidationContext itemContext = new(item, validationContext, validationContext.Items); - itemContext.MemberName = validationContext.MemberName + "[" + index.ToString() + "]"; - - Validator.TryValidateObject(item, itemContext, results); - - index++; - } - } - #nullable disable public static bool TryValidateOptions(Type optionsType, object options, ValidationContext validationContext, ICollection results) { @@ -45,7 +37,7 @@ public static bool TryValidateOptions(Type optionsType, object options, Validati { foreach (string failure in validateResult.Failures) { - results.Add(new ValidationResult(failure)); + results.Add(new ValidationResult(failure, [validationContext.MemberName])); hasFailedResults = true; } } @@ -59,6 +51,58 @@ public static bool TryValidateOptions(Type optionsType, object options, Validati return false; } } -#nullable restore +#nullable enable + + public static bool TryValidateObject(object options, Type type, ValidationOptions validationOptions, ValidationContext validationContext, ICollection results) + { + return TryValidateObject(options, type, validationOptions, validationContext, results); + } + + public static bool TryValidateObject(object options, Type type, ValidationOptions validationOptions, IServiceProvider serviceProvider, List results) + { + var validationContext = new ValidationContext(options, type.Name, serviceProvider, items: null) { + MemberName = type.Name + }; + return TryValidateObject(options, type, validationOptions, validationContext, results); + } + + public static bool TryValidateObject(object options, Type type, ValidationOptions validationOptions, ValidationContext validationContext, List results) + { + if (!validationOptions.TryGetValidatableTypeInfo(type, out IValidatableInfo? validatableTypeInfo)) + { + throw new Exception("No type info found for type " + type.FullName); + } + if (validationContext.MemberName is null) + { + throw new ArgumentNullException(nameof(validationContext.MemberName)); + } + var validateContext = new ValidateContext() + { + ValidationOptions = validationOptions, + ValidationContext = validationContext + }; + validatableTypeInfo.ValidateAsync(options, validateContext, CancellationToken.None).GetAwaiter().GetResult(); + if (validateContext.ValidationErrors is Dictionary validationErrors) + { + foreach (var (name, errors) in validationErrors) + { + foreach (var error in errors) + { + results.Add(new ValidationResult(error, [name])); + } + } + return false; + } + return true; + } + + public static void ValidateObject(object options, Type type, ValidationOptions validationOptions, IServiceProvider serviceProvider) + { + List results = new(); + if (!TryValidateObject(options, type, validationOptions, serviceProvider, results)) + { + throw new ValidationException(string.Join(Environment.NewLine, results.ConvertAll(r => r.ErrorMessage))); + } + } } } diff --git a/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs b/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs index efdf694c883..2c2ccc7d03b 100644 --- a/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs +++ b/src/Tools/dotnet-monitor/CollectionRules/Triggers/CollectionRuleTriggerOperations.cs @@ -107,7 +107,7 @@ public bool TryValidateOptions( } else { - results.Add(new ValidationResult(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownTriggerType, triggerName))); + results.Add(new ValidationResult(string.Format(CultureInfo.InvariantCulture, Strings.ErrorMessage_UnknownTriggerType, triggerName), [validationContext.MemberName])); return false; } } diff --git a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs index c16dcb791d5..6a0ac020fe0 100644 --- a/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs +++ b/src/Tools/dotnet-monitor/Commands/CollectCommandHandler.cs @@ -85,7 +85,7 @@ private static IHostBuilder Configure(this IHostBuilder builder, StartupAuthenti { return builder.ConfigureServices((HostBuilderContext context, IServiceCollection services) => { - IAuthenticationConfigurator authConfigurator = AuthConfiguratorFactory.Create(startupAuthMode, context); + IAuthenticationConfigurator authConfigurator = AuthConfiguratorFactory.Create(startupAuthMode, context, services.BuildServiceProvider()); services.AddSingleton(authConfigurator); //TODO Many of these service additions should be done through extension methods diff --git a/src/Tools/dotnet-monitor/CustomValidationInfo.cs b/src/Tools/dotnet-monitor/CustomValidationInfo.cs new file mode 100644 index 00000000000..3ecc73149d5 --- /dev/null +++ b/src/Tools/dotnet-monitor/CustomValidationInfo.cs @@ -0,0 +1,271 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Http.Validation; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using System.Threading; + +#nullable enable + +namespace Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options +{ + public class CustomValidatableInfoResolver : IValidatableInfoResolver + { + public bool TryGetValidatableTypeInfo(Type type, [NotNullWhen(true)] out IValidatableInfo? validatableInfo) + { + if (type == typeof(CollectionRuleOptions)) + { + validatableInfo = new CollectionRuleOptionsTypeInfo(); + return true; + } + + validatableInfo = null; + return false; + } + + public bool TryGetValidatableParameterInfo(ParameterInfo parameterInfo, [NotNullWhen(true)] out IValidatableInfo? validatableInfo) + { + validatableInfo = null; + return false; + } + + sealed class CollectionRuleOptionsTypeInfo : ValidatableTypeInfo + { + public CollectionRuleOptionsTypeInfo() + : this( + [ + new CustomValidatablePropertyInfo( + containingType: typeof(CollectionRuleOptions), + propertyType: typeof(CollectionRuleTriggerOptions), + name: "Trigger", + displayName: "Trigger" + ), + new CustomValidatablePropertyInfo( + containingType: typeof(CollectionRuleOptions), + propertyType: typeof(List), + name: "Actions", + displayName: "Actions" + ), + new CustomValidatablePropertyInfo( + containingType: typeof(CollectionRuleOptions), + propertyType: typeof(CollectionRuleLimitsOptions), + name: "Limits", + displayName: "Limits" + ) + ]) + { + } + + private CollectionRuleOptionsTypeInfo(ValidatablePropertyInfo[] members) + : base(typeof(CollectionRuleOptions), members) + { + Members = members; + _membersCount = members.Length; + } + + private readonly int _membersCount; + + internal IReadOnlyList Members { get; } + + public override async Task ValidateAsync(object? value, ValidateContext context, CancellationToken cancellationToken) + { + Debug.Assert(context.ValidationContext is not null); + if (value == null) + { + return; + } + + // Check if we've exceeded the maximum depth + if (context.CurrentDepth >= context.ValidationOptions.MaxDepth) + { + throw new InvalidOperationException( + $"Maximum validation depth of {context.ValidationOptions.MaxDepth} exceeded at '{context.CurrentValidationPath}' in '{nameof(CollectionRuleOptions)}'. " + + "This is likely caused by a circular reference in the object graph. " + + "Consider increasing the MaxDepth in ValidationOptions if deeper validation is required."); + } + + var originalPrefix = context.CurrentValidationPath; + + try + { + // Finally validate IValidatableObject if implemented + if (value is IValidatableObject validatable) + { + // Important: Set the DisplayName to the type name for top-level validations + // and restore the original validation context properties + var originalDisplayName = context.ValidationContext.DisplayName; + var originalMemberName = context.ValidationContext.MemberName; + + // Set the display name to the class name for IValidatableObject validation + context.ValidationContext.DisplayName = nameof(CollectionRuleOptions); + context.ValidationContext.MemberName = null; + + var validationResults = validatable.Validate(context.ValidationContext); + bool hasErrors = false; + foreach (var validationResult in validationResults) + { + if (validationResult != ValidationResult.Success && validationResult.ErrorMessage is not null) + { + var memberName = validationResult.MemberNames.First(); + var key = string.IsNullOrEmpty(originalPrefix) ? + memberName : + $"{originalPrefix}.{memberName}"; + + context.AddOrExtendValidationError(key, validationResult.ErrorMessage); + hasErrors = true; + } + } + + // Restore the original validation context properties + context.ValidationContext.DisplayName = originalDisplayName; + context.ValidationContext.MemberName = originalMemberName; + if (hasErrors) + { + return; + } + } + + // Validate members + for (var i = 0; i < _membersCount; i++) + { + await Members[i].ValidateAsync(value, context, cancellationToken); + context.CurrentValidationPath = originalPrefix; + } + } + finally + { + context.CurrentValidationPath = originalPrefix; + } + } + } + + sealed class CustomValidatablePropertyInfo : ValidatablePropertyInfo + { + public CustomValidatablePropertyInfo( + Type containingType, + Type propertyType, + string name, + string displayName) : base(containingType, propertyType, name, displayName) + { + ContainingType = containingType; + Name = name; + } + + internal Type ContainingType { get; } + internal string Name { get; } + + protected override ValidationAttribute[] GetValidationAttributes() + => ValidationAttributeCache.GetValidationAttributes(ContainingType, Name); + } + + static class ValidationAttributeCache + { + private sealed record CacheKey(Type ContainingType, string PropertyName); + private static readonly ConcurrentDictionary _cache = new(); + + public static ValidationAttribute[] GetValidationAttributes(Type containingType, string propertyName) + { + var key = new CacheKey(containingType, propertyName); + return _cache.GetOrAdd(key, static k => + { + var results = new List(); + + // Get attributes from the property + var property = k.ContainingType.GetProperty(k.PropertyName); + if (property != null) + { + var propertyAttributes = CustomAttributeExtensions.GetCustomAttributes(property, inherit: true); + + results.AddRange(propertyAttributes); + } + + // Check constructors for parameters that match the property name + // to handle record scenarios + foreach (var constructor in k.ContainingType.GetConstructors()) + { + // Look for parameter with matching name (case insensitive) + var parameter = Enumerable.FirstOrDefault( + constructor.GetParameters(), + p => string.Equals(p.Name, k.PropertyName, global::System.StringComparison.OrdinalIgnoreCase)); + + if (parameter != null) + { + var paramAttributes = CustomAttributeExtensions.GetCustomAttributes(parameter, inherit: true); + + results.AddRange(paramAttributes); + + break; + } + } + + return results.ToArray(); + }); + } + } + } + + internal static class TypeExtensions + { + public static List GetAllImplementedTypes([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] this Type type) + { + ArgumentNullException.ThrowIfNull(type); + + var implementedTypes = new List(); + + // Yield all interfaces directly and indirectly implemented by this type + foreach (var interfaceType in type.GetInterfaces()) + { + implementedTypes.Add(interfaceType); + } + + // Finally, walk up the inheritance chain + var baseType = type.BaseType; + while (baseType != null && baseType != typeof(object)) + { + implementedTypes.Add(baseType); + baseType = baseType.BaseType; + } + + return implementedTypes; + } + + public static bool ImplementsInterface(this Type type, Type interfaceType) + { + ArgumentNullException.ThrowIfNull(type); + ArgumentNullException.ThrowIfNull(interfaceType); + + // Check if interfaceType is actually an interface + if (!interfaceType.IsInterface) + { + throw new ArgumentException($"Type {interfaceType.FullName} is not an interface.", nameof(interfaceType)); + } + + return interfaceType.IsAssignableFrom(type); + } + } + + internal static class ValidateContextExtensions + { + internal static void AddOrExtendValidationError(this ValidateContext context, string key, string error) + { + context.ValidationErrors ??= []; + + if (context.ValidationErrors.TryGetValue(key, out var existingErrors) && !existingErrors.Contains(error)) + { + context.ValidationErrors[key] = [.. existingErrors, error]; + } + else + { + context.ValidationErrors[key] = [error]; + } + } + } +} diff --git a/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs b/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs index 2b6548a03b3..56c1583a83c 100644 --- a/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs +++ b/src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs @@ -3,11 +3,15 @@ #nullable enable +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Extensions.Options; +using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; +#if !EXTENSION +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +#endif #if EXTENSION namespace Microsoft.Diagnostics.Monitoring.Extension.Common @@ -20,33 +24,30 @@ internal sealed class DataAnnotationValidateOptions : where TOptions : class { private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; public DataAnnotationValidateOptions(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; + _validationOptions = serviceProvider.GetRequiredService>().Value; } public ValidateOptionsResult Validate(string? name, TOptions options) { - ValidationContext validationContext = new(options, _serviceProvider, null); - ICollection results = new Collection(); - if (!Validator.TryValidateObject(options, validationContext, results, validateAllProperties: true)) + var results = new List(); + if (!ValidationHelper.TryValidateObject(options, typeof(TOptions), _validationOptions, _serviceProvider, results)) { IList failures = new List(); foreach (ValidationResult result in results) { - if (ValidationResult.Success != result) + if (result.ErrorMessage is null) { -#nullable disable - failures.Add(result.ErrorMessage); -#nullable restore + throw new ArgumentNullException(nameof(result.ErrorMessage)); } + failures.Add(result.ErrorMessage); } - if (failures.Count > 0) - { - return ValidateOptionsResult.Fail(failures); - } + return ValidateOptionsResult.Fail(failures); } return ValidateOptionsResult.Success; diff --git a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs index fdcf814c0ac..aebb2074656 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtension.cs @@ -3,9 +3,12 @@ #nullable disable +using Microsoft.AspNetCore.Http.Validation; using Microsoft.Diagnostics.Tools.Monitor.Egress.Configuration; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using System; @@ -29,6 +32,8 @@ internal partial class EgressExtension : IExtension, IEgressExtension private readonly string _extensionPath; private readonly ILogger _logger; private readonly ExtensionManifest _manifest; + private readonly IServiceProvider _serviceProvider; + private readonly ValidationOptions _validationOptions; private readonly IDictionary _processEnvironmentVariables = new Dictionary(); private const int PayloadProtocolVersion = 1; @@ -38,12 +43,15 @@ public EgressExtension( ExtensionManifest manifest, string extensionPath, IEgressConfigurationProvider configurationProvider, - ILogger logger) + ILogger logger, + IServiceProvider serviceProvider) { _configurationProvider = configurationProvider ?? throw new ArgumentNullException(nameof(configurationProvider)); _extensionPath = extensionPath ?? throw new ArgumentNullException(nameof(extensionPath)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _manifest = manifest ?? throw new ArgumentNullException(nameof(manifest)); + _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + _validationOptions = serviceProvider.GetRequiredService>().Value; } /// @@ -107,7 +115,7 @@ public async Task EgressArtifact( ExtensionMode mode, CancellationToken token) { - _manifest.Validate(); + _manifest.Validate(_serviceProvider, _validationOptions); ProcessStartInfo pStart = new ProcessStartInfo() { diff --git a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs index dbc690c5bd5..eafe34882e3 100644 --- a/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs +++ b/src/Tools/dotnet-monitor/Egress/Extension/EgressExtensionFactory.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using Microsoft.Diagnostics.Tools.Monitor.Egress.Configuration; using Microsoft.Diagnostics.Tools.Monitor.Extensibility; using Microsoft.Extensions.Logging; @@ -11,18 +12,21 @@ internal sealed class EgressExtensionFactory { private readonly IEgressConfigurationProvider _configurationProvider; private readonly ILogger _logger; + private readonly IServiceProvider _serviceProvider; public EgressExtensionFactory( IEgressConfigurationProvider configurationProvider, - ILogger logger) + ILogger logger, + IServiceProvider serviceProvider) { _configurationProvider = configurationProvider; _logger = logger; + _serviceProvider = serviceProvider; } public IEgressExtension Create(ExtensionManifest manifest, string path) { - return new EgressExtension(manifest, path, _configurationProvider, _logger); + return new EgressExtension(manifest, path, _configurationProvider, _logger, _serviceProvider); } } } diff --git a/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs b/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs index 4af5efa5c31..faaab28ac3f 100644 --- a/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs +++ b/src/Tools/dotnet-monitor/Extensibility/ExtensionManifest.cs @@ -3,6 +3,8 @@ #nullable disable +using Microsoft.AspNetCore.Http.Validation; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Globalization; @@ -10,6 +12,7 @@ using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; namespace Microsoft.Diagnostics.Tools.Monitor.Extensibility { @@ -70,11 +73,10 @@ public static ExtensionManifest FromPath(string path) } } - public void Validate() + public void Validate(IServiceProvider serviceProvider, ValidationOptions validationOptions) { List results = new(); - if (!Validator.TryValidateObject(this, new ValidationContext(this), results, validateAllProperties: true) && - results.Count > 0) + if (!ValidationHelper.TryValidateObject(this, typeof(ExtensionManifest), validationOptions, serviceProvider, results)) { ExtensionException.ThrowInvalidManifest(results.First().ErrorMessage); } @@ -95,7 +97,8 @@ public IEnumerable Validate(ValidationContext validationContex CultureInfo.InvariantCulture, Strings.ErrorMessage_TwoFieldsCannotBeSpecified, nameof(AssemblyFileName), - nameof(ExecutableFileName)))); + nameof(ExecutableFileName)), + [nameof(AssemblyFileName), nameof(ExecutableFileName)])); } if (!hasAssemblyFileName && !hasExecutableFileName) @@ -106,7 +109,8 @@ public IEnumerable Validate(ValidationContext validationContex CultureInfo.InvariantCulture, Strings.ErrorMessage_TwoFieldsMissing, nameof(AssemblyFileName), - nameof(ExecutableFileName)))); + nameof(ExecutableFileName)), + [nameof(AssemblyFileName), nameof(ExecutableFileName)])); } return results; diff --git a/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs b/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs index ed3cb744a00..eea4de2f83e 100644 --- a/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs +++ b/src/Tools/dotnet-monitor/HostBuilder/HostBuilderHelper.cs @@ -131,6 +131,7 @@ public static IHostBuilder CreateHostBuilder(HostBuilderSettings settings) services.AddSingleton(listenResults); services.AddSingleton(); services.AddHostedService(); + ValidatableTypes.AddValidation(services); }) .ConfigureKestrel((context, options) => { diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs new file mode 100644 index 00000000000..372e3c0a249 --- /dev/null +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -0,0 +1,1455 @@ +#nullable enable annotations +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ +#nullable enable + +namespace System.Runtime.CompilerServices +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + file sealed class InterceptsLocationAttribute : System.Attribute + { + public InterceptsLocationAttribute(int version, string data) + { + } + } +} + +namespace Microsoft.AspNetCore.Http.Validation.Generated +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file sealed class GeneratedValidatablePropertyInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatablePropertyInfo + { + public GeneratedValidatablePropertyInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] + global::System.Type containingType, + global::System.Type propertyType, + string name, + string displayName) : base(containingType, propertyType, name, displayName) + { + ContainingType = containingType; + Name = name; + } + + internal global::System.Type ContainingType { get; } + internal string Name { get; } + + protected override global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes() + => ValidationAttributeCache.GetValidationAttributes(ContainingType, Name); + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file sealed class GeneratedValidatableTypeInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatableTypeInfo + { + public GeneratedValidatableTypeInfo( + [param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.Interfaces)] + global::System.Type type, + ValidatablePropertyInfo[] members) : base(type, members) { } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file class GeneratedValidatableInfoResolver : global::Microsoft.AspNetCore.Http.Validation.IValidatableInfoResolver + { + public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) + { + validatableInfo = null; + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions)) + { + validatableInfo = CreateMonitorApiKeyOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions)) + { + validatableInfo = CreateAzureAdOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions)) + { + validatableInfo = CreateAuthenticationOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions)) + { + validatableInfo = CreateGlobalCounterOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration)) + { + validatableInfo = CreateExceptionsConfiguration(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions)) + { + validatableInfo = CreateExceptionsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions)) + { + validatableInfo = CreateInProcessFeaturesOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions)) + { + validatableInfo = CreateCorsConfigurationOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions)) + { + validatableInfo = CreateEgressOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider)) + { + validatableInfo = CreateMetricProvider(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions)) + { + validatableInfo = CreateMetricsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions)) + { + validatableInfo = CreateCollectionRuleTriggerDefaultsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions)) + { + validatableInfo = CreateCollectionRuleLimitsDefaultsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions)) + { + validatableInfo = CreateCollectionRuleDefaultsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions)) + { + validatableInfo = CreateTemplateOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions)) + { + validatableInfo = CreateRootOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions)) + { + validatableInfo = CreateCollectDumpOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions)) + { + validatableInfo = CreateCollectExceptionsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions)) + { + validatableInfo = CreateCollectGCDumpOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions)) + { + validatableInfo = CreateCollectLiveMetricsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions)) + { + validatableInfo = CreateCollectLogsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions)) + { + validatableInfo = CreateCollectStacksOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter)) + { + validatableInfo = CreateTraceEventFilter(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions)) + { + validatableInfo = CreateCollectTraceOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider)) + { + validatableInfo = CreateEventPipeProvider(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions)) + { + validatableInfo = CreateExecuteOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions)) + { + validatableInfo = CreateGetEnvironmentVariableOptions(); + return true; + } + if (type == typeof(global::System.Guid)) + { + validatableInfo = CreateGuid(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions)) + { + validatableInfo = CreateLoadProfilerOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions)) + { + validatableInfo = CreateSetEnvironmentVariableOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions)) + { + validatableInfo = CreateCPUUsageOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions)) + { + validatableInfo = CreateGCHeapSizeOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions)) + { + validatableInfo = CreateThreadpoolQueueLengthOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions)) + { + validatableInfo = CreateAspNetRequestCountOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions)) + { + validatableInfo = CreateAspNetRequestDurationOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions)) + { + validatableInfo = CreateAspNetResponseStatusOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions)) + { + validatableInfo = CreateEventCounterOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions)) + { + validatableInfo = CreateEventMeterOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions)) + { + validatableInfo = CreateFileSystemEgressProviderOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest)) + { + validatableInfo = CreateExtensionManifest(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes)) + { + validatableInfo = CreateValidatableTypes(); + return true; + } + + return false; + } + + // No-ops, rely on runtime code for ParameterInfo-based resolution + public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterInfo parameterInfo, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo) + { + validatableInfo = null; + return false; + } + + private ValidatableTypeInfo CreateMonitorApiKeyOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + propertyType: typeof(string), + name: "Subject", + displayName: "Subject" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + propertyType: typeof(string), + name: "PublicKey", + displayName: "PublicKey" + ), + ] + ); + } + private ValidatableTypeInfo CreateAzureAdOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "TenantId", + displayName: "TenantId" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "ClientId", + displayName: "ClientId" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(global::System.Uri), + name: "AppIdUri", + displayName: "AppIdUri" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + propertyType: typeof(string), + name: "RequiredRole", + displayName: "RequiredRole" + ), + ] + ); + } + private ValidatableTypeInfo CreateAuthenticationOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions), + name: "MonitorApiKey", + displayName: "MonitorApiKey" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions), + name: "AzureAd", + displayName: "AzureAd" + ), + ] + ); + } + private ValidatableTypeInfo CreateGlobalCounterOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(float?), + name: "IntervalSeconds", + displayName: "IntervalSeconds" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(int?), + name: "MaxHistograms", + displayName: "MaxHistograms" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(int?), + name: "MaxTimeSeries", + displayName: "MaxTimeSeries" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Providers", + displayName: "Providers" + ), + ] + ); + } + private ValidatableTypeInfo CreateExceptionsConfiguration() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Exclude", + displayName: "Exclude" + ), + ] + ); + } + private ValidatableTypeInfo CreateExceptionsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + propertyType: typeof(int?), + name: "TopLevelLimit", + displayName: "TopLevelLimit" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + name: "CollectionFilters", + displayName: "CollectionFilters" + ), + ] + ); + } + private ValidatableTypeInfo CreateInProcessFeaturesOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsOptions), + name: "Exceptions", + displayName: "Exceptions" + ), + ] + ); + } + private ValidatableTypeInfo CreateCorsConfigurationOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + propertyType: typeof(string), + name: "AllowedOrigins", + displayName: "AllowedOrigins" + ), + ] + ); + } + private ValidatableTypeInfo CreateEgressOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "FileSystem", + displayName: "FileSystem" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Properties", + displayName: "Properties" + ), + ] + ); + } + private ValidatableTypeInfo CreateMetricProvider() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider), + propertyType: typeof(string), + name: "ProviderName", + displayName: "ProviderName" + ), + ] + ); + } + private ValidatableTypeInfo CreateMetricsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + propertyType: typeof(int?), + name: "MetricCount", + displayName: "MetricCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Providers", + displayName: "Providers" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleTriggerDefaultsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(int?), + name: "RequestCount", + displayName: "RequestCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(int?), + name: "ResponseCount", + displayName: "ResponseCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleLimitsDefaultsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(int?), + name: "ActionCount", + displayName: "ActionCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "ActionCountSlidingWindowDuration", + displayName: "ActionCountSlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RuleDuration", + displayName: "RuleDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleDefaultsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerDefaultsOptions), + name: "Triggers", + displayName: "Triggers" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsDefaultsOptions), + name: "Limits", + displayName: "Limits" + ), + ] + ); + } + private ValidatableTypeInfo CreateTemplateOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleFilters", + displayName: "CollectionRuleFilters" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleTriggers", + displayName: "CollectionRuleTriggers" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleActions", + displayName: "CollectionRuleActions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRuleLimits", + displayName: "CollectionRuleLimits" + ), + ] + ); + } + private ValidatableTypeInfo CreateRootOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions), + name: "Authentication", + displayName: "Authentication" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "CollectionRules", + displayName: "CollectionRules" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions), + name: "GlobalCounter", + displayName: "GlobalCounter" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.InProcessFeaturesOptions), + name: "InProcessFeatures", + displayName: "InProcessFeatures" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.CorsConfigurationOptions), + name: "CorsConfiguration", + displayName: "CorsConfiguration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.EgressOptions), + name: "Egress", + displayName: "Egress" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions), + name: "Metrics", + displayName: "Metrics" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleDefaultsOptions), + name: "CollectionRuleDefaults", + displayName: "CollectionRuleDefaults" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.TemplateOptions), + name: "Templates", + displayName: "Templates" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectDumpOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.DumpType?), + name: "Type", + displayName: "Type" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectExceptionsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.ExceptionsConfiguration), + name: "Filters", + displayName: "Filters" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectGCDumpOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectLiveMetricsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Duration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectLogsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::Microsoft.Extensions.Logging.LogLevel?), + name: "DefaultLevel", + displayName: "DefaultLevel" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::System.Collections.Generic.Dictionary), + name: "FilterSpecs", + displayName: "FilterSpecs" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Duration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.Options.LogFormat?), + name: "Format", + displayName: "Format" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectStacksOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + ] + ); + } + private ValidatableTypeInfo CreateTraceEventFilter() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(string), + name: "ProviderName", + displayName: "ProviderName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(string), + name: "EventName", + displayName: "EventName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "PayloadFilter", + displayName: "PayloadFilter" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectTraceOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.TraceProfile?), + name: "Profile", + displayName: "Profile" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(int?), + name: "BufferSizeMegabytes", + displayName: "BufferSizeMegabytes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "Duration", + displayName: "Duration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(string), + name: "Egress", + displayName: "Egress" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + name: "StoppingEvent", + displayName: "StoppingEvent" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventPipeProvider() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(string), + name: "Name", + displayName: "Name" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(string), + name: "Keywords", + displayName: "Keywords" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(global::System.Diagnostics.Tracing.EventLevel), + name: "EventLevel", + displayName: "EventLevel" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + propertyType: typeof(global::System.Collections.Generic.IDictionary), + name: "Arguments", + displayName: "Arguments" + ), + ] + ); + } + private ValidatableTypeInfo CreateExecuteOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + propertyType: typeof(string), + name: "Path", + displayName: "Path" + ), + ] + ); + } + private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + propertyType: typeof(string), + name: "Name", + displayName: "Name" + ), + ] + ); + } + private ValidatableTypeInfo CreateGuid() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Guid), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Guid), + propertyType: typeof(global::System.Guid), + name: "AllBitsSet", + displayName: "AllBitsSet" + ), + ] + ); + } + private ValidatableTypeInfo CreateLoadProfilerOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + propertyType: typeof(string), + name: "Path", + displayName: "Path" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + propertyType: typeof(global::System.Guid), + name: "Clsid", + displayName: "Clsid" + ), + ] + ); + } + private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + propertyType: typeof(string), + name: "Name", + displayName: "Name" + ), + ] + ); + } + private ValidatableTypeInfo CreateCPUUsageOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + propertyType: typeof(double?), + name: "GreaterThan", + displayName: "GreaterThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + propertyType: typeof(double?), + name: "LessThan", + displayName: "LessThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateGCHeapSizeOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + propertyType: typeof(double?), + name: "GreaterThan", + displayName: "GreaterThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + propertyType: typeof(double?), + name: "LessThan", + displayName: "LessThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateThreadpoolQueueLengthOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + propertyType: typeof(double?), + name: "GreaterThan", + displayName: "GreaterThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + propertyType: typeof(double?), + name: "LessThan", + displayName: "LessThan" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateAspNetRequestCountOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + propertyType: typeof(int), + name: "RequestCount", + displayName: "RequestCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + propertyType: typeof(string[]), + name: "IncludePaths", + displayName: "IncludePaths" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + propertyType: typeof(string[]), + name: "ExcludePaths", + displayName: "ExcludePaths" + ), + ] + ); + } + private ValidatableTypeInfo CreateAspNetRequestDurationOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(int), + name: "RequestCount", + displayName: "RequestCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RequestDuration", + displayName: "RequestDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(string[]), + name: "IncludePaths", + displayName: "IncludePaths" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + propertyType: typeof(string[]), + name: "ExcludePaths", + displayName: "ExcludePaths" + ), + ] + ); + } + private ValidatableTypeInfo CreateAspNetResponseStatusOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(string[]), + name: "StatusCodes", + displayName: "StatusCodes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(int), + name: "ResponseCount", + displayName: "ResponseCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(string[]), + name: "IncludePaths", + displayName: "IncludePaths" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + propertyType: typeof(string[]), + name: "ExcludePaths", + displayName: "ExcludePaths" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventCounterOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + propertyType: typeof(string), + name: "ProviderName", + displayName: "ProviderName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + propertyType: typeof(string), + name: "CounterName", + displayName: "CounterName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventMeterOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + propertyType: typeof(string), + name: "MeterName", + displayName: "MeterName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + propertyType: typeof(string), + name: "InstrumentName", + displayName: "InstrumentName" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "SlidingWindowDuration", + displayName: "SlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + propertyType: typeof(int?), + name: "HistogramPercentile", + displayName: "HistogramPercentile" + ), + ] + ); + } + private ValidatableTypeInfo CreateFileSystemEgressProviderOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + propertyType: typeof(string), + name: "DirectoryPath", + displayName: "DirectoryPath" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + propertyType: typeof(int?), + name: "CopyBufferSize", + displayName: "CopyBufferSize" + ), + ] + ); + } + private ValidatableTypeInfo CreateExtensionManifest() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), + propertyType: typeof(string), + name: "Name", + displayName: "Name" + ), + ] + ); + } + private ValidatableTypeInfo CreateValidatableTypes() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.RootOptions), + name: "RootOptions", + displayName: "RootOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + name: "CollectDumpOptions", + displayName: "CollectDumpOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + name: "CollectExceptionsOptions", + displayName: "CollectExceptionsOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + name: "CollectGCDumpOptions", + displayName: "CollectGCDumpOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + name: "CollectLiveMetricsOptions", + displayName: "CollectLiveMetricsOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + name: "CollectLogsOptions", + displayName: "CollectLogsOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + name: "CollectStacksOptions", + displayName: "CollectStacksOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + name: "CollectTraceOptions", + displayName: "CollectTraceOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.EventPipeProvider), + name: "EventPipeProvider", + displayName: "EventPipeProvider" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + name: "ExecuteOptions", + displayName: "ExecuteOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + name: "GetEnvironmentVariableOptions", + displayName: "GetEnvironmentVariableOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + name: "LoadProfilerOptions", + displayName: "LoadProfilerOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + name: "SetEnvironmentVariableOptions", + displayName: "SetEnvironmentVariableOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.CPUUsageOptions), + name: "CPUUsageOptions", + displayName: "CPUUsageOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.GCHeapSizeOptions), + name: "GCHeapSizeOptions", + displayName: "GCHeapSizeOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts.ThreadpoolQueueLengthOptions), + name: "ThreadpoolQueueLengthOptions", + displayName: "ThreadpoolQueueLengthOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestCountOptions), + name: "AspNetRequestCountOptions", + displayName: "AspNetRequestCountOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetRequestDurationOptions), + name: "AspNetRequestDurationOptions", + displayName: "AspNetRequestDurationOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.AspNetResponseStatusOptions), + name: "AspNetResponseStatusOptions", + displayName: "AspNetResponseStatusOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterOptions), + name: "EventCounterOptions", + displayName: "EventCounterOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventMeterOptions), + name: "EventMeterOptions", + displayName: "EventMeterOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem.FileSystemEgressProviderOptions), + name: "FileSystemEgressProviderOptions", + displayName: "FileSystemEgressProviderOptions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.Extensibility.ExtensionManifest), + name: "ExtensionManifest", + displayName: "ExtensionManifest" + ), + ] + ); + } + + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + internal static class GeneratedServiceCollectionExtensions + { + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + { + // Use non-extension method to avoid infinite recursion. + return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => + { + options.Resolvers.Insert(0, new GeneratedValidatableInfoResolver()); + if (configureOptions is not null) + { + configureOptions(options); + } + }); + } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + file static class ValidationAttributeCache + { + private sealed record CacheKey(global::System.Type ContainingType, string PropertyName); + private static readonly global::System.Collections.Concurrent.ConcurrentDictionary _cache = new(); + + public static global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes( + global::System.Type containingType, + string propertyName) + { + var key = new CacheKey(containingType, propertyName); + return _cache.GetOrAdd(key, static k => + { + var results = new global::System.Collections.Generic.List(); + + // Get attributes from the property + var property = k.ContainingType.GetProperty(k.PropertyName); + if (property != null) + { + var propertyAttributes = global::System.Reflection.CustomAttributeExtensions + .GetCustomAttributes(property, inherit: true); + + results.AddRange(propertyAttributes); + } + + // Check constructors for parameters that match the property name + // to handle record scenarios + foreach (var constructor in k.ContainingType.GetConstructors()) + { + // Look for parameter with matching name (case insensitive) + var parameter = global::System.Linq.Enumerable.FirstOrDefault( + constructor.GetParameters(), + p => string.Equals(p.Name, k.PropertyName, global::System.StringComparison.OrdinalIgnoreCase)); + + if (parameter != null) + { + var paramAttributes = global::System.Reflection.CustomAttributeExtensions + .GetCustomAttributes(parameter, inherit: true); + + results.AddRange(paramAttributes); + + break; + } + } + + return results.ToArray(); + }); + } + } +} \ No newline at end of file diff --git a/src/Tools/dotnet-monitor/ValidatableTypes.cs b/src/Tools/dotnet-monitor/ValidatableTypes.cs new file mode 100644 index 00000000000..85e670b184c --- /dev/null +++ b/src/Tools/dotnet-monitor/ValidatableTypes.cs @@ -0,0 +1,69 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Http.Validation; +using Microsoft.AspNetCore.Http.Validation.Generated; +using Microsoft.Diagnostics.Monitoring.WebApi.Models; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers; +using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Triggers.EventCounterShortcuts; +using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem; +using Microsoft.Diagnostics.Tools.Monitor.Extensibility; +using Microsoft.Extensions.DependencyInjection; + +namespace Microsoft.Diagnostics.Tools.Monitor +{ + // The Validation source generator doesn't run for libraries that don't call AddValidation, + // so we can't generate IValidatableInfo by using [ValidatableType] directly on types defined + // in ProjectReferences. This is a workaround to force the generator running in this project to + // generate IValidatableInfo for the referenced types. The containing class is not used otherwise. + // We use the same pattern for all types, including those defined in the same project. + [ValidatableType] + internal class ValidatableTypes + { + public required RootOptions RootOptions { get; init; } + + + // Action options + public required CollectDumpOptions CollectDumpOptions { get; init; } + public required CollectExceptionsOptions CollectExceptionsOptions { get; init; } + public required CollectGCDumpOptions CollectGCDumpOptions { get; init; } + public required CollectLiveMetricsOptions CollectLiveMetricsOptions { get; init; } + public required CollectLogsOptions CollectLogsOptions { get; init; } + public required CollectStacksOptions CollectStacksOptions { get; init; } + public required CollectTraceOptions CollectTraceOptions { get; init; } + // Necessary to work around the generated validation code not recursing into List? members: + // https://github.com/dotnet/aspnetcore/issues/61737 + public required EventPipeProvider EventPipeProvider { get; init; } + public required ExecuteOptions ExecuteOptions { get; init; } + public required GetEnvironmentVariableOptions GetEnvironmentVariableOptions { get; init; } + public required LoadProfilerOptions LoadProfilerOptions { get; init; } + public required SetEnvironmentVariableOptions SetEnvironmentVariableOptions { get; init; } + + + // Trigger options + // EventCounterShortcuts + public required CPUUsageOptions CPUUsageOptions { get; init; } + public required GCHeapSizeOptions GCHeapSizeOptions { get; init; } + public required ThreadpoolQueueLengthOptions ThreadpoolQueueLengthOptions { get; init; } + // Other trigger options + public required AspNetRequestCountOptions AspNetRequestCountOptions { get; init; } + public required AspNetRequestDurationOptions AspNetRequestDurationOptions { get; init; } + public required AspNetResponseStatusOptions AspNetResponseStatusOptions { get; init; } + public required EventCounterOptions EventCounterOptions { get; init; } + public required EventMeterOptions EventMeterOptions { get; init; } + + + public required FileSystemEgressProviderOptions FileSystemEgressProviderOptions { get; init; } + public required ExtensionManifest ExtensionManifest { get; init; } + + public static void AddValidation(IServiceCollection services) + { + GeneratedServiceCollectionExtensions.AddValidation(services, options => + { + options.Resolvers.Insert(0, new CustomValidatableInfoResolver()); + }); + } + } +} diff --git a/src/Tools/dotnet-monitor/dotnet-monitor.csproj b/src/Tools/dotnet-monitor/dotnet-monitor.csproj index e4c623839ef..4856f2580db 100644 --- a/src/Tools/dotnet-monitor/dotnet-monitor.csproj +++ b/src/Tools/dotnet-monitor/dotnet-monitor.csproj @@ -10,6 +10,8 @@ false enable true + true + $(InterceptorsNamespaces);Microsoft.AspNetCore.Http.Validation.Generated @@ -40,6 +42,7 @@ + From 3be9535efe06c0064f408a8630fd5ac46799f0db Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 30 Apr 2025 18:43:44 +0000 Subject: [PATCH 169/174] Add back CollectionRuleOptions --- .../dotnet-monitor/ValidatableInfoResolver.cs | 704 +++++++++++++++++- src/Tools/dotnet-monitor/ValidatableTypes.cs | 3 + 2 files changed, 688 insertions(+), 19 deletions(-) diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index 372e3c0a249..30f68dee330 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -139,6 +139,111 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateRootOptions(); return true; } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions)) + { + validatableInfo = CreateCollectionRuleTriggerOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions)) + { + validatableInfo = CreateCollectionRuleActionOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions)) + { + validatableInfo = CreateCollectionRuleLimitsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions)) + { + validatableInfo = CreateCollectionRuleOptions(); + return true; + } + if (type == typeof(global::System.Reflection.MethodBase)) + { + validatableInfo = CreateMethodBase(); + return true; + } + if (type == typeof(global::System.Reflection.ConstructorInfo)) + { + validatableInfo = CreateConstructorInfo(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeTypedArgument)) + { + validatableInfo = CreateCustomAttributeTypedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeNamedArgument)) + { + validatableInfo = CreateCustomAttributeNamedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeData)) + { + validatableInfo = CreateCustomAttributeData(); + return true; + } + if (type == typeof(global::System.Reflection.ParameterInfo)) + { + validatableInfo = CreateParameterInfo(); + return true; + } + if (type == typeof(global::System.Reflection.MethodInfo)) + { + validatableInfo = CreateMethodInfo(); + return true; + } + if (type == typeof(global::System.Reflection.EventInfo)) + { + validatableInfo = CreateEventInfo(); + return true; + } + if (type == typeof(global::System.Reflection.FieldInfo)) + { + validatableInfo = CreateFieldInfo(); + return true; + } + if (type == typeof(global::System.Reflection.PropertyInfo)) + { + validatableInfo = CreatePropertyInfo(); + return true; + } + if (type == typeof(global::System.Reflection.TypeInfo)) + { + validatableInfo = CreateTypeInfo(); + return true; + } + if (type == typeof(global::System.Reflection.Assembly)) + { + validatableInfo = CreateAssembly(); + return true; + } + if (type == typeof(global::System.Guid)) + { + validatableInfo = CreateGuid(); + return true; + } + if (type == typeof(global::System.Reflection.Module)) + { + validatableInfo = CreateModule(); + return true; + } + if (type == typeof(global::System.Reflection.MemberInfo)) + { + validatableInfo = CreateMemberInfo(); + return true; + } + if (type == typeof(global::System.Type)) + { + validatableInfo = CreateType(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions)) + { + validatableInfo = CreateBaseRecordOptions(); + return true; + } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions)) { validatableInfo = CreateCollectDumpOptions(); @@ -194,11 +299,6 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateGetEnvironmentVariableOptions(); return true; } - if (type == typeof(global::System.Guid)) - { - validatableInfo = CreateGuid(); - return true; - } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions)) { validatableInfo = CreateLoadProfilerOptions(); @@ -661,6 +761,580 @@ private ValidatableTypeInfo CreateRootOptions() ] ); } + private ValidatableTypeInfo CreateCollectionRuleTriggerOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + propertyType: typeof(string), + name: "Type", + displayName: "Type" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleActionOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), + propertyType: typeof(string), + name: "Type", + displayName: "Type" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleLimitsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(int?), + name: "ActionCount", + displayName: "ActionCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "ActionCountSlidingWindowDuration", + displayName: "ActionCountSlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RuleDuration", + displayName: "RuleDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Filters", + displayName: "Filters" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + name: "Trigger", + displayName: "Trigger" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Actions", + displayName: "Actions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + name: "Limits", + displayName: "Limits" + ), + ] + ); + } + private ValidatableTypeInfo CreateMethodBase() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodBase), + members: [] + ); + } + private ValidatableTypeInfo CreateConstructorInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ConstructorInfo), + members: [] + ); + } + private ValidatableTypeInfo CreateCustomAttributeTypedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeTypedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + propertyType: typeof(global::System.Type), + name: "ArgumentType", + displayName: "ArgumentType" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeNamedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeNamedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "MemberInfo", + displayName: "MemberInfo" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + name: "TypedValue", + displayName: "TypedValue" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeData() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeData), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Type), + name: "AttributeType", + displayName: "AttributeType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "Constructor", + displayName: "Constructor" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "ConstructorArguments", + displayName: "ConstructorArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "NamedArguments", + displayName: "NamedArguments" + ), + ] + ); + } + private ValidatableTypeInfo CreateParameterInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ParameterInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "Member", + displayName: "Member" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Type), + name: "ParameterType", + displayName: "ParameterType" + ), + ] + ); + } + private ValidatableTypeInfo CreateMethodInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.ParameterInfo), + name: "ReturnParameter", + displayName: "ReturnParameter" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Type), + name: "ReturnType", + displayName: "ReturnType" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.EventInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "AddMethod", + displayName: "AddMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Type), + name: "EventHandlerType", + displayName: "EventHandlerType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RaiseMethod", + displayName: "RaiseMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RemoveMethod", + displayName: "RemoveMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateFieldInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.FieldInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Type), + name: "FieldType", + displayName: "FieldType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + ] + ); + } + private ValidatableTypeInfo CreatePropertyInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.PropertyInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "GetMethod", + displayName: "GetMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Type), + name: "PropertyType", + displayName: "PropertyType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "SetMethod", + displayName: "SetMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateTypeInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.TypeInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredConstructors", + displayName: "DeclaredConstructors" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredEvents", + displayName: "DeclaredEvents" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredFields", + displayName: "DeclaredFields" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMembers", + displayName: "DeclaredMembers" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMethods", + displayName: "DeclaredMethods" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredNestedTypes", + displayName: "DeclaredNestedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredProperties", + displayName: "DeclaredProperties" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ImplementedInterfaces", + displayName: "ImplementedInterfaces" + ), + ] + ); + } + private ValidatableTypeInfo CreateAssembly() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Assembly), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DefinedTypes", + displayName: "DefinedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "EntryPoint", + displayName: "EntryPoint" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ExportedTypes", + displayName: "ExportedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.Module), + name: "ManifestModule", + displayName: "ManifestModule" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "Modules", + displayName: "Modules" + ), + ] + ); + } + private ValidatableTypeInfo CreateGuid() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Guid), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Guid), + propertyType: typeof(global::System.Guid), + name: "AllBitsSet", + displayName: "AllBitsSet" + ), + ] + ); + } + private ValidatableTypeInfo CreateModule() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Module), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Guid), + name: "ModuleVersionId", + displayName: "ModuleVersionId" + ), + ] + ); + } + private ValidatableTypeInfo CreateMemberInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MemberInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + ] + ); + } + private ValidatableTypeInfo CreateType() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Type), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "BaseType", + displayName: "BaseType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MethodBase), + name: "DeclaringMethod", + displayName: "DeclaringMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type[]), + name: "GenericTypeArguments", + displayName: "GenericTypeArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Guid), + name: "GUID", + displayName: "GUID" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "TypeInitializer", + displayName: "TypeInitializer" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "UnderlyingSystemType", + displayName: "UnderlyingSystemType" + ), + ] + ); + } + private ValidatableTypeInfo CreateBaseRecordOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + propertyType: typeof(global::System.Type), + name: "EqualityContract", + displayName: "EqualityContract" + ), + ] + ); + } private ValidatableTypeInfo CreateCollectDumpOptions() { return new GeneratedValidatableTypeInfo( @@ -911,20 +1585,6 @@ private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() ] ); } - private ValidatableTypeInfo CreateGuid() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Guid), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Guid), - propertyType: typeof(global::System.Guid), - name: "AllBitsSet", - displayName: "AllBitsSet" - ), - ] - ); - } private ValidatableTypeInfo CreateLoadProfilerOptions() { return new GeneratedValidatableTypeInfo( @@ -1248,6 +1908,12 @@ private ValidatableTypeInfo CreateValidatableTypes() name: "RootOptions", displayName: "RootOptions" ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + name: "CollectionRuleOptions", + displayName: "CollectionRuleOptions" + ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), diff --git a/src/Tools/dotnet-monitor/ValidatableTypes.cs b/src/Tools/dotnet-monitor/ValidatableTypes.cs index 85e670b184c..453dc745f55 100644 --- a/src/Tools/dotnet-monitor/ValidatableTypes.cs +++ b/src/Tools/dotnet-monitor/ValidatableTypes.cs @@ -24,6 +24,9 @@ internal class ValidatableTypes { public required RootOptions RootOptions { get; init; } + // Necessary to work around the generated validation code not recursing into Dictionary? members: + // https://github.com/dotnet/aspnetcore/issues/61737 + public required CollectionRuleOptions CollectionRuleOptions { get; init; } // Action options public required CollectDumpOptions CollectDumpOptions { get; init; } From 3bda2eb0d853452e455a6fc3484f093bedd09143 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 30 Apr 2025 18:43:44 +0000 Subject: [PATCH 170/174] Add back CollectionRuleOptions --- .../dotnet-monitor/ValidatableInfoResolver.cs | 704 +++++++++++++++++- src/Tools/dotnet-monitor/ValidatableTypes.cs | 3 + 2 files changed, 688 insertions(+), 19 deletions(-) diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index 372e3c0a249..30f68dee330 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -139,6 +139,111 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateRootOptions(); return true; } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions)) + { + validatableInfo = CreateCollectionRuleTriggerOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions)) + { + validatableInfo = CreateCollectionRuleActionOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions)) + { + validatableInfo = CreateCollectionRuleLimitsOptions(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions)) + { + validatableInfo = CreateCollectionRuleOptions(); + return true; + } + if (type == typeof(global::System.Reflection.MethodBase)) + { + validatableInfo = CreateMethodBase(); + return true; + } + if (type == typeof(global::System.Reflection.ConstructorInfo)) + { + validatableInfo = CreateConstructorInfo(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeTypedArgument)) + { + validatableInfo = CreateCustomAttributeTypedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeNamedArgument)) + { + validatableInfo = CreateCustomAttributeNamedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeData)) + { + validatableInfo = CreateCustomAttributeData(); + return true; + } + if (type == typeof(global::System.Reflection.ParameterInfo)) + { + validatableInfo = CreateParameterInfo(); + return true; + } + if (type == typeof(global::System.Reflection.MethodInfo)) + { + validatableInfo = CreateMethodInfo(); + return true; + } + if (type == typeof(global::System.Reflection.EventInfo)) + { + validatableInfo = CreateEventInfo(); + return true; + } + if (type == typeof(global::System.Reflection.FieldInfo)) + { + validatableInfo = CreateFieldInfo(); + return true; + } + if (type == typeof(global::System.Reflection.PropertyInfo)) + { + validatableInfo = CreatePropertyInfo(); + return true; + } + if (type == typeof(global::System.Reflection.TypeInfo)) + { + validatableInfo = CreateTypeInfo(); + return true; + } + if (type == typeof(global::System.Reflection.Assembly)) + { + validatableInfo = CreateAssembly(); + return true; + } + if (type == typeof(global::System.Guid)) + { + validatableInfo = CreateGuid(); + return true; + } + if (type == typeof(global::System.Reflection.Module)) + { + validatableInfo = CreateModule(); + return true; + } + if (type == typeof(global::System.Reflection.MemberInfo)) + { + validatableInfo = CreateMemberInfo(); + return true; + } + if (type == typeof(global::System.Type)) + { + validatableInfo = CreateType(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions)) + { + validatableInfo = CreateBaseRecordOptions(); + return true; + } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions)) { validatableInfo = CreateCollectDumpOptions(); @@ -194,11 +299,6 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateGetEnvironmentVariableOptions(); return true; } - if (type == typeof(global::System.Guid)) - { - validatableInfo = CreateGuid(); - return true; - } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions)) { validatableInfo = CreateLoadProfilerOptions(); @@ -661,6 +761,580 @@ private ValidatableTypeInfo CreateRootOptions() ] ); } + private ValidatableTypeInfo CreateCollectionRuleTriggerOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + propertyType: typeof(string), + name: "Type", + displayName: "Type" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleActionOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleActionOptions), + propertyType: typeof(string), + name: "Type", + displayName: "Type" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleLimitsOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(int?), + name: "ActionCount", + displayName: "ActionCount" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "ActionCountSlidingWindowDuration", + displayName: "ActionCountSlidingWindowDuration" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + propertyType: typeof(global::System.TimeSpan?), + name: "RuleDuration", + displayName: "RuleDuration" + ), + ] + ); + } + private ValidatableTypeInfo CreateCollectionRuleOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Filters", + displayName: "Filters" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleTriggerOptions), + name: "Trigger", + displayName: "Trigger" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::System.Collections.Generic.List), + name: "Actions", + displayName: "Actions" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleLimitsOptions), + name: "Limits", + displayName: "Limits" + ), + ] + ); + } + private ValidatableTypeInfo CreateMethodBase() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodBase), + members: [] + ); + } + private ValidatableTypeInfo CreateConstructorInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ConstructorInfo), + members: [] + ); + } + private ValidatableTypeInfo CreateCustomAttributeTypedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeTypedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + propertyType: typeof(global::System.Type), + name: "ArgumentType", + displayName: "ArgumentType" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeNamedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeNamedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "MemberInfo", + displayName: "MemberInfo" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + name: "TypedValue", + displayName: "TypedValue" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeData() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeData), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Type), + name: "AttributeType", + displayName: "AttributeType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "Constructor", + displayName: "Constructor" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "ConstructorArguments", + displayName: "ConstructorArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "NamedArguments", + displayName: "NamedArguments" + ), + ] + ); + } + private ValidatableTypeInfo CreateParameterInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ParameterInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "Member", + displayName: "Member" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Type), + name: "ParameterType", + displayName: "ParameterType" + ), + ] + ); + } + private ValidatableTypeInfo CreateMethodInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.ParameterInfo), + name: "ReturnParameter", + displayName: "ReturnParameter" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Type), + name: "ReturnType", + displayName: "ReturnType" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.EventInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "AddMethod", + displayName: "AddMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Type), + name: "EventHandlerType", + displayName: "EventHandlerType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RaiseMethod", + displayName: "RaiseMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RemoveMethod", + displayName: "RemoveMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateFieldInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.FieldInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Type), + name: "FieldType", + displayName: "FieldType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + ] + ); + } + private ValidatableTypeInfo CreatePropertyInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.PropertyInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "GetMethod", + displayName: "GetMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Type), + name: "PropertyType", + displayName: "PropertyType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "SetMethod", + displayName: "SetMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateTypeInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.TypeInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredConstructors", + displayName: "DeclaredConstructors" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredEvents", + displayName: "DeclaredEvents" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredFields", + displayName: "DeclaredFields" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMembers", + displayName: "DeclaredMembers" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMethods", + displayName: "DeclaredMethods" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredNestedTypes", + displayName: "DeclaredNestedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredProperties", + displayName: "DeclaredProperties" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ImplementedInterfaces", + displayName: "ImplementedInterfaces" + ), + ] + ); + } + private ValidatableTypeInfo CreateAssembly() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Assembly), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DefinedTypes", + displayName: "DefinedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "EntryPoint", + displayName: "EntryPoint" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ExportedTypes", + displayName: "ExportedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.Module), + name: "ManifestModule", + displayName: "ManifestModule" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "Modules", + displayName: "Modules" + ), + ] + ); + } + private ValidatableTypeInfo CreateGuid() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Guid), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Guid), + propertyType: typeof(global::System.Guid), + name: "AllBitsSet", + displayName: "AllBitsSet" + ), + ] + ); + } + private ValidatableTypeInfo CreateModule() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Module), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Guid), + name: "ModuleVersionId", + displayName: "ModuleVersionId" + ), + ] + ); + } + private ValidatableTypeInfo CreateMemberInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MemberInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + ] + ); + } + private ValidatableTypeInfo CreateType() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Type), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "BaseType", + displayName: "BaseType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MethodBase), + name: "DeclaringMethod", + displayName: "DeclaringMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type[]), + name: "GenericTypeArguments", + displayName: "GenericTypeArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Guid), + name: "GUID", + displayName: "GUID" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "TypeInitializer", + displayName: "TypeInitializer" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "UnderlyingSystemType", + displayName: "UnderlyingSystemType" + ), + ] + ); + } + private ValidatableTypeInfo CreateBaseRecordOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + propertyType: typeof(global::System.Type), + name: "EqualityContract", + displayName: "EqualityContract" + ), + ] + ); + } private ValidatableTypeInfo CreateCollectDumpOptions() { return new GeneratedValidatableTypeInfo( @@ -911,20 +1585,6 @@ private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() ] ); } - private ValidatableTypeInfo CreateGuid() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Guid), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Guid), - propertyType: typeof(global::System.Guid), - name: "AllBitsSet", - displayName: "AllBitsSet" - ), - ] - ); - } private ValidatableTypeInfo CreateLoadProfilerOptions() { return new GeneratedValidatableTypeInfo( @@ -1248,6 +1908,12 @@ private ValidatableTypeInfo CreateValidatableTypes() name: "RootOptions", displayName: "RootOptions" ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), + propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.CollectionRuleOptions), + name: "CollectionRuleOptions", + displayName: "CollectionRuleOptions" + ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes), propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), diff --git a/src/Tools/dotnet-monitor/ValidatableTypes.cs b/src/Tools/dotnet-monitor/ValidatableTypes.cs index 85e670b184c..453dc745f55 100644 --- a/src/Tools/dotnet-monitor/ValidatableTypes.cs +++ b/src/Tools/dotnet-monitor/ValidatableTypes.cs @@ -24,6 +24,9 @@ internal class ValidatableTypes { public required RootOptions RootOptions { get; init; } + // Necessary to work around the generated validation code not recursing into Dictionary? members: + // https://github.com/dotnet/aspnetcore/issues/61737 + public required CollectionRuleOptions CollectionRuleOptions { get; init; } // Action options public required CollectDumpOptions CollectDumpOptions { get; init; } From 5f9f9df034d6c9ed4a3a22c363d0e281858f0603 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 30 Apr 2025 23:12:34 +0000 Subject: [PATCH 171/174] Remove EqualityContract Work around https://github.com/dotnet/aspnetcore/issues/61379 --- src/Tools/dotnet-monitor/ValidatableInfoResolver.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index 30f68dee330..5a0bcaaa3a9 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -1326,12 +1326,6 @@ private ValidatableTypeInfo CreateBaseRecordOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), - propertyType: typeof(global::System.Type), - name: "EqualityContract", - displayName: "EqualityContract" - ), ] ); } From c47e9e956062510ee4d826daddf693a2436572bf Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 30 Apr 2025 23:12:34 +0000 Subject: [PATCH 172/174] Remove EqualityContract Work around https://github.com/dotnet/aspnetcore/issues/61379 --- src/Tools/dotnet-monitor/ValidatableInfoResolver.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index 30f68dee330..5a0bcaaa3a9 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -1326,12 +1326,6 @@ private ValidatableTypeInfo CreateBaseRecordOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), - propertyType: typeof(global::System.Type), - name: "EqualityContract", - displayName: "EqualityContract" - ), ] ); } From 649bb8632a7ef1d323d70d1963997d73d57ec941 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 5 May 2025 21:22:06 +0000 Subject: [PATCH 173/174] Update generated code - Re-run latest version of generators - Add comments to help point out places where manual changes were made to the generated code --- .../ValidatableInfoResolver.cs | 59 +- .../dotnet-monitor/ValidatableInfoResolver.cs | 594 +----------------- 2 files changed, 51 insertions(+), 602 deletions(-) diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs index 4a06b0908ac..06509a455b9 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTestCommon/ValidatableInfoResolver.cs @@ -9,8 +9,6 @@ //------------------------------------------------------------------------------ #nullable enable -using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options; - namespace System.Runtime.CompilerServices { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] @@ -647,6 +645,13 @@ private ValidatableTypeInfo CreateBaseRecordOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), ] ); } @@ -654,7 +659,15 @@ private ValidatableTypeInfo CreatePassThroughOptions() { return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), - members: [] + members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Monitoring.TestCommon.PassThroughOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + ] ); } private ValidatableTypeInfo CreateTestValidatableTypes() @@ -674,6 +687,8 @@ private ValidatableTypeInfo CreateTestValidatableTypes() } + // Added internal wrapper to let the generated extension method be accessed from test code + // without conflicting with GeneratedServiceCollectionExtensions in product code. internal static class TestGeneratedServiceCollectionExtensions { public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(global::Microsoft.Extensions.DependencyInjection.IServiceCollection services) @@ -685,13 +700,15 @@ internal static class TestGeneratedServiceCollectionExtensions [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] file static class GeneratedServiceCollectionExtensions { - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "8vl1G447Wi3Pc94851ZKGx+IAABWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + // Removed InterceptsLocation since we are calling the extension method directly from a checked-in copy of the + // generated code, and interceptors are not designed for use in checked-in code. + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => { options.Resolvers.Insert(0, new GeneratedValidatableInfoResolver()); - options.Resolvers.Add(new CustomValidatableInfoResolver()); if (configureOptions is not null) { configureOptions(options); @@ -713,39 +730,13 @@ private sealed record CacheKey(global::System.Type ContainingType, string Proper var key = new CacheKey(containingType, propertyName); return _cache.GetOrAdd(key, static k => { - var results = new global::System.Collections.Generic.List(); - - // Get attributes from the property var property = k.ContainingType.GetProperty(k.PropertyName); - if (property != null) + if (property == null) { - var propertyAttributes = global::System.Reflection.CustomAttributeExtensions - .GetCustomAttributes(property, inherit: true); - - results.AddRange(propertyAttributes); + return []; } - // Check constructors for parameters that match the property name - // to handle record scenarios - foreach (var constructor in k.ContainingType.GetConstructors()) - { - // Look for parameter with matching name (case insensitive) - var parameter = global::System.Linq.Enumerable.FirstOrDefault( - constructor.GetParameters(), - p => string.Equals(p.Name, k.PropertyName, global::System.StringComparison.OrdinalIgnoreCase)); - - if (parameter != null) - { - var paramAttributes = global::System.Reflection.CustomAttributeExtensions - .GetCustomAttributes(parameter, inherit: true); - - results.AddRange(paramAttributes); - - break; - } - } - - return results.ToArray(); + return [.. global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(property, inherit: true)]; }); } } diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index 5a0bcaaa3a9..e4315833f1d 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -159,91 +159,6 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateCollectionRuleOptions(); return true; } - if (type == typeof(global::System.Reflection.MethodBase)) - { - validatableInfo = CreateMethodBase(); - return true; - } - if (type == typeof(global::System.Reflection.ConstructorInfo)) - { - validatableInfo = CreateConstructorInfo(); - return true; - } - if (type == typeof(global::System.Reflection.CustomAttributeTypedArgument)) - { - validatableInfo = CreateCustomAttributeTypedArgument(); - return true; - } - if (type == typeof(global::System.Reflection.CustomAttributeNamedArgument)) - { - validatableInfo = CreateCustomAttributeNamedArgument(); - return true; - } - if (type == typeof(global::System.Reflection.CustomAttributeData)) - { - validatableInfo = CreateCustomAttributeData(); - return true; - } - if (type == typeof(global::System.Reflection.ParameterInfo)) - { - validatableInfo = CreateParameterInfo(); - return true; - } - if (type == typeof(global::System.Reflection.MethodInfo)) - { - validatableInfo = CreateMethodInfo(); - return true; - } - if (type == typeof(global::System.Reflection.EventInfo)) - { - validatableInfo = CreateEventInfo(); - return true; - } - if (type == typeof(global::System.Reflection.FieldInfo)) - { - validatableInfo = CreateFieldInfo(); - return true; - } - if (type == typeof(global::System.Reflection.PropertyInfo)) - { - validatableInfo = CreatePropertyInfo(); - return true; - } - if (type == typeof(global::System.Reflection.TypeInfo)) - { - validatableInfo = CreateTypeInfo(); - return true; - } - if (type == typeof(global::System.Reflection.Assembly)) - { - validatableInfo = CreateAssembly(); - return true; - } - if (type == typeof(global::System.Guid)) - { - validatableInfo = CreateGuid(); - return true; - } - if (type == typeof(global::System.Reflection.Module)) - { - validatableInfo = CreateModule(); - return true; - } - if (type == typeof(global::System.Reflection.MemberInfo)) - { - validatableInfo = CreateMemberInfo(); - return true; - } - if (type == typeof(global::System.Type)) - { - validatableInfo = CreateType(); - return true; - } - if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions)) - { - validatableInfo = CreateBaseRecordOptions(); - return true; - } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions)) { validatableInfo = CreateCollectDumpOptions(); @@ -299,6 +214,11 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateGetEnvironmentVariableOptions(); return true; } + if (type == typeof(global::System.Guid)) + { + validatableInfo = CreateGuid(); + return true; + } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions)) { validatableInfo = CreateLoadProfilerOptions(); @@ -847,488 +767,6 @@ private ValidatableTypeInfo CreateCollectionRuleOptions() ] ); } - private ValidatableTypeInfo CreateMethodBase() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.MethodBase), - members: [] - ); - } - private ValidatableTypeInfo CreateConstructorInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.ConstructorInfo), - members: [] - ); - } - private ValidatableTypeInfo CreateCustomAttributeTypedArgument() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.CustomAttributeTypedArgument), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeTypedArgument), - propertyType: typeof(global::System.Type), - name: "ArgumentType", - displayName: "ArgumentType" - ), - ] - ); - } - private ValidatableTypeInfo CreateCustomAttributeNamedArgument() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.CustomAttributeNamedArgument), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), - propertyType: typeof(global::System.Reflection.MemberInfo), - name: "MemberInfo", - displayName: "MemberInfo" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), - propertyType: typeof(global::System.Reflection.CustomAttributeTypedArgument), - name: "TypedValue", - displayName: "TypedValue" - ), - ] - ); - } - private ValidatableTypeInfo CreateCustomAttributeData() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.CustomAttributeData), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeData), - propertyType: typeof(global::System.Type), - name: "AttributeType", - displayName: "AttributeType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeData), - propertyType: typeof(global::System.Reflection.ConstructorInfo), - name: "Constructor", - displayName: "Constructor" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeData), - propertyType: typeof(global::System.Collections.Generic.IList), - name: "ConstructorArguments", - displayName: "ConstructorArguments" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.CustomAttributeData), - propertyType: typeof(global::System.Collections.Generic.IList), - name: "NamedArguments", - displayName: "NamedArguments" - ), - ] - ); - } - private ValidatableTypeInfo CreateParameterInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.ParameterInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.ParameterInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "CustomAttributes", - displayName: "CustomAttributes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.ParameterInfo), - propertyType: typeof(global::System.Reflection.MemberInfo), - name: "Member", - displayName: "Member" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.ParameterInfo), - propertyType: typeof(global::System.Type), - name: "ParameterType", - displayName: "ParameterType" - ), - ] - ); - } - private ValidatableTypeInfo CreateMethodInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.MethodInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MethodInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MethodInfo), - propertyType: typeof(global::System.Reflection.ParameterInfo), - name: "ReturnParameter", - displayName: "ReturnParameter" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MethodInfo), - propertyType: typeof(global::System.Type), - name: "ReturnType", - displayName: "ReturnType" - ), - ] - ); - } - private ValidatableTypeInfo CreateEventInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.EventInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "AddMethod", - displayName: "AddMethod" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Type), - name: "EventHandlerType", - displayName: "EventHandlerType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "RaiseMethod", - displayName: "RaiseMethod" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.EventInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "RemoveMethod", - displayName: "RemoveMethod" - ), - ] - ); - } - private ValidatableTypeInfo CreateFieldInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.FieldInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.FieldInfo), - propertyType: typeof(global::System.Type), - name: "FieldType", - displayName: "FieldType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.FieldInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - ] - ); - } - private ValidatableTypeInfo CreatePropertyInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.PropertyInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.PropertyInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "GetMethod", - displayName: "GetMethod" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.PropertyInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.PropertyInfo), - propertyType: typeof(global::System.Type), - name: "PropertyType", - displayName: "PropertyType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.PropertyInfo), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "SetMethod", - displayName: "SetMethod" - ), - ] - ); - } - private ValidatableTypeInfo CreateTypeInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.TypeInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredConstructors", - displayName: "DeclaredConstructors" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredEvents", - displayName: "DeclaredEvents" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredFields", - displayName: "DeclaredFields" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredMembers", - displayName: "DeclaredMembers" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredMethods", - displayName: "DeclaredMethods" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredNestedTypes", - displayName: "DeclaredNestedTypes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DeclaredProperties", - displayName: "DeclaredProperties" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.TypeInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "ImplementedInterfaces", - displayName: "ImplementedInterfaces" - ), - ] - ); - } - private ValidatableTypeInfo CreateAssembly() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.Assembly), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "CustomAttributes", - displayName: "CustomAttributes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "DefinedTypes", - displayName: "DefinedTypes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Reflection.MethodInfo), - name: "EntryPoint", - displayName: "EntryPoint" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "ExportedTypes", - displayName: "ExportedTypes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Reflection.Module), - name: "ManifestModule", - displayName: "ManifestModule" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Assembly), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "Modules", - displayName: "Modules" - ), - ] - ); - } - private ValidatableTypeInfo CreateGuid() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Guid), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Guid), - propertyType: typeof(global::System.Guid), - name: "AllBitsSet", - displayName: "AllBitsSet" - ), - ] - ); - } - private ValidatableTypeInfo CreateModule() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.Module), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Module), - propertyType: typeof(global::System.Reflection.Assembly), - name: "Assembly", - displayName: "Assembly" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Module), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "CustomAttributes", - displayName: "CustomAttributes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.Module), - propertyType: typeof(global::System.Guid), - name: "ModuleVersionId", - displayName: "ModuleVersionId" - ), - ] - ); - } - private ValidatableTypeInfo CreateMemberInfo() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Reflection.MemberInfo), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Collections.Generic.IEnumerable), - name: "CustomAttributes", - displayName: "CustomAttributes" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Type), - name: "DeclaringType", - displayName: "DeclaringType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Reflection.Module), - name: "Module", - displayName: "Module" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Reflection.MemberInfo), - propertyType: typeof(global::System.Type), - name: "ReflectedType", - displayName: "ReflectedType" - ), - ] - ); - } - private ValidatableTypeInfo CreateType() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Type), - members: [ - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.Assembly), - name: "Assembly", - displayName: "Assembly" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type), - name: "BaseType", - displayName: "BaseType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.MethodBase), - name: "DeclaringMethod", - displayName: "DeclaringMethod" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type), - name: "DeclaringType", - displayName: "DeclaringType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type[]), - name: "GenericTypeArguments", - displayName: "GenericTypeArguments" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Guid), - name: "GUID", - displayName: "GUID" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.MemberTypes), - name: "MemberType", - displayName: "MemberType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.Module), - name: "Module", - displayName: "Module" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type), - name: "ReflectedType", - displayName: "ReflectedType" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Reflection.ConstructorInfo), - name: "TypeInitializer", - displayName: "TypeInitializer" - ), - new GeneratedValidatablePropertyInfo( - containingType: typeof(global::System.Type), - propertyType: typeof(global::System.Type), - name: "UnderlyingSystemType", - displayName: "UnderlyingSystemType" - ), - ] - ); - } - private ValidatableTypeInfo CreateBaseRecordOptions() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), - members: [ - ] - ); - } private ValidatableTypeInfo CreateCollectDumpOptions() { return new GeneratedValidatableTypeInfo( @@ -1579,6 +1017,21 @@ private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() ] ); } + private ValidatableTypeInfo CreateGuid() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Guid), + members: [ + // https://github.com/dotnet/aspnetcore/issues/61525 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::System.Guid), + // propertyType: typeof(global::System.Guid), + // name: "AllBitsSet", + // displayName: "AllBitsSet" + // ), + ] + ); + } private ValidatableTypeInfo CreateLoadProfilerOptions() { return new GeneratedValidatableTypeInfo( @@ -2047,9 +1500,14 @@ private ValidatableTypeInfo CreateValidatableTypes() } [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")] + // file static class GeneratedServiceCollectionExtensions + // Made internal to allow access within the same assembly internal static class GeneratedServiceCollectionExtensions { - public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "SYJrC5usv1zxb1xGUp2I5czAAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + // Removed InterceptsLocation since we are calling the extension method directly from a checked-in copy of the + // generated code, and interceptors are not designed for use in checked-in code. + public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) { // Use non-extension method to avoid infinite recursion. return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options => From 2d57445dfa18a586f511975623c54f95a930cf2c Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 5 May 2025 22:01:17 +0000 Subject: [PATCH 174/174] Update generated code Something was wrong with the previous update (maybe a caching issue). This uses the latest version of the generator. --- .../dotnet-monitor/ValidatableInfoResolver.cs | 760 ++++++++++++++++-- 1 file changed, 709 insertions(+), 51 deletions(-) diff --git a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs index e4315833f1d..2b3f303b977 100644 --- a/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs +++ b/src/Tools/dotnet-monitor/ValidatableInfoResolver.cs @@ -74,6 +74,12 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateAuthenticationOptions(); return true; } + // https://github.com/dotnet/aspnetcore/issues/61388 + // if (type == typeof(global::System.Collections.Generic.IDictionary)) + // { + // validatableInfo = CreateIDictionary`2(); + // return true; + // } if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.GlobalCounterOptions)) { validatableInfo = CreateGlobalCounterOptions(); @@ -159,6 +165,91 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateCollectionRuleOptions(); return true; } + if (type == typeof(global::System.Reflection.MethodBase)) + { + validatableInfo = CreateMethodBase(); + return true; + } + if (type == typeof(global::System.Reflection.ConstructorInfo)) + { + validatableInfo = CreateConstructorInfo(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeTypedArgument)) + { + validatableInfo = CreateCustomAttributeTypedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeNamedArgument)) + { + validatableInfo = CreateCustomAttributeNamedArgument(); + return true; + } + if (type == typeof(global::System.Reflection.CustomAttributeData)) + { + validatableInfo = CreateCustomAttributeData(); + return true; + } + if (type == typeof(global::System.Reflection.ParameterInfo)) + { + validatableInfo = CreateParameterInfo(); + return true; + } + if (type == typeof(global::System.Reflection.MethodInfo)) + { + validatableInfo = CreateMethodInfo(); + return true; + } + if (type == typeof(global::System.Reflection.EventInfo)) + { + validatableInfo = CreateEventInfo(); + return true; + } + if (type == typeof(global::System.Reflection.FieldInfo)) + { + validatableInfo = CreateFieldInfo(); + return true; + } + if (type == typeof(global::System.Reflection.PropertyInfo)) + { + validatableInfo = CreatePropertyInfo(); + return true; + } + if (type == typeof(global::System.Reflection.TypeInfo)) + { + validatableInfo = CreateTypeInfo(); + return true; + } + if (type == typeof(global::System.Reflection.Assembly)) + { + validatableInfo = CreateAssembly(); + return true; + } + if (type == typeof(global::System.Guid)) + { + validatableInfo = CreateGuid(); + return true; + } + if (type == typeof(global::System.Reflection.Module)) + { + validatableInfo = CreateModule(); + return true; + } + if (type == typeof(global::System.Reflection.MemberInfo)) + { + validatableInfo = CreateMemberInfo(); + return true; + } + if (type == typeof(global::System.Type)) + { + validatableInfo = CreateType(); + return true; + } + if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions)) + { + validatableInfo = CreateBaseRecordOptions(); + return true; + } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions)) { validatableInfo = CreateCollectDumpOptions(); @@ -179,6 +270,12 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateCollectLiveMetricsOptions(); return true; } + // https://github.com/dotnet/aspnetcore/issues/61388 + // if (type == typeof(global::System.Collections.Generic.Dictionary)) + // { + // validatableInfo = CreateDictionary`2(); + // return true; + // } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions)) { validatableInfo = CreateCollectLogsOptions(); @@ -214,11 +311,6 @@ public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System. validatableInfo = CreateGetEnvironmentVariableOptions(); return true; } - if (type == typeof(global::System.Guid)) - { - validatableInfo = CreateGuid(); - return true; - } if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions)) { validatableInfo = CreateLoadProfilerOptions(); @@ -767,11 +859,508 @@ private ValidatableTypeInfo CreateCollectionRuleOptions() ] ); } + private ValidatableTypeInfo CreateMethodBase() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodBase), + members: [] + ); + } + private ValidatableTypeInfo CreateConstructorInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ConstructorInfo), + members: [] + ); + } + private ValidatableTypeInfo CreateCustomAttributeTypedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeTypedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + propertyType: typeof(global::System.Type), + name: "ArgumentType", + displayName: "ArgumentType" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeNamedArgument() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeNamedArgument), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "MemberInfo", + displayName: "MemberInfo" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeNamedArgument), + propertyType: typeof(global::System.Reflection.CustomAttributeTypedArgument), + name: "TypedValue", + displayName: "TypedValue" + ), + ] + ); + } + private ValidatableTypeInfo CreateCustomAttributeData() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.CustomAttributeData), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Type), + name: "AttributeType", + displayName: "AttributeType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "Constructor", + displayName: "Constructor" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "ConstructorArguments", + displayName: "ConstructorArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.CustomAttributeData), + propertyType: typeof(global::System.Collections.Generic.IList), + name: "NamedArguments", + displayName: "NamedArguments" + ), + ] + ); + } + private ValidatableTypeInfo CreateParameterInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.ParameterInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Reflection.MemberInfo), + name: "Member", + displayName: "Member" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.ParameterInfo), + propertyType: typeof(global::System.Type), + name: "ParameterType", + displayName: "ParameterType" + ), + ] + ); + } + private ValidatableTypeInfo CreateMethodInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MethodInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Reflection.ParameterInfo), + name: "ReturnParameter", + displayName: "ReturnParameter" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MethodInfo), + propertyType: typeof(global::System.Type), + name: "ReturnType", + displayName: "ReturnType" + ), + ] + ); + } + private ValidatableTypeInfo CreateEventInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.EventInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "AddMethod", + displayName: "AddMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Type), + name: "EventHandlerType", + displayName: "EventHandlerType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RaiseMethod", + displayName: "RaiseMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.EventInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "RemoveMethod", + displayName: "RemoveMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateFieldInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.FieldInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Type), + name: "FieldType", + displayName: "FieldType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.FieldInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + ] + ); + } + private ValidatableTypeInfo CreatePropertyInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.PropertyInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "GetMethod", + displayName: "GetMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Type), + name: "PropertyType", + displayName: "PropertyType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.PropertyInfo), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "SetMethod", + displayName: "SetMethod" + ), + ] + ); + } + private ValidatableTypeInfo CreateTypeInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.TypeInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredConstructors", + displayName: "DeclaredConstructors" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredEvents", + displayName: "DeclaredEvents" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredFields", + displayName: "DeclaredFields" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMembers", + displayName: "DeclaredMembers" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredMethods", + displayName: "DeclaredMethods" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredNestedTypes", + displayName: "DeclaredNestedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DeclaredProperties", + displayName: "DeclaredProperties" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.TypeInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ImplementedInterfaces", + displayName: "ImplementedInterfaces" + ), + ] + ); + } + private ValidatableTypeInfo CreateAssembly() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Assembly), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "DefinedTypes", + displayName: "DefinedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.MethodInfo), + name: "EntryPoint", + displayName: "EntryPoint" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "ExportedTypes", + displayName: "ExportedTypes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Reflection.Module), + name: "ManifestModule", + displayName: "ManifestModule" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Assembly), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "Modules", + displayName: "Modules" + ), + ] + ); + } + private ValidatableTypeInfo CreateGuid() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Guid), + members: [ + // https://github.com/dotnet/aspnetcore/issues/61525 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::System.Guid), + // propertyType: typeof(global::System.Guid), + // name: "AllBitsSet", + // displayName: "AllBitsSet" + // ), + ] + ); + } + private ValidatableTypeInfo CreateModule() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.Module), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.Module), + propertyType: typeof(global::System.Guid), + name: "ModuleVersionId", + displayName: "ModuleVersionId" + ), + ] + ); + } + private ValidatableTypeInfo CreateMemberInfo() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Reflection.MemberInfo), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Collections.Generic.IEnumerable), + name: "CustomAttributes", + displayName: "CustomAttributes" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Reflection.MemberInfo), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + ] + ); + } + private ValidatableTypeInfo CreateType() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::System.Type), + members: [ + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Assembly), + name: "Assembly", + displayName: "Assembly" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "BaseType", + displayName: "BaseType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MethodBase), + name: "DeclaringMethod", + displayName: "DeclaringMethod" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "DeclaringType", + displayName: "DeclaringType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type[]), + name: "GenericTypeArguments", + displayName: "GenericTypeArguments" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Guid), + name: "GUID", + displayName: "GUID" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.MemberTypes), + name: "MemberType", + displayName: "MemberType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.Module), + name: "Module", + displayName: "Module" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "ReflectedType", + displayName: "ReflectedType" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Reflection.ConstructorInfo), + name: "TypeInitializer", + displayName: "TypeInitializer" + ), + new GeneratedValidatablePropertyInfo( + containingType: typeof(global::System.Type), + propertyType: typeof(global::System.Type), + name: "UnderlyingSystemType", + displayName: "UnderlyingSystemType" + ), + ] + ); + } + private ValidatableTypeInfo CreateBaseRecordOptions() + { + return new GeneratedValidatableTypeInfo( + type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.BaseRecordOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), + ] + ); + } private ValidatableTypeInfo CreateCollectDumpOptions() { return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectDumpOptions), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.DumpType?), @@ -792,6 +1381,13 @@ private ValidatableTypeInfo CreateCollectExceptionsOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectExceptionsOptions), propertyType: typeof(string), @@ -812,11 +1408,18 @@ private ValidatableTypeInfo CreateCollectGCDumpOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectGCDumpOptions), propertyType: typeof(string), name: "Egress", - displayName: "Egress" + displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings" ), ] ); @@ -826,6 +1429,13 @@ private ValidatableTypeInfo CreateCollectLiveMetricsOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLiveMetricsOptions), propertyType: typeof(global::System.TimeSpan?), @@ -841,11 +1451,51 @@ private ValidatableTypeInfo CreateCollectLiveMetricsOptions() ] ); } + // https://github.com/dotnet/aspnetcore/issues/61388 + // private ValidatableTypeInfo CreateDictionary`2() + // { + // return new GeneratedValidatableTypeInfo( + // type: typeof(global::System.Collections.Generic.Dictionary), + // members: [ + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::System.Collections.Generic.Dictionary), + // propertyType: typeof(global::System.Collections.Generic.ICollection), + // name: "System.Collections.Generic.IDictionary.Values", + // displayName: "System.Collections.Generic.IDictionary.Values" + // ), + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::System.Collections.Generic.Dictionary), + // propertyType: typeof(global::System.Collections.Generic.IEnumerable), + // name: "System.Collections.Generic.IReadOnlyDictionary.Keys", + // displayName: "System.Collections.Generic.IReadOnlyDictionary.Keys" + // ), + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::System.Collections.Generic.Dictionary), + // propertyType: typeof(global::System.Collections.Generic.IEnumerable), + // name: "System.Collections.Generic.IReadOnlyDictionary.Values", + // displayName: "System.Collections.Generic.IReadOnlyDictionary.Values" + // ), + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::System.Collections.Generic.Dictionary), + // propertyType: typeof(global::System.Collections.ICollection), + // name: "System.Collections.IDictionary.Values", + // displayName: "System.Collections.IDictionary.Values" + // ), + // ] + // ); + // } private ValidatableTypeInfo CreateCollectLogsOptions() { return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectLogsOptions), propertyType: typeof(global::Microsoft.Extensions.Logging.LogLevel?), @@ -884,6 +1534,13 @@ private ValidatableTypeInfo CreateCollectStacksOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectStacksOptions), propertyType: typeof(string), @@ -898,6 +1555,13 @@ private ValidatableTypeInfo CreateTraceEventFilter() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.TraceEventFilter), propertyType: typeof(string), @@ -924,6 +1588,13 @@ private ValidatableTypeInfo CreateCollectTraceOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.CollectTraceOptions), propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.Models.TraceProfile?), @@ -994,6 +1665,13 @@ private ValidatableTypeInfo CreateExecuteOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.ExecuteOptions), propertyType: typeof(string), @@ -1008,6 +1686,13 @@ private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.GetEnvironmentVariableOptions), propertyType: typeof(string), @@ -1017,26 +1702,18 @@ private ValidatableTypeInfo CreateGetEnvironmentVariableOptions() ] ); } - private ValidatableTypeInfo CreateGuid() - { - return new GeneratedValidatableTypeInfo( - type: typeof(global::System.Guid), - members: [ - // https://github.com/dotnet/aspnetcore/issues/61525 - // new GeneratedValidatablePropertyInfo( - // containingType: typeof(global::System.Guid), - // propertyType: typeof(global::System.Guid), - // name: "AllBitsSet", - // displayName: "AllBitsSet" - // ), - ] - ); - } private ValidatableTypeInfo CreateLoadProfilerOptions() { return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.LoadProfilerOptions), propertyType: typeof(string), @@ -1057,6 +1734,13 @@ private ValidatableTypeInfo CreateSetEnvironmentVariableOptions() return new GeneratedValidatableTypeInfo( type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), members: [ + // https://github.com/dotnet/aspnetcore/issues/61379 + // new GeneratedValidatablePropertyInfo( + // containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), + // propertyType: typeof(global::System.Type), + // name: "EqualityContract", + // displayName: "EqualityContract" + // ), new GeneratedValidatablePropertyInfo( containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions.SetEnvironmentVariableOptions), propertyType: typeof(string), @@ -1504,7 +2188,7 @@ private ValidatableTypeInfo CreateValidatableTypes() // Made internal to allow access within the same assembly internal static class GeneratedServiceCollectionExtensions { - // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "SYJrC5usv1zxb1xGUp2I5czAAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] + // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "o8z0Jzavd3bSTijvzqPfl8tVAQBWYWxpZGF0YWJsZUluZm9SZXNvbHZlci5jcw==")] // Removed InterceptsLocation since we are calling the extension method directly from a checked-in copy of the // generated code, and interceptors are not designed for use in checked-in code. public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action? configureOptions = null) @@ -1534,39 +2218,13 @@ private sealed record CacheKey(global::System.Type ContainingType, string Proper var key = new CacheKey(containingType, propertyName); return _cache.GetOrAdd(key, static k => { - var results = new global::System.Collections.Generic.List(); - - // Get attributes from the property var property = k.ContainingType.GetProperty(k.PropertyName); - if (property != null) - { - var propertyAttributes = global::System.Reflection.CustomAttributeExtensions - .GetCustomAttributes(property, inherit: true); - - results.AddRange(propertyAttributes); - } - - // Check constructors for parameters that match the property name - // to handle record scenarios - foreach (var constructor in k.ContainingType.GetConstructors()) + if (property == null) { - // Look for parameter with matching name (case insensitive) - var parameter = global::System.Linq.Enumerable.FirstOrDefault( - constructor.GetParameters(), - p => string.Equals(p.Name, k.PropertyName, global::System.StringComparison.OrdinalIgnoreCase)); - - if (parameter != null) - { - var paramAttributes = global::System.Reflection.CustomAttributeExtensions - .GetCustomAttributes(parameter, inherit: true); - - results.AddRange(paramAttributes); - - break; - } + return []; } - return results.ToArray(); + return [.. global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(property, inherit: true)]; }); } }