up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
oas-ci / oas-validate (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
oas-ci / oas-validate (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using StellaOps.Notifier.Worker.StormBreaker;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
/// <summary>
|
||||
/// REST API endpoints for storm breaker operations.
|
||||
/// </summary>
|
||||
public static class StormBreakerEndpoints
|
||||
{
|
||||
/// <summary>
|
||||
/// Maps storm breaker API endpoints.
|
||||
/// </summary>
|
||||
public static RouteGroupBuilder MapStormBreakerEndpoints(this IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var group = endpoints.MapGroup("/api/v2/storm-breaker")
|
||||
.WithTags("Storm Breaker")
|
||||
.WithOpenApi();
|
||||
|
||||
// List active storms for tenant
|
||||
group.MapGet("/storms", async (
|
||||
HttpContext context,
|
||||
IStormBreaker stormBreaker,
|
||||
CancellationToken cancellationToken) =>
|
||||
{
|
||||
var tenantId = context.Request.Headers["X-Tenant-Id"].FirstOrDefault() ?? "default";
|
||||
|
||||
var storms = await stormBreaker.GetActiveStormsAsync(tenantId, cancellationToken);
|
||||
|
||||
return Results.Ok(new
|
||||
{
|
||||
tenantId,
|
||||
activeStorms = storms.Select(s => new
|
||||
{
|
||||
s.TenantId,
|
||||
s.StormKey,
|
||||
s.StartedAt,
|
||||
eventCount = s.EventIds.Count,
|
||||
s.SuppressedCount,
|
||||
s.LastActivityAt,
|
||||
s.IsActive
|
||||
}).ToList(),
|
||||
count = storms.Count
|
||||
});
|
||||
})
|
||||
.WithName("ListActiveStorms")
|
||||
.WithSummary("Lists all active notification storms for a tenant");
|
||||
|
||||
// Get specific storm state
|
||||
group.MapGet("/storms/{stormKey}", async (
|
||||
string stormKey,
|
||||
HttpContext context,
|
||||
IStormBreaker stormBreaker,
|
||||
CancellationToken cancellationToken) =>
|
||||
{
|
||||
var tenantId = context.Request.Headers["X-Tenant-Id"].FirstOrDefault() ?? "default";
|
||||
|
||||
var state = await stormBreaker.GetStateAsync(tenantId, stormKey, cancellationToken);
|
||||
if (state is null)
|
||||
{
|
||||
return Results.NotFound(new { error = $"No storm found with key '{stormKey}'" });
|
||||
}
|
||||
|
||||
return Results.Ok(new
|
||||
{
|
||||
state.TenantId,
|
||||
state.StormKey,
|
||||
state.StartedAt,
|
||||
eventCount = state.EventIds.Count,
|
||||
state.SuppressedCount,
|
||||
state.LastActivityAt,
|
||||
state.LastSummaryAt,
|
||||
state.IsActive,
|
||||
sampleEventIds = state.EventIds.Take(10).ToList()
|
||||
});
|
||||
})
|
||||
.WithName("GetStormState")
|
||||
.WithSummary("Gets the current state of a specific storm");
|
||||
|
||||
// Generate storm summary
|
||||
group.MapPost("/storms/{stormKey}/summary", async (
|
||||
string stormKey,
|
||||
HttpContext context,
|
||||
IStormBreaker stormBreaker,
|
||||
CancellationToken cancellationToken) =>
|
||||
{
|
||||
var tenantId = context.Request.Headers["X-Tenant-Id"].FirstOrDefault() ?? "default";
|
||||
|
||||
var summary = await stormBreaker.GenerateSummaryAsync(tenantId, stormKey, cancellationToken);
|
||||
if (summary is null)
|
||||
{
|
||||
return Results.NotFound(new { error = $"No storm found with key '{stormKey}'" });
|
||||
}
|
||||
|
||||
return Results.Ok(summary);
|
||||
})
|
||||
.WithName("GenerateStormSummary")
|
||||
.WithSummary("Generates a summary for an active storm");
|
||||
|
||||
// Clear storm state
|
||||
group.MapDelete("/storms/{stormKey}", async (
|
||||
string stormKey,
|
||||
HttpContext context,
|
||||
IStormBreaker stormBreaker,
|
||||
CancellationToken cancellationToken) =>
|
||||
{
|
||||
var tenantId = context.Request.Headers["X-Tenant-Id"].FirstOrDefault() ?? "default";
|
||||
|
||||
await stormBreaker.ClearAsync(tenantId, stormKey, cancellationToken);
|
||||
|
||||
return Results.Ok(new { message = $"Storm '{stormKey}' cleared successfully" });
|
||||
})
|
||||
.WithName("ClearStorm")
|
||||
.WithSummary("Clears a storm state manually");
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user