fix(catalog): preserve fromEndpointUri for removed routes
Both catalog controllers resolved the from-endpoint URI via findContentHashForRouteByAgents, which filtered by the currently-live agent instance_ids. Routes removed between app versions therefore lost their fromUri even though the diagram row still exists. Route through findLatestContentHashForAppRoute so resolution depends only on (app, env, route) — stays populated for historical routes. CatalogController now resolves the per-row env slug up-front so the fromUri lookup works even for cross-env queries against managed apps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -196,7 +196,16 @@ public class CatalogController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Set<String> routeIds = routesByApp.getOrDefault(slug, Set.of());
|
Set<String> routeIds = routesByApp.getOrDefault(slug, Set.of());
|
||||||
List<String> agentIds = agents.stream().map(AgentInfo::instanceId).toList();
|
|
||||||
|
// Resolve the env slug for this row early so fromUri can survive
|
||||||
|
// cross-env queries (env==null) against managed apps.
|
||||||
|
String rowEnvSlug = envSlug;
|
||||||
|
if (app != null && rowEnvSlug.isEmpty()) {
|
||||||
|
try {
|
||||||
|
rowEnvSlug = envService.getById(app.environmentId()).slug();
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
}
|
||||||
|
final String resolvedEnvSlug = rowEnvSlug;
|
||||||
|
|
||||||
// Routes
|
// Routes
|
||||||
List<RouteSummary> routeSummaries = routeIds.stream()
|
List<RouteSummary> routeSummaries = routeIds.stream()
|
||||||
@@ -204,7 +213,7 @@ public class CatalogController {
|
|||||||
String key = slug + "/" + routeId;
|
String key = slug + "/" + routeId;
|
||||||
long count = routeExchangeCounts.getOrDefault(key, 0L);
|
long count = routeExchangeCounts.getOrDefault(key, 0L);
|
||||||
Instant lastSeen = routeLastSeen.get(key);
|
Instant lastSeen = routeLastSeen.get(key);
|
||||||
String fromUri = resolveFromEndpointUri(routeId, agentIds);
|
String fromUri = resolveFromEndpointUri(slug, routeId, resolvedEnvSlug);
|
||||||
String state = routeStateRegistry.getState(slug, routeId).name().toLowerCase();
|
String state = routeStateRegistry.getState(slug, routeId).name().toLowerCase();
|
||||||
String routeState = "started".equals(state) ? null : state;
|
String routeState = "started".equals(state) ? null : state;
|
||||||
return new RouteSummary(routeId, count, lastSeen, fromUri, routeState);
|
return new RouteSummary(routeId, count, lastSeen, fromUri, routeState);
|
||||||
@@ -258,15 +267,9 @@ public class CatalogController {
|
|||||||
String healthTooltip = buildHealthTooltip(app != null, deployStatus, agentHealth, agents.size());
|
String healthTooltip = buildHealthTooltip(app != null, deployStatus, agentHealth, agents.size());
|
||||||
|
|
||||||
String displayName = app != null ? app.displayName() : slug;
|
String displayName = app != null ? app.displayName() : slug;
|
||||||
String appEnvSlug = envSlug;
|
|
||||||
if (app != null && appEnvSlug.isEmpty()) {
|
|
||||||
try {
|
|
||||||
appEnvSlug = envService.getById(app.environmentId()).slug();
|
|
||||||
} catch (Exception ignored) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
catalog.add(new CatalogApp(
|
catalog.add(new CatalogApp(
|
||||||
slug, displayName, app != null, appEnvSlug,
|
slug, displayName, app != null, resolvedEnvSlug,
|
||||||
health, healthTooltip, agents.size(), routeSummaries, agentSummaries,
|
health, healthTooltip, agents.size(), routeSummaries, agentSummaries,
|
||||||
totalExchanges, deploymentSummary
|
totalExchanges, deploymentSummary
|
||||||
));
|
));
|
||||||
@@ -275,8 +278,11 @@ public class CatalogController {
|
|||||||
return ResponseEntity.ok(catalog);
|
return ResponseEntity.ok(catalog);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String resolveFromEndpointUri(String routeId, List<String> agentIds) {
|
private String resolveFromEndpointUri(String applicationId, String routeId, String environment) {
|
||||||
return diagramStore.findContentHashForRouteByAgents(routeId, agentIds)
|
if (environment == null || environment.isBlank()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return diagramStore.findLatestContentHashForAppRoute(applicationId, routeId, environment)
|
||||||
.flatMap(diagramStore::findByContentHash)
|
.flatMap(diagramStore::findByContentHash)
|
||||||
.map(RouteGraph::getRoot)
|
.map(RouteGraph::getRoot)
|
||||||
.map(root -> root.getEndpointUri())
|
.map(root -> root.getEndpointUri())
|
||||||
|
|||||||
@@ -132,13 +132,12 @@ public class RouteCatalogController {
|
|||||||
List<AgentInfo> agents = agentsByApp.getOrDefault(appId, List.of());
|
List<AgentInfo> agents = agentsByApp.getOrDefault(appId, List.of());
|
||||||
|
|
||||||
Set<String> routeIds = routesByApp.getOrDefault(appId, Set.of());
|
Set<String> routeIds = routesByApp.getOrDefault(appId, Set.of());
|
||||||
List<String> agentIds = agents.stream().map(AgentInfo::instanceId).toList();
|
|
||||||
List<RouteSummary> routeSummaries = routeIds.stream()
|
List<RouteSummary> routeSummaries = routeIds.stream()
|
||||||
.map(routeId -> {
|
.map(routeId -> {
|
||||||
String key = appId + "/" + routeId;
|
String key = appId + "/" + routeId;
|
||||||
long count = routeExchangeCounts.getOrDefault(key, 0L);
|
long count = routeExchangeCounts.getOrDefault(key, 0L);
|
||||||
Instant lastSeen = routeLastSeen.get(key);
|
Instant lastSeen = routeLastSeen.get(key);
|
||||||
String fromUri = resolveFromEndpointUri(routeId, agentIds);
|
String fromUri = resolveFromEndpointUri(appId, routeId, envSlug);
|
||||||
String state = routeStateRegistry.getState(appId, routeId).name().toLowerCase();
|
String state = routeStateRegistry.getState(appId, routeId).name().toLowerCase();
|
||||||
String routeState = "started".equals(state) ? null : state;
|
String routeState = "started".equals(state) ? null : state;
|
||||||
return new RouteSummary(routeId, count, lastSeen, fromUri, routeState);
|
return new RouteSummary(routeId, count, lastSeen, fromUri, routeState);
|
||||||
@@ -160,8 +159,8 @@ public class RouteCatalogController {
|
|||||||
return ResponseEntity.ok(catalog);
|
return ResponseEntity.ok(catalog);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String resolveFromEndpointUri(String routeId, List<String> agentIds) {
|
private String resolveFromEndpointUri(String applicationId, String routeId, String environment) {
|
||||||
return diagramStore.findContentHashForRouteByAgents(routeId, agentIds)
|
return diagramStore.findLatestContentHashForAppRoute(applicationId, routeId, environment)
|
||||||
.flatMap(diagramStore::findByContentHash)
|
.flatMap(diagramStore::findByContentHash)
|
||||||
.map(RouteGraph::getRoot)
|
.map(RouteGraph::getRoot)
|
||||||
.map(root -> root.getEndpointUri())
|
.map(root -> root.getEndpointUri())
|
||||||
|
|||||||
Reference in New Issue
Block a user