Restore platform ownership for v2 evidence routes

This commit is contained in:
master
2026-03-10 13:10:06 +02:00
parent ffd4646d89
commit fc7aaf4d37
9 changed files with 132 additions and 5 deletions

View File

@@ -18,6 +18,7 @@ public sealed class GatewayRouteSearchMappingsTests
("^/api/v2/releases(.*)", "http://platform.stella-ops.local/api/v2/releases$1", "Microservice", true),
("^/api/v2/security(.*)", "http://platform.stella-ops.local/api/v2/security$1", "Microservice", true),
("^/api/v2/topology(.*)", "http://platform.stella-ops.local/api/v2/topology$1", "Microservice", true),
("^/api/v2/evidence(.*)", "http://platform.stella-ops.local/api/v2/evidence$1", "Microservice", true),
("^/api/v2/integrations(.*)", "http://platform.stella-ops.local/api/v2/integrations$1", "Microservice", true),
("^/scheduler(?=/|$)(.*)", "http://scheduler.stella-ops.local$1", "Microservice", true),
("^/doctor(?=/|$)(.*)", "http://doctor.stella-ops.local$1", "Microservice", true),

View File

@@ -390,6 +390,53 @@ public sealed class RouteDispatchMiddlewareMicroserviceTests
context.Items[RouterHttpContextKeys.TranslatedRequestPath] as string);
}
[Fact]
public async Task InvokeAsync_SpecificPlatformV2EvidenceRoute_PrefersPlatformOverGenericCatchAll()
{
var resolver = new StellaOpsRouteResolver(
[
new StellaOpsRoute
{
Type = StellaOpsRouteType.Microservice,
Path = @"^/api/v2/evidence(.*)",
IsRegex = true,
TranslatesTo = "http://platform.stella-ops.local/api/v2/evidence$1"
},
new StellaOpsRoute
{
Type = StellaOpsRouteType.Microservice,
Path = @"^/api/v2/([^/]+)(.*)",
IsRegex = true,
TranslatesTo = "http://$1.stella-ops.local/api/v2/$1$2"
}
]);
var httpClientFactory = new Mock<IHttpClientFactory>();
httpClientFactory.Setup(factory => factory.CreateClient(It.IsAny<string>())).Returns(new HttpClient());
var nextCalled = false;
var middleware = new RouteDispatchMiddleware(
_ =>
{
nextCalled = true;
return Task.CompletedTask;
},
resolver,
httpClientFactory.Object,
NullLogger<RouteDispatchMiddleware>.Instance);
var context = new DefaultHttpContext();
context.Request.Path = "/api/v2/evidence/packs";
await middleware.InvokeAsync(context);
Assert.True(nextCalled);
Assert.Equal(
"platform",
context.Items[RouterHttpContextKeys.RouteTargetMicroservice] as string);
Assert.False(context.Items.ContainsKey(RouterHttpContextKeys.TranslatedRequestPath));
}
[Theory]
[InlineData("/doctor/api/v1/doctor/checks", @"^/doctor(?=/|$)(.*)", "http://doctor.stella-ops.local$1", "doctor", "/api/v1/doctor/checks")]
[InlineData("/scheduler/api/v1/scheduler/runs", @"^/scheduler(?=/|$)(.*)", "http://scheduler.stella-ops.local$1", "scheduler", "/api/v1/scheduler/runs")]

View File

@@ -152,6 +152,29 @@ public sealed class StellaOpsRouteResolverTests
Assert.Equal(expectedCapture, result.RegexMatch!.Groups[1].Value);
}
[Fact]
public void Resolve_SpecificPlatformV2EvidenceRoute_BeatsGenericCatchAll()
{
var resolver = new StellaOpsRouteResolver(
[
MakeRoute(
@"^/api/v2/evidence(.*)",
isRegex: true,
translatesTo: "http://platform.stella-ops.local/api/v2/evidence$1"),
MakeRoute(
@"^/api/v2/([^/]+)(.*)",
isRegex: true,
translatesTo: "http://$1.stella-ops.local/api/v2/$1$2")
]);
var result = resolver.Resolve(new PathString("/api/v2/evidence/packs"));
Assert.NotNull(result.Route);
Assert.Equal(@"^/api/v2/evidence(.*)", result.Route!.Path);
Assert.NotNull(result.RegexMatch);
Assert.Equal("/packs", result.RegexMatch!.Groups[1].Value);
}
[Fact]
public void Resolve_NoMatch_ReturnsNull()
{