feat(03-01): add agent registration controller, config, lifecycle monitor
- AgentRegistryConfig: heartbeat, stale, dead, ping, command expiry settings
- AgentRegistryBeanConfig: wires AgentRegistryService as Spring bean
- AgentLifecycleMonitor: @Scheduled lifecycle check + command expiry sweep
- AgentRegistrationController: POST /register, POST /{id}/heartbeat, GET /agents
- Updated Cameleer3ServerApplication with AgentRegistryConfig
- Updated application.yml with agent-registry section and async timeout
- 7 integration tests: register, re-register, heartbeat, list, filter, invalid status
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
package com.cameleer3.server.app.config;
|
||||
|
||||
import com.cameleer3.server.core.agent.AgentRegistryService;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Creates the {@link AgentRegistryService} bean.
|
||||
* <p>
|
||||
* Follows the established pattern: core module plain class, app module bean config.
|
||||
*/
|
||||
@Configuration
|
||||
public class AgentRegistryBeanConfig {
|
||||
|
||||
@Bean
|
||||
public AgentRegistryService agentRegistryService(AgentRegistryConfig config) {
|
||||
return new AgentRegistryService(
|
||||
config.getStaleThresholdMs(),
|
||||
config.getDeadThresholdMs(),
|
||||
config.getCommandExpiryMs()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.cameleer3.server.app.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for the agent registry.
|
||||
* Bound from the {@code agent-registry.*} namespace in application.yml.
|
||||
* <p>
|
||||
* Registered via {@code @EnableConfigurationProperties} on the application class.
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "agent-registry")
|
||||
public class AgentRegistryConfig {
|
||||
|
||||
private long heartbeatIntervalMs = 30_000;
|
||||
private long staleThresholdMs = 90_000;
|
||||
private long deadThresholdMs = 300_000;
|
||||
private long pingIntervalMs = 15_000;
|
||||
private long commandExpiryMs = 60_000;
|
||||
private long lifecycleCheckIntervalMs = 10_000;
|
||||
|
||||
public long getHeartbeatIntervalMs() {
|
||||
return heartbeatIntervalMs;
|
||||
}
|
||||
|
||||
public void setHeartbeatIntervalMs(long heartbeatIntervalMs) {
|
||||
this.heartbeatIntervalMs = heartbeatIntervalMs;
|
||||
}
|
||||
|
||||
public long getStaleThresholdMs() {
|
||||
return staleThresholdMs;
|
||||
}
|
||||
|
||||
public void setStaleThresholdMs(long staleThresholdMs) {
|
||||
this.staleThresholdMs = staleThresholdMs;
|
||||
}
|
||||
|
||||
public long getDeadThresholdMs() {
|
||||
return deadThresholdMs;
|
||||
}
|
||||
|
||||
public void setDeadThresholdMs(long deadThresholdMs) {
|
||||
this.deadThresholdMs = deadThresholdMs;
|
||||
}
|
||||
|
||||
public long getPingIntervalMs() {
|
||||
return pingIntervalMs;
|
||||
}
|
||||
|
||||
public void setPingIntervalMs(long pingIntervalMs) {
|
||||
this.pingIntervalMs = pingIntervalMs;
|
||||
}
|
||||
|
||||
public long getCommandExpiryMs() {
|
||||
return commandExpiryMs;
|
||||
}
|
||||
|
||||
public void setCommandExpiryMs(long commandExpiryMs) {
|
||||
this.commandExpiryMs = commandExpiryMs;
|
||||
}
|
||||
|
||||
public long getLifecycleCheckIntervalMs() {
|
||||
return lifecycleCheckIntervalMs;
|
||||
}
|
||||
|
||||
public void setLifecycleCheckIntervalMs(long lifecycleCheckIntervalMs) {
|
||||
this.lifecycleCheckIntervalMs = lifecycleCheckIntervalMs;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user