using Fleet.Core; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using MoShiro.Backend.Application; using MoShiro.Protocol; namespace MoShiro.Backend.Api; /// 线路开关:哪些(Probe,Agent)要连。自动连接的总开关是设置 fleet.auto_link;这里看每一对的结果,并且手动强制开、关或取消手动设置。 public static class LinkEndpoints { private const string Tag = "admin-links"; public static void Map(RouteGroupBuilder group) { group.MapGet("/links", ListAsync) .Api("links_list", "Every probe/agent pair: whether it is linked, the manual override and whether it is connected", Tag).Returns().ProducesProblems(401, 403); group.MapPut("/links/{probe_id}/{agent_id}", SetAsync) .Api("links_set", "Force a link on or off, or give it back to the automatic setting (enabled: null)", Tag).Returns().ProducesProblems(400, 401, 403, 404); } private static async Task ListAsync(AgentService agents, ProbeService probes, LinkService links, CancellationToken ct) { LinkSnapshot snapshot = await links.SnapshotAsync(ct); IReadOnlyList agentViews = await agents.ListAsync(ct); var items = new List(); foreach (ProbeView probe in (await probes.ListAsync(ct)).Where(p => !p.Revoked).OrderBy(p => p.Probe.Name, StringComparer.Ordinal)) { foreach (AgentView agent in agentViews.OrderBy(a => a.Agent.Name, StringComparer.Ordinal)) { items.Add(ToDto(snapshot, probe, agent)); } } return TypedResults.Json(new LinkMatrixDto(snapshot.Auto, items), ApiJsonContext.Default.LinkMatrixDto); } private static async Task SetAsync(HttpContext http, AgentService agents, ProbeService probes, LinkService links, string probe_id, string agent_id, SetLinkRequest request, CancellationToken ct) { if (await probes.GetAsync(probe_id, ct) is not { Revoked: false } probe) { return Problems.Create(http, MoShiroErrors.ProbeNotFound, "probe not found"); } if (await agents.GetAsync(new NodeId(agent_id), ct) is not { } agent) { return Problems.Create(http, MoShiroErrors.AgentNotFound, "agent not found"); } await links.SetAsync(probe_id, agent_id, request.Enabled, ct); await agents.AfterAgentSetChangedAsync(ct); // 重新下发:Probe 的 Agent 列表、Agent 允许的 Probe return TypedResults.Json(ToDto(await links.SnapshotAsync(ct), probe, agent), ApiJsonContext.Default.LinkDto); } private static LinkDto ToDto(LinkSnapshot snapshot, ProbeView probe, AgentView agent) => new(probe.Probe.Id, probe.Probe.Name, agent.Agent.Id.Value, agent.Agent.Name, snapshot.IsLinked(probe.Probe.Id, agent.Agent.Id.Value), snapshot.OverrideOf(probe.Probe.Id, agent.Agent.Id.Value), agent.Probes.Any(p => p.Id == probe.Probe.Id)); }