Add XML documentation across gateway, worker, and .NET client

This commit is contained in:
Joseph Doherty
2026-04-30 11:49:58 -04:00
parent 4731ab535c
commit eed1e88a37
269 changed files with 4555 additions and 13 deletions
@@ -2,6 +2,11 @@ namespace MxGateway.Server.Dashboard.Components;
public static class DashboardDisplay
{
/// <summary>
/// Formats a nullable date and time value for display.
/// </summary>
/// <param name="value">The date and time to format.</param>
/// <returns>Formatted date and time string or "-" if null.</returns>
public static string DateTime(DateTimeOffset? value)
{
return value.HasValue
@@ -9,6 +14,11 @@ public static class DashboardDisplay
: "-";
}
/// <summary>
/// Formats a time span duration for display.
/// </summary>
/// <param name="value">The duration to format.</param>
/// <returns>Formatted duration string.</returns>
public static string Duration(TimeSpan value)
{
return value.TotalDays >= 1
@@ -16,16 +26,33 @@ public static class DashboardDisplay
: value.ToString(@"hh\:mm\:ss", System.Globalization.CultureInfo.InvariantCulture);
}
/// <summary>
/// Formats a nullable text value for display.
/// </summary>
/// <param name="value">The text to format.</param>
/// <returns>Formatted text or "-" if null or empty.</returns>
public static string Text(string? value)
{
return string.IsNullOrWhiteSpace(value) ? "-" : value;
}
/// <summary>
/// Formats a long count value for display with thousands separator.
/// </summary>
/// <param name="value">The count to format.</param>
/// <returns>Formatted count string.</returns>
public static string Count(long value)
{
return value.ToString("N0", System.Globalization.CultureInfo.InvariantCulture);
}
/// <summary>
/// Retrieves a metric value from a snapshot by name and optional dimension.
/// </summary>
/// <param name="snapshot">Dashboard snapshot.</param>
/// <param name="name">Metric name.</param>
/// <param name="dimension">Optional metric dimension.</param>
/// <returns>Metric value or zero if not found.</returns>
public static long MetricValue(DashboardSnapshot snapshot, string name, string? dimension = null)
{
return snapshot.Metrics.FirstOrDefault(metric =>
@@ -2,21 +2,32 @@ using Microsoft.AspNetCore.Components;
namespace MxGateway.Server.Dashboard.Components;
/// <summary>
/// Base class for Blazor dashboard pages that watch gateway metrics snapshots.
/// </summary>
public abstract class DashboardPageBase : ComponentBase, IAsyncDisposable
{
private readonly CancellationTokenSource _disposeCancellation = new();
private Task? _watchTask;
/// <summary>
/// Service that provides gateway metric snapshots.
/// </summary>
[Inject]
protected IDashboardSnapshotService SnapshotService { get; set; } = null!;
/// <summary>
/// The most recent gateway metric snapshot, updated as it changes.
/// </summary>
protected DashboardSnapshot? Snapshot { get; private set; }
/// <inheritdoc />
protected override void OnInitialized()
{
_watchTask = WatchSnapshotsAsync();
}
/// <inheritdoc />
public async ValueTask DisposeAsync()
{
await _disposeCancellation.CancelAsync().ConfigureAwait(false);
@@ -29,6 +40,9 @@ public abstract class DashboardPageBase : ComponentBase, IAsyncDisposable
GC.SuppressFinalize(this);
}
/// <summary>
/// Watches snapshot changes and triggers component refresh.
/// </summary>
private async Task WatchSnapshotsAsync()
{
try
@@ -2,16 +2,36 @@ using System.Security.Claims;
namespace MxGateway.Server.Dashboard;
/// <summary>
/// Result of a dashboard authentication attempt.
/// </summary>
public sealed record DashboardAuthenticationResult(
/// <summary>
/// Whether authentication succeeded.
/// </summary>
bool Succeeded,
/// <summary>
/// The authenticated principal if successful; otherwise null.
/// </summary>
ClaimsPrincipal? Principal,
/// <summary>
/// The failure message if authentication failed; otherwise null.
/// </summary>
string? FailureMessage)
{
/// <summary>
/// Creates a successful authentication result.
/// </summary>
/// <param name="principal">Authenticated principal.</param>
public static DashboardAuthenticationResult Success(ClaimsPrincipal principal)
{
return new DashboardAuthenticationResult(true, principal, null);
}
/// <summary>
/// Creates a failed authentication result.
/// </summary>
/// <param name="failureMessage">Diagnostic message describing the failure.</param>
public static DashboardAuthenticationResult Fail(string failureMessage)
{
return new DashboardAuthenticationResult(false, null, failureMessage);
@@ -12,6 +12,7 @@ public sealed class DashboardAuthenticator(
{
private const string GenericFailureMessage = "The API key is invalid or is not authorized for dashboard access.";
/// <inheritdoc />
public async Task<DashboardAuthenticationResult> AuthenticateAsync(
string? apiKey,
CancellationToken cancellationToken)
@@ -10,6 +10,7 @@ public sealed class DashboardAuthorizationHandler(
IHttpContextAccessor httpContextAccessor,
IOptions<GatewayOptions> options) : AuthorizationHandler<DashboardAuthorizationRequirement>
{
/// <inheritdoc />
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
DashboardAuthorizationRequirement requirement)
@@ -7,8 +7,12 @@ using MxGateway.Server.Dashboard.Components;
namespace MxGateway.Server.Dashboard;
/// <summary>Endpoint extensions for registering the gateway dashboard routes.</summary>
public static class DashboardEndpointRouteBuilderExtensions
{
/// <summary>Maps all gateway dashboard routes including login, logout, and Razor components.</summary>
/// <param name="endpoints">The endpoint route builder.</param>
/// <returns>The route builder for chaining.</returns>
public static IEndpointRouteBuilder MapGatewayDashboard(this IEndpointRouteBuilder endpoints)
{
IConfiguration configuration = endpoints.ServiceProvider.GetRequiredService<IConfiguration>();
@@ -8,6 +8,7 @@ namespace MxGateway.Server.Dashboard;
/// per-category breakdowns are computed here rather than stored on the cache so the
/// Galaxy namespace stays free of dashboard-presentation concepts.
/// </summary>
/// <summary>Projects Galaxy Repository cache entries to dashboard presentation format.</summary>
internal static class DashboardGalaxyProjector
{
private const int TopTemplatesLimit = 10;
@@ -25,6 +26,9 @@ internal static class DashboardGalaxyProjector
[26] = "OPCClient",
};
/// <summary>Projects a Galaxy Repository cache entry to a dashboard summary.</summary>
/// <param name="entry">Galaxy cache entry to project.</param>
/// <returns>Dashboard-formatted Galaxy summary.</returns>
public static DashboardGalaxySummary Project(GalaxyHierarchyCacheEntry entry)
{
DashboardGalaxyStatus status = entry.Status switch
@@ -19,6 +19,7 @@ public sealed record DashboardGalaxySummary(
IReadOnlyList<DashboardGalaxyTemplateUsage> TopTemplates,
IReadOnlyList<DashboardGalaxyCategoryCount> ObjectCategories)
{
/// <summary>Gets the unknown Galaxy status placeholder.</summary>
public static DashboardGalaxySummary Unknown { get; } = new(
DashboardGalaxyStatus.Unknown,
LastQueriedAt: null,
@@ -15,6 +15,11 @@ internal static class DashboardRedactor
"token",
];
/// <summary>
/// Redacts sensitive content from a value for dashboard display.
/// </summary>
/// <param name="value">Value to redact.</param>
/// <returns>Redacted value or original value if not sensitive.</returns>
public static string? Redact(string? value)
{
if (string.IsNullOrWhiteSpace(value))
@@ -5,8 +5,15 @@ using MxGateway.Server.Configuration;
namespace MxGateway.Server.Dashboard;
/// <summary>
/// Extension methods for configuring the gateway dashboard services.
/// </summary>
public static class DashboardServiceCollectionExtensions
{
/// <summary>
/// Registers all dashboard services, authentication, and Razor components.
/// </summary>
/// <param name="services">Service collection to register services.</param>
public static IServiceCollection AddGatewayDashboard(this IServiceCollection services)
{
services.AddSingleton<IDashboardSnapshotService, DashboardSnapshotService>();
@@ -22,6 +22,13 @@ public sealed class DashboardSnapshotService : IDashboardSnapshotService
private readonly int _recentFaultLimit;
private readonly int _recentSessionLimit;
/// <summary>Initializes a new instance of the DashboardSnapshotService class.</summary>
/// <param name="sessionRegistry">Registry of active gateway sessions.</param>
/// <param name="metrics">Gateway metrics collector.</param>
/// <param name="configurationProvider">Gateway configuration provider.</param>
/// <param name="galaxyHierarchyCache">Galaxy hierarchy cache.</param>
/// <param name="options">Gateway configuration options.</param>
/// <param name="timeProvider">Provider for current time; defaults to system time.</param>
public DashboardSnapshotService(
ISessionRegistry sessionRegistry,
GatewayMetrics metrics,
@@ -43,6 +50,10 @@ public sealed class DashboardSnapshotService : IDashboardSnapshotService
_recentSessionLimit = options.Value.Dashboard.RecentSessionLimit;
}
/// <summary>
/// Gets a current dashboard snapshot of gateway state.
/// </summary>
/// <returns>Dashboard snapshot.</returns>
public DashboardSnapshot GetSnapshot()
{
DateTimeOffset generatedAt = _timeProvider.GetUtcNow();
@@ -73,6 +84,11 @@ public sealed class DashboardSnapshotService : IDashboardSnapshotService
Galaxy: DashboardGalaxyProjector.Project(_galaxyHierarchyCache.Current));
}
/// <summary>
/// Watches dashboard snapshots at regular intervals asynchronously.
/// </summary>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>Async enumerable of dashboard snapshots.</returns>
public async IAsyncEnumerable<DashboardSnapshot> WatchSnapshotsAsync(
[EnumeratorCancellation] CancellationToken cancellationToken)
{
@@ -1,7 +1,15 @@
namespace MxGateway.Server.Dashboard;
/// <summary>
/// Authenticates dashboard access with API keys.
/// </summary>
public interface IDashboardAuthenticator
{
/// <summary>
/// Authenticates the dashboard session with an API key.
/// </summary>
/// <param name="apiKey">The API key to authenticate.</param>
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
Task<DashboardAuthenticationResult> AuthenticateAsync(
string? apiKey,
CancellationToken cancellationToken);
@@ -1,8 +1,18 @@
namespace MxGateway.Server.Dashboard;
/// <summary>
/// Provides snapshots of the dashboard state for UI updates.
/// </summary>
public interface IDashboardSnapshotService
{
/// <summary>
/// Gets the current dashboard snapshot.
/// </summary>
DashboardSnapshot GetSnapshot();
/// <summary>
/// Watches for changes to the dashboard state as an async enumerable.
/// </summary>
/// <param name="cancellationToken">Token to cancel the asynchronous operation.</param>
IAsyncEnumerable<DashboardSnapshot> WatchSnapshotsAsync(CancellationToken cancellationToken);
}