Skip to content
This repository was archived by the owner on Sep 4, 2025. It is now read-only.

Commit 16b5b78

Browse files
authored
Onboarding the Azure Service Health & Adding the resourcehealth availability-status get & resourcehealth availability-status list tools (#998)
* Onboarding the Azure Service Health & Adding the resourcehealth availability-status get & resourcehealth availability-status list tools * Fix ResourceHealth unit test validation and AOT compatibility * Remove ResourceHealth live tests and test infrastructure * Fix Extension.UnitTests: Correct mock method signatures for IExternalProcessService.ExecuteAsync
1 parent 9d08dcd commit 16b5b78

26 files changed

+900
-16
lines changed

‎.vscode/cspell.json‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,10 @@
370370
"timechart",
371371
"myapp",
372372
"mygroup",
373-
"myworkbook"
373+
"myworkbook",
374+
"resourcehealth",
375+
"rhvm",
376+
"azureadmin",
377+
"Occured"
374378
]
375379
}

‎AzureMcp.sln‎

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureMcp.VirtualDesktop.Liv
321321
EndProject
322322
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureMcp.VirtualDesktop.UnitTests", "areas\virtualdesktop\tests\AzureMcp.VirtualDesktop.UnitTests\AzureMcp.VirtualDesktop.UnitTests.csproj", "{F32955FF-3A13-2433-ECF7-EE5DB43F4631}"
323323
EndProject
324+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "resourcehealth", "resourcehealth", "{A29DD7BA-996D-C4EA-7CB3-91A08E5445CC}"
325+
EndProject
326+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{74490446-B0E8-F412-A296-BAE0BDC966AF}"
327+
EndProject
328+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureMcp.ResourceHealth", "areas\resourcehealth\src\AzureMcp.ResourceHealth\AzureMcp.ResourceHealth.csproj", "{FD987DB2-B19B-42EE-99C9-BF743D1288E3}"
329+
EndProject
330+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{75F7911D-A518-6F54-1978-62BEAF400CFE}"
331+
EndProject
332+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureMcp.ResourceHealth.UnitTests", "areas\resourcehealth\tests\AzureMcp.ResourceHealth.UnitTests\AzureMcp.ResourceHealth.UnitTests.csproj", "{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}"
333+
EndProject
324334
Global
325335
GlobalSection(SolutionConfigurationPlatforms) = preSolution
326336
Debug|Any CPU = Debug|Any CPU
@@ -1255,6 +1265,30 @@ Global
12551265
{F32955FF-3A13-2433-ECF7-EE5DB43F4631}.Release|x64.Build.0 = Release|Any CPU
12561266
{F32955FF-3A13-2433-ECF7-EE5DB43F4631}.Release|x86.ActiveCfg = Release|Any CPU
12571267
{F32955FF-3A13-2433-ECF7-EE5DB43F4631}.Release|x86.Build.0 = Release|Any CPU
1268+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1269+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
1270+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3}.Debug|x64.ActiveCfg = Debug|Any CPU
1271+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3}.Debug|x64.Build.0 = Debug|Any CPU
1272+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3}.Debug|x86.ActiveCfg = Debug|Any CPU
1273+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3}.Debug|x86.Build.0 = Debug|Any CPU
1274+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
1275+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3}.Release|Any CPU.Build.0 = Release|Any CPU
1276+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3}.Release|x64.ActiveCfg = Release|Any CPU
1277+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3}.Release|x64.Build.0 = Release|Any CPU
1278+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3}.Release|x86.ActiveCfg = Release|Any CPU
1279+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3}.Release|x86.Build.0 = Release|Any CPU
1280+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1281+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
1282+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}.Debug|x64.ActiveCfg = Debug|Any CPU
1283+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}.Debug|x64.Build.0 = Debug|Any CPU
1284+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}.Debug|x86.ActiveCfg = Debug|Any CPU
1285+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}.Debug|x86.Build.0 = Debug|Any CPU
1286+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
1287+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}.Release|Any CPU.Build.0 = Release|Any CPU
1288+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}.Release|x64.ActiveCfg = Release|Any CPU
1289+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}.Release|x64.Build.0 = Release|Any CPU
1290+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}.Release|x86.ActiveCfg = Release|Any CPU
1291+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2}.Release|x86.Build.0 = Release|Any CPU
12581292
EndGlobalSection
12591293
GlobalSection(SolutionProperties) = preSolution
12601294
HideSolutionNode = FALSE
@@ -1404,10 +1438,10 @@ Global
14041438
{2A3CD1B4-38A3-46A1-AEDC-2C2AC47CB8F1} = {8783C0BC-EE27-8E0C-7452-5882FB8E96CA}
14051439
{1AE3FC50-8E8C-4637-AAB1-A871D5FB4535} = {8783C0BC-EE27-8E0C-7452-5882FB8E96CA}
14061440
{527FE0F6-40AE-4E71-A483-0F0A2368F2A7} = {8783C0BC-EE27-8E0C-7452-5882FB8E96CA}
1441+
{E6E10688-A3CD-4C33-8E13-E0E905329272} = {4A85B59D-2802-46D2-B9D1-CDFE11A37945}
14071442
{3310D97C-93BE-4434-BED7-81EB639B3141} = {87783708-79E3-AD60-C783-1D52BE7DE4BB}
14081443
{4A85B59D-2802-46D2-B9D1-CDFE11A37945} = {3310D97C-93BE-4434-BED7-81EB639B3141}
14091444
{C1C50B06-1175-49A1-81C6-59842EEFC51B} = {3310D97C-93BE-4434-BED7-81EB639B3141}
1410-
{E6E10688-A3CD-4C33-8E13-E0E905329272} = {4A85B59D-2802-46D2-B9D1-CDFE11A37945}
14111445
{59A3843F-39AD-45C9-90A6-EBD40D644451} = {C1C50B06-1175-49A1-81C6-59842EEFC51B}
14121446
{5918EA72-9701-4223-B7BB-C64EB81B6351} = {C1C50B06-1175-49A1-81C6-59842EEFC51B}
14131447
{A3ADC1CC-6020-7233-DCFA-106CA917B0CD} = {7ECA6DB2-F8EF-407B-F2FD-DEF81B86CC73}
@@ -1417,5 +1451,10 @@ Global
14171451
{7DA56A1F-EA8A-C768-9777-F26EDCA059B6} = {3F159DE4-1438-4821-AA38-9BC3441661F0}
14181452
{D76F2E37-887E-9ADA-30A2-8969EB68DD76} = {775A7320-3D27-4FF2-B0F1-1078A6221B7C}
14191453
{F32955FF-3A13-2433-ECF7-EE5DB43F4631} = {775A7320-3D27-4FF2-B0F1-1078A6221B7C}
1454+
{A29DD7BA-996D-C4EA-7CB3-91A08E5445CC} = {87783708-79E3-AD60-C783-1D52BE7DE4BB}
1455+
{74490446-B0E8-F412-A296-BAE0BDC966AF} = {A29DD7BA-996D-C4EA-7CB3-91A08E5445CC}
1456+
{FD987DB2-B19B-42EE-99C9-BF743D1288E3} = {74490446-B0E8-F412-A296-BAE0BDC966AF}
1457+
{75F7911D-A518-6F54-1978-62BEAF400CFE} = {A29DD7BA-996D-C4EA-7CB3-91A08E5445CC}
1458+
{2A346B5F-D5FB-4454-ABBB-5E60280CBDF2} = {75F7911D-A518-6F54-1978-62BEAF400CFE}
14201459
EndGlobalSection
14211460
EndGlobal

‎Directory.Packages.props‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<PackageVersion Include="Azure.ResourceManager.PostgreSql" Version="1.3.1" />
2929
<PackageVersion Include="Azure.ResourceManager.Redis" Version="1.5.1" />
3030
<PackageVersion Include="Azure.ResourceManager.RedisEnterprise" Version="1.2.1" />
31+
<PackageVersion Include="Azure.ResourceManager.ResourceHealth" Version="1.0.0" />
3132
<PackageVersion Include="Azure.ResourceManager.LoadTesting" Version="1.1.2" />
3233
<PackageVersion Include="Azure.ResourceManager.Sql" Version="1.4.0-beta.3" />
3334
<PackageVersion Include="Azure.Security.KeyVault.Keys" Version="4.7.0" />

‎areas/extension/tests/AzureMcp.Extension.UnitTests/AzdCommandTest.cs‎

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ public async Task ExecuteAsync_ReturnsSuccessResult_WhenCommandExecutesSuccessfu
4747
_processService.ExecuteAsync(
4848
Arg.Any<string>(),
4949
Arg.Any<string>(),
50-
Arg.Any<int>(),
51-
Arg.Any<IEnumerable<string>>())
50+
Arg.Any<int>())
5251
.Returns(new ProcessResult(0, expectedOutput, string.Empty, "azd env list --cwd test-dir --no-prompt"));
5352

5453
var tempDir = CreateTempAzdCliDirectory();
@@ -105,8 +104,7 @@ public async Task ExecuteAsync_ReturnsErrorResponse_WhenCommandFails()
105104
_processService.ExecuteAsync(
106105
Arg.Any<string>(),
107106
Arg.Any<string>(),
108-
Arg.Any<int>(),
109-
Arg.Any<IEnumerable<string>>())
107+
Arg.Any<int>())
110108
.Returns(new ProcessResult(1, string.Empty, errorMessage, "azd env invalid-command --cwd test-dir --no-prompt"));
111109

112110
var tempDir = CreateTempAzdCliDirectory();
@@ -158,8 +156,7 @@ public async Task ExecuteAsync_HandlesException_AndSetsException()
158156
_processService.ExecuteAsync(
159157
Arg.Any<string>(),
160158
Arg.Any<string>(),
161-
Arg.Any<int>(),
162-
Arg.Any<IEnumerable<string>>())
159+
Arg.Any<int>())
163160
.ThrowsAsync(new FileNotFoundException(exceptionMessage));
164161

165162
// Act
@@ -241,8 +238,7 @@ public async Task ExecuteAsync_WithEnvironmentOption_IncludesEnvironmentInComman
241238
_processService.ExecuteAsync(
242239
Arg.Any<string>(),
243240
Arg.Any<string>(),
244-
Arg.Any<int>(),
245-
Arg.Any<IEnumerable<string>>())
241+
Arg.Any<int>())
246242
.Returns(new ProcessResult(0, "output", "", "command"));
247243

248244
var tempDir = CreateTempAzdCliDirectory();
@@ -340,8 +336,7 @@ public async Task ExecuteAsync_WithComplexCommand_HandlesArgumentsProperly()
340336
_processService.ExecuteAsync(
341337
Arg.Any<string>(),
342338
Arg.Any<string>(),
343-
Arg.Any<int>(),
344-
Arg.Any<IEnumerable<string>>())
339+
Arg.Any<int>())
345340
.Returns(new ProcessResult(0, expectedOutput, string.Empty, "azd env get-values --output json --cwd test-dir --no-prompt"));
346341

347342
var tempDir = CreateTempAzdCliDirectory();
@@ -371,8 +366,7 @@ public async Task ExecuteAsync_WithComplexCommand_HandlesArgumentsProperly()
371366
await _processService.Received(1).ExecuteAsync(
372367
Arg.Any<string>(),
373368
Arg.Is<string>(cmd => cmd.Contains("env get-values") && cmd.Contains("--output json") && cmd.Contains("--no-prompt")),
374-
Arg.Any<int>(),
375-
Arg.Any<IEnumerable<string>>());
369+
Arg.Any<int>());
376370
}
377371
finally
378372
{
@@ -403,8 +397,7 @@ public async Task ExecuteAsync_WithInfoCommands_ExecutesSuccessfully(string info
403397
_processService.ExecuteAsync(
404398
Arg.Any<string>(),
405399
Arg.Any<string>(),
406-
Arg.Any<int>(),
407-
Arg.Any<IEnumerable<string>>())
400+
Arg.Any<int>())
408401
.Returns(new ProcessResult(0, expectedOutput, string.Empty, $"azd {infoCommand} --cwd test-dir --no-prompt"));
409402

410403
var tempDir = CreateTempAzdCliDirectory();
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using System.Runtime.CompilerServices;
5+
6+
[assembly: InternalsVisibleTo("AzureMcp.ResourceHealth.UnitTests")]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<IsAotCompatible>true</IsAotCompatible>
4+
</PropertyGroup>
5+
<ItemGroup>
6+
<EmbeddedResource Include="**\Resources\*.txt" />
7+
<EmbeddedResource Include="**\Resources\*.json" />
8+
</ItemGroup>
9+
<ItemGroup>
10+
<ProjectReference Include="..\..\..\..\core\src\AzureMcp.Core\AzureMcp.Core.csproj" />
11+
</ItemGroup>
12+
<ItemGroup>
13+
<PackageReference Include="Azure.ResourceManager" />
14+
<PackageReference Include="Azure.ResourceManager.ResourceHealth" />
15+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
16+
<PackageReference Include="ModelContextProtocol" />
17+
<PackageReference Include="System.CommandLine" />
18+
</ItemGroup>
19+
</Project>
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using AzureMcp.Core.Commands;
5+
using AzureMcp.ResourceHealth.Models;
6+
using AzureMcp.ResourceHealth.Options.AvailabilityStatus;
7+
using AzureMcp.ResourceHealth.Services;
8+
using Microsoft.Extensions.Logging;
9+
10+
namespace AzureMcp.ResourceHealth.Commands.AvailabilityStatus;
11+
12+
/// <summary>
13+
/// Gets the current availability status of the specified Azure resource for health diagnostics.
14+
/// </summary>
15+
public sealed class AvailabilityStatusGetCommand(ILogger<AvailabilityStatusGetCommand> logger)
16+
: BaseResourceHealthCommand<AvailabilityStatusGetOptions>()
17+
{
18+
private const string CommandTitle = "Get Resource Availability Status";
19+
private readonly ILogger<AvailabilityStatusGetCommand> _logger = logger;
20+
21+
public override string Name => "get";
22+
23+
public override string Description =>
24+
$"""
25+
Get the current availability status of an Azure resource to diagnose health issues.
26+
Provides detailed information about resource availability state, potential issues, and timestamps.
27+
Equivalent to Azure Resource Health availability status API.
28+
""";
29+
30+
public override string Title => CommandTitle;
31+
32+
public override ToolMetadata Metadata => new() { Destructive = false, ReadOnly = true };
33+
34+
protected override void RegisterOptions(Command command)
35+
{
36+
base.RegisterOptions(command);
37+
command.AddOption(ResourceHealthOptionDefinitions.ResourceId);
38+
}
39+
40+
protected override AvailabilityStatusGetOptions BindOptions(ParseResult parseResult)
41+
{
42+
var options = base.BindOptions(parseResult);
43+
options.ResourceId = parseResult.GetValueForOption(ResourceHealthOptionDefinitions.ResourceId);
44+
return options;
45+
}
46+
47+
public override async Task<CommandResponse> ExecuteAsync(CommandContext context, ParseResult parseResult)
48+
{
49+
var options = BindOptions(parseResult);
50+
51+
try
52+
{
53+
if (!Validate(parseResult.CommandResult, context.Response).IsValid)
54+
{
55+
return context.Response;
56+
}
57+
58+
var resourceHealthService = context.GetService<IResourceHealthService>() ??
59+
throw new InvalidOperationException("Resource Health service is not available.");
60+
61+
var status = await resourceHealthService.GetAvailabilityStatusAsync(
62+
options.ResourceId!,
63+
options.RetryPolicy);
64+
65+
context.Response.Results = ResponseResult.Create(
66+
new AvailabilityStatusGetCommandResult(status),
67+
ResourceHealthJsonContext.Default.AvailabilityStatusGetCommandResult);
68+
}
69+
catch (Exception ex)
70+
{
71+
_logger.LogError(ex, "Failed to get availability status for resource {ResourceId}", options.ResourceId);
72+
HandleException(context, ex);
73+
}
74+
75+
return context.Response;
76+
}
77+
78+
internal record AvailabilityStatusGetCommandResult(Models.AvailabilityStatus Status);
79+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using AzureMcp.Core.Commands;
5+
using AzureMcp.ResourceHealth.Models;
6+
using AzureMcp.ResourceHealth.Options.AvailabilityStatus;
7+
using AzureMcp.ResourceHealth.Services;
8+
using Microsoft.Extensions.Logging;
9+
10+
namespace AzureMcp.ResourceHealth.Commands.AvailabilityStatus;
11+
12+
/// <summary>
13+
/// Lists availability statuses for all resources in a subscription or resource group.
14+
/// </summary>
15+
public sealed class AvailabilityStatusListCommand(ILogger<AvailabilityStatusListCommand> logger)
16+
: BaseResourceHealthCommand<AvailabilityStatusListOptions>()
17+
{
18+
private const string CommandTitle = "List Resource Availability Statuses";
19+
private readonly ILogger<AvailabilityStatusListCommand> _logger = logger;
20+
21+
public override string Name => "list";
22+
23+
public override string Description =>
24+
$"""
25+
List availability statuses for all resources in a subscription or resource group.
26+
Provides health status information for multiple Azure resources at once, including availability state,
27+
summaries, and timestamps. This is useful for getting an overview of resource health across your infrastructure.
28+
Results can be filtered by resource group to narrow the scope.
29+
""";
30+
31+
public override string Title => CommandTitle;
32+
33+
public override ToolMetadata Metadata => new() { Destructive = false, ReadOnly = true };
34+
35+
protected override void RegisterOptions(Command command)
36+
{
37+
base.RegisterOptions(command);
38+
UseResourceGroup(); // Optional filter for better performance
39+
}
40+
41+
protected override AvailabilityStatusListOptions BindOptions(ParseResult parseResult)
42+
{
43+
var options = base.BindOptions(parseResult);
44+
return options;
45+
}
46+
47+
public override async Task<CommandResponse> ExecuteAsync(CommandContext context, ParseResult parseResult)
48+
{
49+
var options = BindOptions(parseResult);
50+
51+
try
52+
{
53+
if (!Validate(parseResult.CommandResult, context.Response).IsValid)
54+
{
55+
return context.Response;
56+
}
57+
58+
var resourceHealthService = context.GetService<IResourceHealthService>() ??
59+
throw new InvalidOperationException("Resource Health service is not available.");
60+
61+
var statuses = await resourceHealthService.ListAvailabilityStatusesAsync(
62+
options.Subscription!,
63+
options.ResourceGroup,
64+
options.Tenant,
65+
options.RetryPolicy);
66+
67+
context.Response.Results = statuses?.Count > 0
68+
? ResponseResult.Create(
69+
new AvailabilityStatusListCommandResult(statuses),
70+
ResourceHealthJsonContext.Default.AvailabilityStatusListCommandResult)
71+
: null;
72+
}
73+
catch (Exception ex)
74+
{
75+
_logger.LogError(ex, "Failed to list availability statuses for subscription {Subscription}{ResourceGroupInfo}",
76+
options.Subscription,
77+
options.ResourceGroup != null ? $" and resource group {options.ResourceGroup}" : "");
78+
HandleException(context, ex);
79+
}
80+
81+
return context.Response;
82+
}
83+
84+
internal record AvailabilityStatusListCommandResult(List<Models.AvailabilityStatus> Statuses);
85+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using System.Diagnostics.CodeAnalysis;
5+
using AzureMcp.Core.Commands;
6+
using AzureMcp.Core.Commands.Subscription;
7+
using AzureMcp.ResourceHealth.Options;
8+
9+
namespace AzureMcp.ResourceHealth.Commands;
10+
11+
public abstract class BaseResourceHealthCommand<
12+
[DynamicallyAccessedMembers(TrimAnnotations.CommandAnnotations)] T>
13+
: SubscriptionCommand<T>
14+
where T : BaseResourceHealthOptions, new()
15+
{
16+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using System.Text.Json.Serialization;
5+
using AzureMcp.ResourceHealth.Commands.AvailabilityStatus;
6+
7+
namespace AzureMcp.ResourceHealth.Commands;
8+
9+
[JsonSerializable(typeof(AvailabilityStatusGetCommand.AvailabilityStatusGetCommandResult))]
10+
[JsonSerializable(typeof(AvailabilityStatusListCommand.AvailabilityStatusListCommandResult))]
11+
[JsonSerializable(typeof(AzureMcp.ResourceHealth.Models.AvailabilityStatus), TypeInfoPropertyName = "AvailabilityStatusModel")]
12+
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault)]
13+
internal sealed partial class ResourceHealthJsonContext : JsonSerializerContext;

0 commit comments

Comments
 (0)