113 lines
4.2 KiB
C#
113 lines
4.2 KiB
C#
using Management.Data;
|
|
using Management.Security;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using System.Text.Json;
|
|
|
|
namespace Management.Controllers.Admin;
|
|
|
|
/// <summary>
|
|
/// Admin endpoint for manually triggering metric sync.
|
|
///
|
|
/// ENDPOINTS:
|
|
/// POST /api/admin/sync/metrics/{clientId} - Sync a specific client
|
|
/// POST /api/admin/sync/metrics - Sync all active clients
|
|
///
|
|
/// Proxies to Gateway /api/sync/metrics/* using an internal service key.
|
|
/// Gateway owns provider connectivity; Management owns the trigger surface.
|
|
/// Configure via GATEWAY_URL + INTERNAL_SERVICE_KEY env vars.
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/admin/sync")]
|
|
public sealed class AdminMetricSyncController : AdminControllerBase
|
|
{
|
|
private readonly IHttpClientFactory _http;
|
|
private readonly IConfiguration _config;
|
|
|
|
public AdminMetricSyncController(
|
|
SqlService sql,
|
|
ClientContext client,
|
|
ILogger<AdminMetricSyncController> log,
|
|
IHttpClientFactory http,
|
|
IConfiguration config)
|
|
: base(sql, client, log)
|
|
{
|
|
_http = http;
|
|
_config = config;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Trigger metric sync for a specific client.
|
|
/// </summary>
|
|
[HttpPost("metrics/{clientId}")]
|
|
public async Task<IActionResult> SyncClient(
|
|
string clientId,
|
|
[FromQuery] string? startDate,
|
|
[FromQuery] string? endDate,
|
|
CancellationToken ct)
|
|
{
|
|
Logger.LogInformation("[Admin] MetricSync triggered for client {ClientId} | By={User}",
|
|
clientId, Client.Email);
|
|
|
|
return await ProxyToGateway($"metrics/{Uri.EscapeDataString(clientId)}", startDate, endDate, ct);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Trigger metric sync for all active clients.
|
|
/// </summary>
|
|
[HttpPost("metrics")]
|
|
public async Task<IActionResult> SyncAll(
|
|
[FromQuery] string? startDate,
|
|
[FromQuery] string? endDate,
|
|
CancellationToken ct)
|
|
{
|
|
Logger.LogInformation("[Admin] MetricSync ALL clients triggered | By={User}", Client.Email);
|
|
|
|
return await ProxyToGateway("metrics/all", startDate, endDate, ct);
|
|
}
|
|
|
|
// ────────────────────────────────────────────────
|
|
// Proxy helper
|
|
// ────────────────────────────────────────────────
|
|
|
|
private async Task<IActionResult> ProxyToGateway(
|
|
string path, string? startDate, string? endDate, CancellationToken ct)
|
|
{
|
|
var gatewayUrl = _config["GATEWAY_URL"]?.TrimEnd('/');
|
|
var serviceKey = _config["INTERNAL_SERVICE_KEY"];
|
|
|
|
if (string.IsNullOrWhiteSpace(gatewayUrl))
|
|
return StatusCode(500, new { ok = false, error = "GATEWAY_URL not configured" });
|
|
if (string.IsNullOrWhiteSpace(serviceKey))
|
|
return StatusCode(500, new { ok = false, error = "INTERNAL_SERVICE_KEY not configured" });
|
|
|
|
var qs = new List<string>();
|
|
if (!string.IsNullOrWhiteSpace(startDate)) qs.Add($"startDate={Uri.EscapeDataString(startDate)}");
|
|
if (!string.IsNullOrWhiteSpace(endDate)) qs.Add($"endDate={Uri.EscapeDataString(endDate)}");
|
|
|
|
var url = $"{gatewayUrl}/api/sync/{path}";
|
|
if (qs.Count > 0) url += "?" + string.Join("&", qs);
|
|
|
|
try
|
|
{
|
|
var client = _http.CreateClient();
|
|
using var req = new HttpRequestMessage(HttpMethod.Post, url);
|
|
req.Headers.Add("X-Service-Key", serviceKey);
|
|
|
|
using var resp = await client.SendAsync(req, ct);
|
|
var body = await resp.Content.ReadAsStringAsync(ct);
|
|
|
|
Logger.LogInformation("[Admin] MetricSync Gateway response {Status} | Path={Path}",
|
|
(int)resp.StatusCode, path);
|
|
|
|
return resp.IsSuccessStatusCode
|
|
? Content(body, "application/json")
|
|
: StatusCode((int)resp.StatusCode, new { ok = false, error = $"Gateway returned {(int)resp.StatusCode}", detail = body });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogError(ex, "[Admin] MetricSync proxy error | Path={Path}", path);
|
|
return StatusCode(500, new { ok = false, error = "Sync trigger failed", detail = ex.Message });
|
|
}
|
|
}
|
|
}
|