feat: distinguish agent re-registration from first registration
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m16s
CI / docker (push) Successful in 1m38s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Failing after 2m19s

Detect when an agent instance already exists in the registry and record
a RE_REGISTERED event with route count and capabilities instead of a
generic REGISTERED event. UI shows a refresh icon for re-registrations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-14 23:57:20 +02:00
parent 33b0bc4d98
commit 9c912fe694
2 changed files with 20 additions and 6 deletions

View File

@@ -119,16 +119,28 @@ public class AgentRegistrationController {
List<String> routeIds = request.routeIds() != null ? request.routeIds() : List.of();
var capabilities = request.capabilities() != null ? request.capabilities() : Collections.<String, Object>emptyMap();
boolean reRegistration = registryService.findById(request.instanceId()) != null;
AgentInfo agent = registryService.register(
request.instanceId(), request.instanceId(), application, environmentId,
request.version(), routeIds, capabilities);
log.info("Agent registered: {} (application={})", request.instanceId(), application);
agentEventService.recordEvent(request.instanceId(), application, "REGISTERED",
"Agent registered: " + request.instanceId());
if (reRegistration) {
log.info("Agent re-registered: {} (application={}, routes={}, capabilities={})",
request.instanceId(), application, routeIds.size(), capabilities.keySet());
agentEventService.recordEvent(request.instanceId(), application, "RE_REGISTERED",
"Agent re-registered with " + routeIds.size() + " routes");
} else {
log.info("Agent registered: {} (application={}, routes={})",
request.instanceId(), application, routeIds.size());
agentEventService.recordEvent(request.instanceId(), application, "REGISTERED",
"Agent registered: " + request.instanceId());
}
auditService.log(request.instanceId(), "agent_register", AuditCategory.AGENT, request.instanceId(),
Map.of("application", application),
auditService.log(request.instanceId(), reRegistration ? "agent_reregister" : "agent_register",
AuditCategory.AGENT, request.instanceId(),
Map.of("application", application, "routeCount", routeIds.size(),
"reRegistration", reRegistration),
AuditResult.SUCCESS, httpRequest);
// Issue JWT tokens with AGENT role + environment

View File

@@ -1,6 +1,6 @@
import type { FeedEvent } from '@cameleer/design-system';
import type { LogEntry } from '@cameleer/design-system';
import { UserPlus, UserMinus, Play, Square, Clock, Skull, HeartPulse, Route, Send, Activity } from 'lucide-react';
import { UserPlus, UserMinus, RefreshCw, Play, Square, Clock, Skull, HeartPulse, Route, Send, Activity } from 'lucide-react';
import { createElement } from 'react';
export function formatUptime(seconds?: number): string {
@@ -31,6 +31,7 @@ export function eventSeverity(type: string): FeedEvent['severity'] {
case 'WENT_STALE': return 'warning';
case 'RECOVERED':
case 'REGISTERED':
case 'RE_REGISTERED':
case 'AGENT_STARTED': return 'success';
default: return 'running';
}
@@ -39,6 +40,7 @@ export function eventSeverity(type: string): FeedEvent['severity'] {
export function eventIcon(type: string) {
switch (type) {
case 'REGISTERED': return createElement(UserPlus, { size: 14 });
case 'RE_REGISTERED': return createElement(RefreshCw, { size: 14 });
case 'DEREGISTERED': return createElement(UserMinus, { size: 14 });
case 'AGENT_STARTED': return createElement(Play, { size: 14 });
case 'AGENT_STOPPED': return createElement(Square, { size: 14 });