From 462b9a4bf08cf660c89322bff1c4c2e241bc16a9 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:47:22 +0200 Subject: [PATCH] feat: persist route catalog on agent register and heartbeat Wire RouteCatalogStore into AgentRegistrationController and call upsert after registration and heartbeat so routes survive server restarts. Co-Authored-By: Claude Sonnet 4.6 --- .../AgentRegistrationController.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java b/cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java index 185d45f2..aed8bea3 100644 --- a/cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java +++ b/cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java @@ -19,6 +19,7 @@ import com.cameleer.server.core.agent.AgentRegistryService; import com.cameleer.server.core.agent.AgentState; import com.cameleer.server.core.agent.RouteStateRegistry; import com.cameleer.server.core.security.Ed25519SigningService; +import com.cameleer.server.core.storage.RouteCatalogStore; import com.cameleer.server.core.security.InvalidTokenException; import com.cameleer.server.core.security.JwtService; import io.swagger.v3.oas.annotations.Operation; @@ -68,6 +69,7 @@ public class AgentRegistrationController { private final AuditService auditService; private final JdbcTemplate jdbc; private final RouteStateRegistry routeStateRegistry; + private final RouteCatalogStore routeCatalogStore; public AgentRegistrationController(AgentRegistryService registryService, AgentRegistryConfig config, @@ -77,7 +79,8 @@ public class AgentRegistrationController { AgentEventService agentEventService, AuditService auditService, @org.springframework.beans.factory.annotation.Qualifier("clickHouseJdbcTemplate") JdbcTemplate jdbc, - RouteStateRegistry routeStateRegistry) { + RouteStateRegistry routeStateRegistry, + RouteCatalogStore routeCatalogStore) { this.registryService = registryService; this.config = config; this.bootstrapTokenValidator = bootstrapTokenValidator; @@ -87,6 +90,7 @@ public class AgentRegistrationController { this.auditService = auditService; this.jdbc = jdbc; this.routeStateRegistry = routeStateRegistry; + this.routeCatalogStore = routeCatalogStore; } @PostMapping("/register") @@ -125,6 +129,11 @@ public class AgentRegistrationController { request.instanceId(), request.instanceId(), application, environmentId, request.version(), routeIds, capabilities); + // Persist routes in catalog for server-restart recovery + if (!routeIds.isEmpty()) { + routeCatalogStore.upsert(application, environmentId, routeIds); + } + if (reRegistration) { log.info("Agent re-registered: {} (application={}, routes={}, capabilities={})", request.instanceId(), application, routeIds.size(), capabilities.keySet()); @@ -260,6 +269,15 @@ public class AgentRegistrationController { } } + // Persist routes in catalog for server-restart recovery + if (routeIds != null && !routeIds.isEmpty()) { + AgentInfo agentForCatalog = registryService.findById(id); + if (agentForCatalog != null) { + String catalogEnv = agentForCatalog.environmentId(); + routeCatalogStore.upsert(agentForCatalog.applicationId(), catalogEnv, routeIds); + } + } + return ResponseEntity.ok().build(); }