feat: use endpointUri for cross-route drill-down instead of label parsing
Server: - Add endpointUri to PositionedNode (from RouteNode) - Add fromEndpointUri to RouteSummary (catalog API) - Catalog controller resolves endpoint URI from diagram store UI: - Build endpointRouteMap from catalog's fromEndpointUri field - Drill-down uses exact match on node.endpointUri against the map - Remove label parsing heuristics (extractTargetEndpoint, camelToKebab) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,9 +3,11 @@ package com.cameleer3.server.app.controller;
|
||||
import com.cameleer3.server.app.dto.AgentSummary;
|
||||
import com.cameleer3.server.app.dto.AppCatalogEntry;
|
||||
import com.cameleer3.server.app.dto.RouteSummary;
|
||||
import com.cameleer3.common.graph.RouteGraph;
|
||||
import com.cameleer3.server.core.agent.AgentInfo;
|
||||
import com.cameleer3.server.core.agent.AgentRegistryService;
|
||||
import com.cameleer3.server.core.agent.AgentState;
|
||||
import com.cameleer3.server.core.storage.DiagramStore;
|
||||
import com.cameleer3.server.core.storage.StatsStore;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
@@ -34,10 +36,14 @@ import java.util.stream.Collectors;
|
||||
public class RouteCatalogController {
|
||||
|
||||
private final AgentRegistryService registryService;
|
||||
private final DiagramStore diagramStore;
|
||||
private final JdbcTemplate jdbc;
|
||||
|
||||
public RouteCatalogController(AgentRegistryService registryService, JdbcTemplate jdbc) {
|
||||
public RouteCatalogController(AgentRegistryService registryService,
|
||||
DiagramStore diagramStore,
|
||||
JdbcTemplate jdbc) {
|
||||
this.registryService = registryService;
|
||||
this.diagramStore = diagramStore;
|
||||
this.jdbc = jdbc;
|
||||
}
|
||||
|
||||
@@ -114,12 +120,14 @@ public class RouteCatalogController {
|
||||
|
||||
// Routes
|
||||
Set<String> routeIds = routesByApp.getOrDefault(appId, Set.of());
|
||||
List<String> agentIds = agents.stream().map(AgentInfo::id).toList();
|
||||
List<RouteSummary> routeSummaries = routeIds.stream()
|
||||
.map(routeId -> {
|
||||
String key = appId + "/" + routeId;
|
||||
long count = routeExchangeCounts.getOrDefault(key, 0L);
|
||||
Instant lastSeen = routeLastSeen.get(key);
|
||||
return new RouteSummary(routeId, count, lastSeen);
|
||||
String fromUri = resolveFromEndpointUri(routeId, agentIds);
|
||||
return new RouteSummary(routeId, count, lastSeen, fromUri);
|
||||
})
|
||||
.toList();
|
||||
|
||||
@@ -141,6 +149,15 @@ public class RouteCatalogController {
|
||||
return ResponseEntity.ok(catalog);
|
||||
}
|
||||
|
||||
/** Resolve the from() endpoint URI for a route by looking up its diagram. */
|
||||
private String resolveFromEndpointUri(String routeId, List<String> agentIds) {
|
||||
return diagramStore.findContentHashForRouteByAgents(routeId, agentIds)
|
||||
.flatMap(diagramStore::findByContentHash)
|
||||
.map(RouteGraph::getRoot)
|
||||
.map(root -> root.getEndpointUri())
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private String computeWorstHealth(List<AgentInfo> agents) {
|
||||
boolean hasDead = false;
|
||||
boolean hasStale = false;
|
||||
|
||||
@@ -666,7 +666,7 @@ public class ElkDiagramRenderer implements DiagramRenderer {
|
||||
getAbsoluteX(wrapperElk, rootNode),
|
||||
getAbsoluteY(wrapperElk, rootNode),
|
||||
wrapperElk.getWidth(), wrapperElk.getHeight(),
|
||||
wrapperChildren));
|
||||
wrapperChildren, null));
|
||||
ctx.compoundInfos.put(wrapperId, new CompoundInfo(wrapperId, Color.WHITE));
|
||||
}
|
||||
// Handler children in order: DO_FINALLY first, then DO_CATCH
|
||||
@@ -693,7 +693,8 @@ public class ElkDiagramRenderer implements DiagramRenderer {
|
||||
rn.getType() != null ? rn.getType().name() : "UNKNOWN",
|
||||
absX, absY,
|
||||
elkNode.getWidth(), elkNode.getHeight(),
|
||||
children
|
||||
children,
|
||||
rn.getEndpointUri()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,5 +9,7 @@ import java.time.Instant;
|
||||
public record RouteSummary(
|
||||
@NotNull String routeId,
|
||||
@NotNull long exchangeCount,
|
||||
Instant lastSeen
|
||||
Instant lastSeen,
|
||||
@Schema(description = "The from() endpoint URI, e.g. 'direct:processOrder'")
|
||||
String fromEndpointUri
|
||||
) {}
|
||||
|
||||
Reference in New Issue
Block a user