using OTSSignsOrchestrator.Server.Clients; using OTSSignsOrchestrator.Server.Data.Entities; namespace OTSSignsOrchestrator.Server.Health.Checks; /// /// Verifies the Xibo CMS API is reachable by calling GET /about and expecting a 200 response. /// public sealed class XiboApiHealthCheck : IHealthCheck { private readonly XiboClientFactory _clientFactory; private readonly IServiceProvider _services; private readonly ILogger _logger; public string CheckName => "XiboApi"; public bool AutoRemediate => false; public XiboApiHealthCheck( XiboClientFactory clientFactory, IServiceProvider services, ILogger logger) { _clientFactory = clientFactory; _services = services; _logger = logger; } public async Task RunAsync(Instance instance, CancellationToken ct) { var client = await ResolveClientAsync(instance); if (client is null) return new HealthCheckResult(HealthStatus.Critical, "No OAuth app registered — cannot reach API"); try { var response = await client.GetAboutAsync(); return response.IsSuccessStatusCode ? new HealthCheckResult(HealthStatus.Healthy, "Xibo API reachable") : new HealthCheckResult(HealthStatus.Critical, $"Xibo API returned {response.StatusCode}", response.Error?.Content); } catch (Exception ex) { return new HealthCheckResult(HealthStatus.Critical, $"Xibo API unreachable: {ex.Message}"); } } private async Task ResolveClientAsync(Instance instance) { var oauthApp = instance.OauthAppRegistries.FirstOrDefault(); if (oauthApp is null) return null; var settings = _services.GetRequiredService(); var abbrev = instance.Customer.Abbreviation; var secret = await settings.GetAsync(Core.Services.SettingsService.InstanceOAuthSecretId(abbrev)); if (string.IsNullOrEmpty(secret)) return null; return await _clientFactory.CreateAsync(instance.XiboUrl, oauthApp.ClientId, secret); } }