Restructure solution layout by module

This commit is contained in:
master
2025-10-28 15:10:40 +02:00
parent 95daa159c4
commit d870da18ce
4103 changed files with 192899 additions and 187024 deletions

View File

@@ -0,0 +1,161 @@
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using StellaOps.Auth.Abstractions;
using StellaOps.Scheduler.Models;
using StellaOps.Scheduler.WebService.Auth;
namespace StellaOps.Scheduler.WebService.GraphJobs;
public static class GraphJobEndpointExtensions
{
public static void MapGraphJobEndpoints(this IEndpointRouteBuilder builder)
{
var group = builder.MapGroup("/graphs");
group.MapPost("/build", CreateGraphBuildJob);
group.MapPost("/overlays", CreateGraphOverlayJob);
group.MapGet("/jobs", GetGraphJobs);
group.MapPost("/hooks/completed", CompleteGraphJob);
group.MapGet("/overlays/lag", GetOverlayLagMetrics);
}
internal static async Task<IResult> CreateGraphBuildJob(
[FromBody] GraphBuildJobRequest request,
HttpContext httpContext,
[FromServices] ITenantContextAccessor tenantAccessor,
[FromServices] IScopeAuthorizer authorizer,
[FromServices] IGraphJobService jobService,
CancellationToken cancellationToken)
{
try
{
authorizer.EnsureScope(httpContext, StellaOpsScopes.GraphWrite);
var tenant = tenantAccessor.GetTenant(httpContext);
var job = await jobService.CreateBuildJobAsync(tenant.TenantId, request, cancellationToken);
return Results.Created($"/graphs/jobs/{job.Id}", GraphJobResponse.From(job));
}
catch (UnauthorizedAccessException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status401Unauthorized);
}
catch (InvalidOperationException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status403Forbidden);
}
catch (ValidationException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status400BadRequest);
}
catch (KeyNotFoundException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status404NotFound);
}
}
internal static async Task<IResult> CreateGraphOverlayJob(
[FromBody] GraphOverlayJobRequest request,
HttpContext httpContext,
[FromServices] ITenantContextAccessor tenantAccessor,
[FromServices] IScopeAuthorizer authorizer,
[FromServices] IGraphJobService jobService,
CancellationToken cancellationToken)
{
try
{
authorizer.EnsureScope(httpContext, StellaOpsScopes.GraphWrite);
var tenant = tenantAccessor.GetTenant(httpContext);
var job = await jobService.CreateOverlayJobAsync(tenant.TenantId, request, cancellationToken);
return Results.Created($"/graphs/jobs/{job.Id}", GraphJobResponse.From(job));
}
catch (UnauthorizedAccessException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status401Unauthorized);
}
catch (InvalidOperationException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status403Forbidden);
}
catch (ValidationException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status400BadRequest);
}
}
internal static async Task<IResult> GetGraphJobs(
[AsParameters] GraphJobQuery query,
HttpContext httpContext,
[FromServices] ITenantContextAccessor tenantAccessor,
[FromServices] IScopeAuthorizer authorizer,
[FromServices] IGraphJobService jobService,
CancellationToken cancellationToken)
{
try
{
authorizer.EnsureScope(httpContext, StellaOpsScopes.GraphRead);
var tenant = tenantAccessor.GetTenant(httpContext);
var jobs = await jobService.GetJobsAsync(tenant.TenantId, query, cancellationToken);
return Results.Ok(jobs);
}
catch (UnauthorizedAccessException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status401Unauthorized);
}
catch (InvalidOperationException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status403Forbidden);
}
}
internal static async Task<IResult> CompleteGraphJob(
[FromBody] GraphJobCompletionRequest request,
HttpContext httpContext,
[FromServices] ITenantContextAccessor tenantAccessor,
[FromServices] IScopeAuthorizer authorizer,
[FromServices] IGraphJobService jobService,
CancellationToken cancellationToken)
{
try
{
authorizer.EnsureScope(httpContext, StellaOpsScopes.GraphWrite);
var tenant = tenantAccessor.GetTenant(httpContext);
var response = await jobService.CompleteJobAsync(tenant.TenantId, request, cancellationToken);
return Results.Ok(response);
}
catch (UnauthorizedAccessException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status401Unauthorized);
}
catch (KeyNotFoundException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status404NotFound);
}
catch (InvalidOperationException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status403Forbidden);
}
catch (ValidationException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status400BadRequest);
}
}
internal static async Task<IResult> GetOverlayLagMetrics(
HttpContext httpContext,
[FromServices] ITenantContextAccessor tenantAccessor,
[FromServices] IScopeAuthorizer authorizer,
[FromServices] IGraphJobService jobService,
CancellationToken cancellationToken)
{
try
{
authorizer.EnsureScope(httpContext, StellaOpsScopes.GraphRead);
var tenant = tenantAccessor.GetTenant(httpContext);
var metrics = await jobService.GetOverlayLagMetricsAsync(tenant.TenantId, cancellationToken);
return Results.Ok(metrics);
}
catch (UnauthorizedAccessException ex)
{
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status401Unauthorized);
}
}
}