Initial import into Gitea
This commit is contained in:
112
Management/Controllers/Admin/AdminMetricSyncController.cs
Normal file
112
Management/Controllers/Admin/AdminMetricSyncController.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user