feat: merge persistent route catalog into unified catalog endpoint

Wires RouteCatalogStore into CatalogController as a third data source:
routes with zero executions and routes from previous app versions
(within the queried time window) now appear in the unified catalog.
Also clears route_catalog on app dismiss via deleteByApplication().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-16 18:49:00 +02:00
parent 462b9a4bf0
commit 24c858cca4

View File

@@ -11,6 +11,8 @@ import com.cameleer.server.core.agent.AgentState;
import com.cameleer.server.core.agent.RouteStateRegistry;
import com.cameleer.server.core.runtime.*;
import com.cameleer.server.core.storage.DiagramStore;
import com.cameleer.server.core.storage.RouteCatalogEntry;
import com.cameleer.server.core.storage.RouteCatalogStore;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -47,6 +49,7 @@ public class CatalogController {
private final EnvironmentService envService;
private final DeploymentRepository deploymentRepo;
private final TenantProperties tenantProperties;
private final RouteCatalogStore routeCatalogStore;
@Value("${cameleer.server.catalog.discoveryttldays:7}")
private int discoveryTtlDays;
@@ -58,7 +61,8 @@ public class CatalogController {
AppService appService,
EnvironmentService envService,
DeploymentRepository deploymentRepo,
TenantProperties tenantProperties) {
TenantProperties tenantProperties,
RouteCatalogStore routeCatalogStore) {
this.registryService = registryService;
this.diagramStore = diagramStore;
this.jdbc = jdbc;
@@ -67,6 +71,7 @@ public class CatalogController {
this.envService = envService;
this.deploymentRepo = deploymentRepo;
this.tenantProperties = tenantProperties;
this.routeCatalogStore = routeCatalogStore;
}
@GetMapping
@@ -154,6 +159,20 @@ public class CatalogController {
}
}
// Merge routes from persistent catalog (covers routes with 0 executions
// and routes from previous app versions within the selected time window)
try {
List<RouteCatalogEntry> catalogEntries = (environment != null && !environment.isBlank())
? routeCatalogStore.findByEnvironment(environment, rangeFrom, rangeTo)
: routeCatalogStore.findAll(rangeFrom, rangeTo);
for (RouteCatalogEntry entry : catalogEntries) {
routesByApp.computeIfAbsent(entry.applicationId(), k -> new LinkedHashSet<>())
.add(entry.routeId());
}
} catch (Exception e) {
log.warn("Failed to query route catalog: {}", e.getMessage());
}
// 7. Build unified catalog
Set<String> allSlugs = new LinkedHashSet<>(appsBySlug.keySet());
allSlugs.addAll(agentsByApp.keySet());
@@ -331,6 +350,7 @@ public class CatalogController {
// Delete ClickHouse data
deleteClickHouseData(tenantId, applicationId);
routeCatalogStore.deleteByApplication(applicationId);
// Delete managed app if exists (PostgreSQL)
try {
@@ -348,7 +368,7 @@ public class CatalogController {
String[] tablesWithAppId = {
"executions", "processor_executions", "route_diagrams", "agent_events",
"stats_1m_app", "stats_1m_route", "stats_1m_processor_type", "stats_1m_processor",
"stats_1m_processor_detail"
"stats_1m_processor_detail", "route_catalog"
};
for (String table : tablesWithAppId) {
try {