Add XML documentation across gateway, worker, and .NET client
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user