Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
a704e80
Rebasing EventHubs Namespace List Command
jairmyree Sep 15, 2025
5e04724
Live tests passing
jairmyree Sep 16, 2025
a522534
Updating test-resources-post and adding e2e prompt
jairmyree Sep 17, 2025
d2b391e
Updating Namespace List to Namespace Get
jairmyree Sep 18, 2025
145ab5a
updating test-resources-post
jairmyree Sep 18, 2025
04e4466
Updating test to reflect tool consolidation
jairmyree Sep 18, 2025
f103655
Updates to PR based on feedback
jairmyree Sep 18, 2025
6dc75ca
EventHubs namespace get command update. Now supports getting metadata…
jairmyree Sep 22, 2025
b46760f
Update namespace get command to not take id parameter
jairmyree Sep 22, 2025
a03e420
Correcting EventHubs to Event Hubs in documentation
jairmyree Sep 22, 2025
8015a23
Additional Updates
jairmyree Sep 22, 2025
28bdcc3
Remove unused imports
jairmyree Sep 22, 2025
8a6d752
Changes to EventHubsService
jairmyree Sep 22, 2025
141d09d
dotnet format
jairmyree Sep 22, 2025
a5109b9
Remove the dependency on Azure.ResourceManager.EventHubs due to use A…
ArthurMa1978 Sep 23, 2025
623049c
Update tools/Azure.Mcp.Tools.EventHubs/src/EventHubsSetup.cs
jairmyree Sep 23, 2025
87b5424
Updates from PR comments
jairmyree Sep 24, 2025
9885f19
Updates from PR comments
jairmyree Sep 24, 2025
49ee954
Updates from PR comments
jairmyree Sep 24, 2025
31358e1
Updates from PR comments
jairmyree Sep 24, 2025
2bce69a
Fixing test error
jairmyree Sep 24, 2025
d7d849b
Fixing live test error
jairmyree Sep 25, 2025
e4de163
Update tools/Azure.Mcp.Tools.EventHubs/src/Commands/Namespace/Namespa…
jairmyree Sep 25, 2025
513a2ba
Update tools/Azure.Mcp.Tools.EventHubs/src/Commands/Namespace/Namespa…
jairmyree Sep 25, 2025
14175c7
Update tools/Azure.Mcp.Tools.EventHubs/src/Commands/Namespace/Namespa…
jairmyree Sep 25, 2025
1e79fa0
Update tools/Azure.Mcp.Tools.EventHubs/src/Services/EventHubsService.cs
jairmyree Sep 25, 2025
209abb5
Update tools/Azure.Mcp.Tools.EventHubs/tests/Azure.Mcp.Tools.EventHub…
jairmyree Sep 25, 2025
9cf4a3c
Update tools/Azure.Mcp.Tools.EventHubs/tests/Azure.Mcp.Tools.EventHub…
jairmyree Sep 25, 2025
7f6aa9e
Updates to PR based on feedback fron Alan and Connie
jairmyree Sep 26, 2025
a0c4def
Update tools/Azure.Mcp.Tools.EventHubs/src/Options/BaseEventHubsOptio…
jairmyree Sep 26, 2025
6bffa87
additional PR updates
jairmyree Sep 26, 2025
a172503
Updates to fix test failures
jairmyree Sep 26, 2025
075f97a
Update tools/Azure.Mcp.Tools.EventHubs/tests/Azure.Mcp.Tools.EventHub…
jairmyree Sep 26, 2025
efb33d1
Update tools/Azure.Mcp.Tools.EventHubs/src/Services/EventHubsService.cs
jairmyree Sep 26, 2025
39d7fa9
Rmoving empty file
jairmyree Sep 29, 2025
3e12ced
Update validation pattern
jairmyree Sep 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 76 additions & 16 deletions AzureMcp.sln
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Expand Down Expand Up @@ -493,6 +492,22 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{294AC723
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fabric.Mcp.Tools.PublicApi.Tests", "tools\Fabric.Mcp.Tools.PublicApi\tests\Fabric.Mcp.Tools.PublicApi.Tests.csproj", "{D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure.Mcp.Tools.EventHubs", "Azure.Mcp.Tools.EventHubs", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{DF2B8B1C-12CD-49EF-A072-7E839483CA18}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{71D9DE62-0765-4098-B4EC-157E71350C1D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.EventHubs", "tools\Azure.Mcp.Tools.EventHubs\src\Azure.Mcp.Tools.EventHubs.csproj", "{632DF404-7E5D-56B7-808D-816A3AB773A4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.EventHubs.LiveTests", "tools\Azure.Mcp.Tools.EventHubs\tests\Azure.Mcp.Tools.EventHubs.LiveTests\Azure.Mcp.Tools.EventHubs.LiveTests.csproj", "{760CAD28-4792-44B8-77D1-0F42F47BD303}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Mcp.Tools.EventHubs.UnitTests", "tools\Azure.Mcp.Tools.EventHubs\tests\Azure.Mcp.Tools.EventHubs.UnitTests\Azure.Mcp.Tools.EventHubs.UnitTests.csproj", "{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{13FF4FF8-11BB-470D-978D-87571D308826}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{26498A3E-7EAD-43A2-A2D1-5EFE17606906}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -863,6 +878,18 @@ Global
{E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Release|x64.Build.0 = Release|Any CPU
{E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Release|x86.ActiveCfg = Release|Any CPU
{E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB}.Release|x86.Build.0 = Release|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|x64.ActiveCfg = Debug|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|x64.Build.0 = Debug|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|x86.ActiveCfg = Debug|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|x86.Build.0 = Debug|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|Any CPU.Build.0 = Release|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|x64.ActiveCfg = Release|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|x64.Build.0 = Release|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|x86.ActiveCfg = Release|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|x86.Build.0 = Release|Any CPU
{916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{916DF4C9-3EB7-4D2B-B727-6EEEBB049A80}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -1859,18 +1886,42 @@ Global
{D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Release|x64.Build.0 = Release|Any CPU
{D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Release|x86.ActiveCfg = Release|Any CPU
{D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F}.Release|x86.Build.0 = Release|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|x64.ActiveCfg = Debug|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|x64.Build.0 = Debug|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|x86.ActiveCfg = Debug|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Debug|x86.Build.0 = Debug|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|Any CPU.Build.0 = Release|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|x64.ActiveCfg = Release|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|x64.Build.0 = Release|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|x86.ActiveCfg = Release|Any CPU
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11}.Release|x86.Build.0 = Release|Any CPU
{632DF404-7E5D-56B7-808D-816A3AB773A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{632DF404-7E5D-56B7-808D-816A3AB773A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{632DF404-7E5D-56B7-808D-816A3AB773A4}.Debug|x64.ActiveCfg = Debug|Any CPU
{632DF404-7E5D-56B7-808D-816A3AB773A4}.Debug|x64.Build.0 = Debug|Any CPU
{632DF404-7E5D-56B7-808D-816A3AB773A4}.Debug|x86.ActiveCfg = Debug|Any CPU
{632DF404-7E5D-56B7-808D-816A3AB773A4}.Debug|x86.Build.0 = Debug|Any CPU
{632DF404-7E5D-56B7-808D-816A3AB773A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{632DF404-7E5D-56B7-808D-816A3AB773A4}.Release|Any CPU.Build.0 = Release|Any CPU
{632DF404-7E5D-56B7-808D-816A3AB773A4}.Release|x64.ActiveCfg = Release|Any CPU
{632DF404-7E5D-56B7-808D-816A3AB773A4}.Release|x64.Build.0 = Release|Any CPU
{632DF404-7E5D-56B7-808D-816A3AB773A4}.Release|x86.ActiveCfg = Release|Any CPU
{632DF404-7E5D-56B7-808D-816A3AB773A4}.Release|x86.Build.0 = Release|Any CPU
{760CAD28-4792-44B8-77D1-0F42F47BD303}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{760CAD28-4792-44B8-77D1-0F42F47BD303}.Debug|Any CPU.Build.0 = Debug|Any CPU
{760CAD28-4792-44B8-77D1-0F42F47BD303}.Debug|x64.ActiveCfg = Debug|Any CPU
{760CAD28-4792-44B8-77D1-0F42F47BD303}.Debug|x64.Build.0 = Debug|Any CPU
{760CAD28-4792-44B8-77D1-0F42F47BD303}.Debug|x86.ActiveCfg = Debug|Any CPU
{760CAD28-4792-44B8-77D1-0F42F47BD303}.Debug|x86.Build.0 = Debug|Any CPU
{760CAD28-4792-44B8-77D1-0F42F47BD303}.Release|Any CPU.ActiveCfg = Release|Any CPU
{760CAD28-4792-44B8-77D1-0F42F47BD303}.Release|Any CPU.Build.0 = Release|Any CPU
{760CAD28-4792-44B8-77D1-0F42F47BD303}.Release|x64.ActiveCfg = Release|Any CPU
{760CAD28-4792-44B8-77D1-0F42F47BD303}.Release|x64.Build.0 = Release|Any CPU
{760CAD28-4792-44B8-77D1-0F42F47BD303}.Release|x86.ActiveCfg = Release|Any CPU
{760CAD28-4792-44B8-77D1-0F42F47BD303}.Release|x86.Build.0 = Release|Any CPU
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Debug|x64.ActiveCfg = Debug|Any CPU
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Debug|x64.Build.0 = Debug|Any CPU
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Debug|x86.ActiveCfg = Debug|Any CPU
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Debug|x86.Build.0 = Debug|Any CPU
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Release|Any CPU.Build.0 = Release|Any CPU
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Release|x64.ActiveCfg = Release|Any CPU
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Release|x64.Build.0 = Release|Any CPU
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Release|x86.ActiveCfg = Release|Any CPU
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1962,6 +2013,8 @@ Global
{168BAD1F-6D9B-4A41-9A40-CAA2766110EF} = {F894982B-4C93-0C62-D6DA-E27C0A3503E4}
{F4CC2172-46F8-04D7-FF11-4F95DDBB59E2} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84}
{065991D2-6F8C-6F65-0E72-DC96953B87D8} = {F4CC2172-46F8-04D7-FF11-4F95DDBB59E2}
{E2C2A3E4-1D5F-4F6E-9A7F-1C2E54F893AB} = {13FF4FF8-11BB-470D-978D-87571D308826}
{C0F9D8F5-3F6D-4D46-9E6D-8A7E4EDC0E11} = {26498A3E-7EAD-43A2-A2D1-5EFE17606906}
{916DF4C9-3EB7-4D2B-B727-6EEEBB049A80} = {065991D2-6F8C-6F65-0E72-DC96953B87D8}
{898C8C6E-FC1C-58E1-FB62-BBE77ED42888} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84}
{C1148A03-1886-DC1A-65F9-2AE3D2752F84} = {898C8C6E-FC1C-58E1-FB62-BBE77ED42888}
Expand Down Expand Up @@ -2115,6 +2168,13 @@ Global
{C031D592-96D6-44D0-BF31-33CCE5CAABA1} = {447CAF13-A1DE-A946-989B-DD6CAA0CDF92}
{294AC723-70DA-F50A-2C7A-AC6C0AEA0A62} = {9072C7AF-9EB2-E481-3974-77957587AC76}
{D3F46C2D-3AFD-FD9C-9C6A-180B1514DD2F} = {294AC723-70DA-F50A-2C7A-AC6C0AEA0A62}
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84}
{DF2B8B1C-12CD-49EF-A072-7E839483CA18} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{71D9DE62-0765-4098-B4EC-157E71350C1D} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{632DF404-7E5D-56B7-808D-816A3AB773A4} = {DF2B8B1C-12CD-49EF-A072-7E839483CA18}
{760CAD28-4792-44B8-77D1-0F42F47BD303} = {71D9DE62-0765-4098-B4EC-157E71350C1D}
{459CFD26-F5BC-B3C8-0632-DE7EA1504AD3} = {71D9DE62-0765-4098-B4EC-157E71350C1D}
{13FF4FF8-11BB-470D-978D-87571D308826} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84}
{26498A3E-7EAD-43A2-A2D1-5EFE17606906} = {07C2787E-EAC7-C090-1BA3-A61EC2A24D84}
EndGlobalSection
EndGlobal

EndGlobal
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

namespace Azure.Mcp.Core.Services.Azure.Models;

Comment thread
jairmyree marked this conversation as resolved.

/// <summary>
/// A class representing the Resource Sku data model.
/// </summary>
Comment thread
jairmyree marked this conversation as resolved.
Expand Down
7 changes: 7 additions & 0 deletions docs/e2eTestPrompts.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,13 @@ This file contains prompts used for end-to-end testing to ensure each tool is in
| azmcp_eventgrid_events_publish | Publish event to my Event Grid topic <topic_name> with the following events <event_data> |
| azmcp_eventgrid_events_publish | Send an event to Event Grid topic <topic_name> in resource group <resource_group_name> with <event_data> |

## Azure Event Hubs

| Tool Name | Test Prompt |
|:----------|:----------|
| azmcp_eventhubs_namespace_get | List all Event Hubs namespaces in my subscription |
| azmcp_eventhubs_namespace_get | Get the details of my namespace <namespace_name> in my resource group <resource_group_name> |

## Azure Function App

| Tool Name | Test Prompt |
Expand Down
1 change: 1 addition & 0 deletions servers/Azure.Mcp.Server/src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ private static IAreaSetup[] RegisterAreas()
new Azure.Mcp.Tools.BicepSchema.BicepSchemaSetup(),
new Azure.Mcp.Tools.Cosmos.CosmosSetup(),
new Azure.Mcp.Tools.CloudArchitect.CloudArchitectSetup(),
new Azure.Mcp.Tools.EventHubs.EventHubsSetup(),
new Azure.Mcp.Tools.Foundry.FoundrySetup(),
new Azure.Mcp.Tools.FunctionApp.FunctionAppSetup(),
new Azure.Mcp.Tools.Grafana.GrafanaSetup(),
Expand Down
7 changes: 7 additions & 0 deletions tools/Azure.Mcp.Tools.EventHubs/src/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Azure.Mcp.Tools.EventHubs.UnitTests")]
[assembly: InternalsVisibleTo("Azure.Mcp.Tools.EventHubs.LiveTests")]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<IsAotCompatible>true</IsAotCompatible>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\core\Azure.Mcp.Core\src\Azure.Mcp.Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
<PackageReference Include="ModelContextProtocol" />
<PackageReference Include="System.CommandLine" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Diagnostics.CodeAnalysis;
using Azure.Mcp.Core.Commands;
using Azure.Mcp.Core.Commands.Subscription;
using Azure.Mcp.Tools.EventHubs.Options;

namespace Azure.Mcp.Tools.EventHubs.Commands;

public abstract class BaseEventHubsCommand<
[DynamicallyAccessedMembers(TrimAnnotations.CommandAnnotations)] TOptions>
: SubscriptionCommand<TOptions> where TOptions : BaseEventHubsOptions, new();
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Text.Json.Serialization;
using Azure.Mcp.Tools.EventHubs.Commands.Namespace;
using Azure.Mcp.Tools.EventHubs.Models;

namespace Azure.Mcp.Tools.EventHubs.Commands;

[JsonSerializable(typeof(EventHubsNamespaceData))]
[JsonSerializable(typeof(EventHubsNamespaceSku))]
[JsonSerializable(typeof(Models.Namespace))]
[JsonSerializable(typeof(NamespaceGetCommand.NamespaceGetCommandResult))]
[JsonSerializable(typeof(NamespaceGetCommand.NamespacesGetCommandResult))]
[JsonSourceGenerationOptions(
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
internal partial class EventHubsJsonContext : JsonSerializerContext;
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Net;
using Azure.Mcp.Core.Commands;
using Azure.Mcp.Core.Extensions;
using Azure.Mcp.Core.Models.Option;
using Azure.Mcp.Tools.EventHubs.Options;
using Azure.Mcp.Tools.EventHubs.Options.Namespace;
using Azure.Mcp.Tools.EventHubs.Services;
using Microsoft.Extensions.Logging;

namespace Azure.Mcp.Tools.EventHubs.Commands.Namespace;

public sealed class NamespaceGetCommand(ILogger<NamespaceGetCommand> logger)
: BaseEventHubsCommand<NamespaceGetOptions>
{
private const string CommandTitle = "Get Event Hubs Namespaces";

private readonly ILogger<NamespaceGetCommand> _logger = logger;

public override string Name => "get";

public override string Description =>
"""
Get Event Hubs namespaces from Azure. This command supports three modes of operation:
1. List all Event Hubs namespaces in a subscription (when no --resource-group is provided)
2. List all Event Hubs namespaces in a specific resource group (when only --resource-group is provided)
3. Get a single namespace by name (using --namespace with --resource-group)

When retrieving a single namespace, detailed information including SKU, settings, and metadata
is returned. When listing namespaces, the same detailed information is returned for all
namespaces in the specified scope.

The --resource-group parameter is optional for listing operations but required when getting a specific namespace.
""";

public override string Title => CommandTitle;

public override ToolMetadata Metadata => new()
{
OpenWorld = false,
Destructive = false, // Safe read-only operation
Idempotent = true, // Same parameters produce same results
ReadOnly = true, // Only reads data, no modifications
Secret = false, // Returns non-sensitive information
LocalRequired = false // Pure cloud API calls
};

protected override void RegisterOptions(Command command)
{
base.RegisterOptions(command);
command.Options.Add(OptionDefinitions.Common.ResourceGroup.AsOptional());
command.Options.Add(EventHubsOptionDefinitions.NamespaceName.AsOptional());
command.Validators.Add(commandResult =>
{
var namespaceName = commandResult.GetValueOrDefault<string>(EventHubsOptionDefinitions.NamespaceName.Name);
var resourceGroup = commandResult.GetValueOrDefault<string>(OptionDefinitions.Common.ResourceGroup.Name);

if (!string.IsNullOrEmpty(namespaceName) && string.IsNullOrEmpty(resourceGroup))
{
commandResult.AddError("When specifying a namespace name, a resource group must also be provided.");
}
});
}

protected override NamespaceGetOptions BindOptions(ParseResult parseResult)
{
var options = base.BindOptions(parseResult);
options.ResourceGroup ??= parseResult.GetValueOrDefault<string>(OptionDefinitions.Common.ResourceGroup.Name);
options.NamespaceName = parseResult.GetValueOrDefault<string>(EventHubsOptionDefinitions.NamespaceName.Name);
return options;
}

Comment thread
jairmyree marked this conversation as resolved.
public override async Task<CommandResponse> ExecuteAsync(CommandContext context, ParseResult parseResult)
{
if (!Validate(parseResult.CommandResult, context.Response).IsValid)
{
return context.Response;
}

var options = BindOptions(parseResult);

try
{
var eventHubsService = context.GetService<IEventHubsService>();

// Determine if this is a single namespace request or list request
bool isSingleNamespaceRequest = !string.IsNullOrEmpty(options.NamespaceName);

if (isSingleNamespaceRequest)
{
// Get single namespace with detailed information
var namespaceDetails = await eventHubsService.GetNamespaceAsync(
options.NamespaceName!,
options.ResourceGroup!,
options.Subscription!,
options.Tenant,
options.RetryPolicy);

context.Response.Results = namespaceDetails != null
? ResponseResult.Create(new(namespaceDetails), EventHubsJsonContext.Default.NamespaceGetCommandResult)
: null;
}
else
{
var namespaces = await eventHubsService.GetNamespacesAsync(
options.ResourceGroup,
options.Subscription!,
options.Tenant,
options.RetryPolicy);

context.Response.Results = ResponseResult.Create(new(namespaces ?? []), EventHubsJsonContext.Default.NamespacesGetCommandResult);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting Event Hubs namespaces");
HandleException(context, ex);
}

return context.Response;
}

protected override string GetErrorMessage(Exception ex) => ex switch
{
KeyNotFoundException => $"Event Hubs namespace not found. Verify the namespace name, resource group, and that you have access.",
Identity.AuthenticationFailedException authEx =>
"Authentication failed. Please ensure your Azure credentials are properly configured and have not expired.",
RequestFailedException reqEx when reqEx.Status == 403 =>
"Access denied. Please ensure you have sufficient permissions to get Event Hubs namespaces in the specified resource group.",
RequestFailedException reqEx when reqEx.Status == 404 =>
"The specified resource group or subscription was not found. Please verify the resource group name and subscription.",
ArgumentException argEx when argEx.ParamName == "resourceGroup" =>
"Invalid resource group name. Please provide a valid resource group name.",
ArgumentException argEx when argEx.ParamName == "subscription" =>
"Invalid subscription. Please provide a valid subscription ID or name.",
_ => base.GetErrorMessage(ex)
};

internal record NamespacesGetCommandResult(List<Models.Namespace> Namespaces);
internal record NamespaceGetCommandResult(Models.Namespace Namespace);
}
Loading