Migrate config to cameleer.server.* naming convention
Move all configuration properties under the cameleer.server.* namespace with all-lowercase dot-separated names and mechanical env var mapping (dots→underscores, uppercase). This aligns with the agent's convention (cameleer.agent.*) and establishes a predictable pattern across all components. Changes: - Move 6 config prefixes under cameleer.server.*: agent-registry, ingestion, security, license, clickhouse, and cameleer.tenant/runtime/indexer - Rename all kebab-case properties to concatenated lowercase (e.g., bootstrap-token → bootstraptoken, jar-storage-path → jarstoragepath) - Update all env vars to CAMELEER_SERVER_* mechanical mapping - Fix container-cpu-request/container-cpu-shares mismatch bug - Remove displayName from AgentRegistrationRequest (redundant with instanceId) - Update agent container env vars to CAMELEER_AGENT_* convention - Update K8s manifests and CI workflow for new env var names - Update CLAUDE.md, HOWTO.md, SERVER-CAPABILITIES.md documentation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,11 +4,11 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for the agent registry.
|
||||
* Bound from the {@code agent-registry.*} namespace in application.yml.
|
||||
* Bound from the {@code cameleer.server.agentregistry.*} namespace in application.yml.
|
||||
* <p>
|
||||
* Registered via {@code @EnableConfigurationProperties} on the application class.
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "agent-registry")
|
||||
@ConfigurationProperties(prefix = "cameleer.server.agentregistry")
|
||||
public class AgentRegistryConfig {
|
||||
|
||||
private long heartbeatIntervalMs = 30_000;
|
||||
|
||||
@@ -14,7 +14,7 @@ import javax.sql.DataSource;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(ClickHouseProperties.class)
|
||||
@ConditionalOnProperty(name = "clickhouse.enabled", havingValue = "true")
|
||||
@ConditionalOnProperty(name = "cameleer.server.clickhouse.enabled", havingValue = "true")
|
||||
public class ClickHouseConfig {
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.cameleer3.server.app.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "clickhouse")
|
||||
@ConfigurationProperties(prefix = "cameleer.server.clickhouse")
|
||||
public class ClickHouseProperties {
|
||||
|
||||
private String url = "jdbc:clickhouse://localhost:8123/cameleer";
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.springframework.stereotype.Component;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Component
|
||||
@ConditionalOnProperty(name = "clickhouse.enabled", havingValue = "true")
|
||||
@ConditionalOnProperty(name = "cameleer.server.clickhouse.enabled", havingValue = "true")
|
||||
public class ClickHouseSchemaInitializer {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ClickHouseSchemaInitializer.class);
|
||||
|
||||
@@ -25,19 +25,19 @@ public class IngestionBeanConfig {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "clickhouse.enabled", havingValue = "true")
|
||||
@ConditionalOnProperty(name = "cameleer.server.clickhouse.enabled", havingValue = "true")
|
||||
public WriteBuffer<MergedExecution> executionBuffer(IngestionConfig config) {
|
||||
return new WriteBuffer<>(config.getBufferCapacity());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "clickhouse.enabled", havingValue = "true")
|
||||
@ConditionalOnProperty(name = "cameleer.server.clickhouse.enabled", havingValue = "true")
|
||||
public WriteBuffer<ChunkAccumulator.ProcessorBatch> processorBatchBuffer(IngestionConfig config) {
|
||||
return new WriteBuffer<>(config.getBufferCapacity());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "clickhouse.enabled", havingValue = "true")
|
||||
@ConditionalOnProperty(name = "cameleer.server.clickhouse.enabled", havingValue = "true")
|
||||
public WriteBuffer<BufferedLogEntry> logBuffer(IngestionConfig config) {
|
||||
return new WriteBuffer<>(config.getBufferCapacity());
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for the ingestion write buffer.
|
||||
* Bound from the {@code ingestion.*} namespace in application.yml.
|
||||
* Bound from the {@code cameleer.server.ingestion.*} namespace in application.yml.
|
||||
* <p>
|
||||
* Registered via {@code @EnableConfigurationProperties} on the application class.
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "ingestion")
|
||||
@ConfigurationProperties(prefix = "cameleer.server.ingestion")
|
||||
public class IngestionConfig {
|
||||
|
||||
private int bufferCapacity = 50_000;
|
||||
|
||||
@@ -17,13 +17,13 @@ public class LicenseBeanConfig {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(LicenseBeanConfig.class);
|
||||
|
||||
@Value("${license.token:}")
|
||||
@Value("${cameleer.server.license.token:}")
|
||||
private String licenseToken;
|
||||
|
||||
@Value("${license.file:}")
|
||||
@Value("${cameleer.server.license.file:}")
|
||||
private String licenseFile;
|
||||
|
||||
@Value("${license.public-key:}")
|
||||
@Value("${cameleer.server.license.publickey:}")
|
||||
private String licensePublicKey;
|
||||
|
||||
@Bean
|
||||
@@ -37,7 +37,7 @@ public class LicenseBeanConfig {
|
||||
}
|
||||
|
||||
if (licensePublicKey == null || licensePublicKey.isBlank()) {
|
||||
log.warn("License token provided but no public key configured (CAMELEER_LICENSE_PUBLIC_KEY). Running in open mode.");
|
||||
log.warn("License token provided but no public key configured (CAMELEER_SERVER_LICENSE_PUBLICKEY). Running in open mode.");
|
||||
return gate;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public class RuntimeBeanConfig {
|
||||
|
||||
@Bean
|
||||
public AppService appService(AppRepository appRepo, AppVersionRepository versionRepo,
|
||||
@Value("${cameleer.runtime.jar-storage-path:/data/jars}") String jarStoragePath) {
|
||||
@Value("${cameleer.server.runtime.jarstoragepath:/data/jars}") String jarStoragePath) {
|
||||
return new AppService(appRepo, versionRepo, jarStoragePath);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,8 +43,8 @@ public class StorageBeanConfig {
|
||||
|
||||
@Bean(destroyMethod = "shutdown")
|
||||
public SearchIndexer searchIndexer(ExecutionStore executionStore, SearchIndex searchIndex,
|
||||
@Value("${cameleer.indexer.debounce-ms:2000}") long debounceMs,
|
||||
@Value("${cameleer.indexer.queue-size:10000}") int queueSize) {
|
||||
@Value("${cameleer.server.indexer.debouncems:2000}") long debounceMs,
|
||||
@Value("${cameleer.server.indexer.queuesize:10000}") int queueSize) {
|
||||
return new SearchIndexer(executionStore, searchIndex, debounceMs, queueSize);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class StorageBeanConfig {
|
||||
DiagramStore diagramStore,
|
||||
WriteBuffer<MetricsSnapshot> metricsBuffer,
|
||||
SearchIndexer searchIndexer,
|
||||
@Value("${cameleer.body-size-limit:16384}") int bodySizeLimit) {
|
||||
@Value("${cameleer.server.ingestion.bodysizelimit:16384}") int bodySizeLimit) {
|
||||
return new IngestionService(executionStore, diagramStore, metricsBuffer,
|
||||
searchIndexer::onExecutionUpdated, bodySizeLimit);
|
||||
}
|
||||
@@ -165,7 +165,7 @@ public class StorageBeanConfig {
|
||||
// ── Usage Analytics ──────────────────────────────────────────────
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "clickhouse.enabled", havingValue = "true")
|
||||
@ConditionalOnProperty(name = "cameleer.server.clickhouse.enabled", havingValue = "true")
|
||||
public ClickHouseUsageTracker clickHouseUsageTracker(
|
||||
TenantProperties tenantProperties,
|
||||
@Qualifier("clickHouseJdbcTemplate") JdbcTemplate clickHouseJdbc) {
|
||||
@@ -174,14 +174,14 @@ public class StorageBeanConfig {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "clickhouse.enabled", havingValue = "true")
|
||||
@ConditionalOnProperty(name = "cameleer.server.clickhouse.enabled", havingValue = "true")
|
||||
public com.cameleer3.server.app.analytics.UsageTrackingInterceptor usageTrackingInterceptor(
|
||||
ClickHouseUsageTracker usageTracker) {
|
||||
return new com.cameleer3.server.app.analytics.UsageTrackingInterceptor(usageTracker);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "clickhouse.enabled", havingValue = "true")
|
||||
@ConditionalOnProperty(name = "cameleer.server.clickhouse.enabled", havingValue = "true")
|
||||
public com.cameleer3.server.app.analytics.UsageFlushScheduler usageFlushScheduler(
|
||||
ClickHouseUsageTracker usageTracker) {
|
||||
return new com.cameleer3.server.app.analytics.UsageFlushScheduler(usageTracker);
|
||||
|
||||
@@ -4,7 +4,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "cameleer.tenant")
|
||||
@ConfigurationProperties(prefix = "cameleer.server.tenant")
|
||||
public class TenantProperties {
|
||||
|
||||
private String id = "default";
|
||||
|
||||
@@ -110,8 +110,7 @@ public class AgentRegistrationController {
|
||||
return ResponseEntity.status(401).build();
|
||||
}
|
||||
|
||||
if (request.instanceId() == null || request.instanceId().isBlank()
|
||||
|| request.displayName() == null || request.displayName().isBlank()) {
|
||||
if (request.instanceId() == null || request.instanceId().isBlank()) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
|
||||
@@ -121,15 +120,15 @@ public class AgentRegistrationController {
|
||||
var capabilities = request.capabilities() != null ? request.capabilities() : Collections.<String, Object>emptyMap();
|
||||
|
||||
AgentInfo agent = registryService.register(
|
||||
request.instanceId(), request.displayName(), application, environmentId,
|
||||
request.instanceId(), request.instanceId(), application, environmentId,
|
||||
request.version(), routeIds, capabilities);
|
||||
log.info("Agent registered: {} (name={}, application={})", request.instanceId(), request.displayName(), application);
|
||||
log.info("Agent registered: {} (application={})", request.instanceId(), application);
|
||||
|
||||
agentEventService.recordEvent(request.instanceId(), application, "REGISTERED",
|
||||
"Agent registered: " + request.displayName());
|
||||
"Agent registered: " + request.instanceId());
|
||||
|
||||
auditService.log(request.instanceId(), "agent_register", AuditCategory.AGENT, request.instanceId(),
|
||||
Map.of("application", application, "name", request.displayName()),
|
||||
Map.of("application", application),
|
||||
AuditResult.SUCCESS, httpRequest);
|
||||
|
||||
// Issue JWT tokens with AGENT role + environment
|
||||
|
||||
@@ -31,7 +31,7 @@ public class ClickHouseAdminController {
|
||||
public ClickHouseAdminController(
|
||||
@Qualifier("clickHouseJdbcTemplate") JdbcTemplate clickHouseJdbc,
|
||||
SearchIndexerStats indexerStats,
|
||||
@Value("${clickhouse.url:}") String clickHouseUrl) {
|
||||
@Value("${cameleer.server.clickhouse.url:}") String clickHouseUrl) {
|
||||
this.clickHouseJdbc = clickHouseJdbc;
|
||||
this.indexerStats = indexerStats;
|
||||
this.clickHouseUrl = clickHouseUrl;
|
||||
|
||||
@@ -22,7 +22,7 @@ public class LicenseAdminController {
|
||||
private final String licensePublicKey;
|
||||
|
||||
public LicenseAdminController(LicenseGate licenseGate,
|
||||
@Value("${license.public-key:}") String licensePublicKey) {
|
||||
@Value("${cameleer.server.license.publickey:}") String licensePublicKey) {
|
||||
this.licenseGate = licenseGate;
|
||||
this.licensePublicKey = licensePublicKey;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import java.util.Map;
|
||||
@Schema(description = "Agent registration payload")
|
||||
public record AgentRegistrationRequest(
|
||||
@NotNull String instanceId,
|
||||
@NotNull String displayName,
|
||||
@Schema(defaultValue = "default") String applicationId,
|
||||
@Schema(defaultValue = "default") String environmentId,
|
||||
String version,
|
||||
|
||||
@@ -28,43 +28,43 @@ public class DeploymentExecutor {
|
||||
@Autowired(required = false)
|
||||
private DockerNetworkManager networkManager;
|
||||
|
||||
@Value("${cameleer.runtime.base-image:cameleer-runtime-base:latest}")
|
||||
@Value("${cameleer.server.runtime.baseimage:cameleer-runtime-base:latest}")
|
||||
private String baseImage;
|
||||
|
||||
@Value("${cameleer.runtime.docker-network:cameleer}")
|
||||
@Value("${cameleer.server.runtime.dockernetwork:cameleer}")
|
||||
private String dockerNetwork;
|
||||
|
||||
@Value("${cameleer.runtime.container-memory-limit:512m}")
|
||||
@Value("${cameleer.server.runtime.containermemorylimit:512m}")
|
||||
private String globalMemoryLimit;
|
||||
|
||||
@Value("${cameleer.runtime.container-cpu-request:500}")
|
||||
private int globalCpuRequest;
|
||||
@Value("${cameleer.server.runtime.containercpushares:512}")
|
||||
private int globalCpuShares;
|
||||
|
||||
@Value("${cameleer.runtime.health-check-timeout:60}")
|
||||
@Value("${cameleer.server.runtime.healthchecktimeout:60}")
|
||||
private int healthCheckTimeout;
|
||||
|
||||
@Value("${cameleer.runtime.agent-health-port:9464}")
|
||||
@Value("${cameleer.server.runtime.agenthealthport:9464}")
|
||||
private int agentHealthPort;
|
||||
|
||||
@Value("${security.bootstrap-token:}")
|
||||
@Value("${cameleer.server.security.bootstraptoken:}")
|
||||
private String bootstrapToken;
|
||||
|
||||
@Value("${cameleer.runtime.routing-mode:path}")
|
||||
@Value("${cameleer.server.runtime.routingmode:path}")
|
||||
private String globalRoutingMode;
|
||||
|
||||
@Value("${cameleer.runtime.routing-domain:localhost}")
|
||||
@Value("${cameleer.server.runtime.routingdomain:localhost}")
|
||||
private String globalRoutingDomain;
|
||||
|
||||
@Value("${cameleer.runtime.server-url:}")
|
||||
@Value("${cameleer.server.runtime.serverurl:}")
|
||||
private String globalServerUrl;
|
||||
|
||||
@Value("${cameleer.runtime.jar-docker-volume:}")
|
||||
@Value("${cameleer.server.runtime.jardockervolume:}")
|
||||
private String jarDockerVolume;
|
||||
|
||||
@Value("${cameleer.runtime.jar-storage-path:/data/jars}")
|
||||
@Value("${cameleer.server.runtime.jarstoragepath:/data/jars}")
|
||||
private String jarStoragePath;
|
||||
|
||||
@Value("${cameleer.tenant.id:default}")
|
||||
@Value("${cameleer.server.tenant.id:default}")
|
||||
private String tenantId;
|
||||
|
||||
public DeploymentExecutor(RuntimeOrchestrator orchestrator,
|
||||
@@ -89,7 +89,7 @@ public class DeploymentExecutor {
|
||||
|
||||
var globalDefaults = new ConfigMerger.GlobalRuntimeDefaults(
|
||||
parseMemoryLimitMb(globalMemoryLimit),
|
||||
globalCpuRequest,
|
||||
globalCpuShares,
|
||||
globalRoutingMode,
|
||||
globalRoutingDomain,
|
||||
globalServerUrl.isBlank() ? "http://cameleer3-server:8081" : globalServerUrl
|
||||
@@ -271,14 +271,14 @@ public class DeploymentExecutor {
|
||||
|
||||
private Map<String, String> buildEnvVars(App app, Environment env, ResolvedContainerConfig config) {
|
||||
Map<String, String> envVars = new LinkedHashMap<>();
|
||||
envVars.put("CAMELEER_EXPORT_TYPE", "HTTP");
|
||||
envVars.put("CAMELEER_APPLICATION_ID", app.slug());
|
||||
envVars.put("CAMELEER_ENVIRONMENT_ID", env.slug());
|
||||
envVars.put("CAMELEER_SERVER_URL", config.serverUrl());
|
||||
envVars.put("CAMELEER_ROUTE_CONTROL_ENABLED", String.valueOf(config.routeControlEnabled()));
|
||||
envVars.put("CAMELEER_REPLAY_ENABLED", String.valueOf(config.replayEnabled()));
|
||||
envVars.put("CAMELEER_AGENT_EXPORT_TYPE", "HTTP");
|
||||
envVars.put("CAMELEER_AGENT_APPLICATION", app.slug());
|
||||
envVars.put("CAMELEER_AGENT_ENVIRONMENT", env.slug());
|
||||
envVars.put("CAMELEER_AGENT_EXPORT_ENDPOINT", config.serverUrl());
|
||||
envVars.put("CAMELEER_AGENT_ROUTECONTROL_ENABLED", String.valueOf(config.routeControlEnabled()));
|
||||
envVars.put("CAMELEER_AGENT_REPLAY_ENABLED", String.valueOf(config.replayEnabled()));
|
||||
if (bootstrapToken != null && !bootstrapToken.isBlank()) {
|
||||
envVars.put("CAMELEER_AUTH_TOKEN", bootstrapToken);
|
||||
envVars.put("CAMELEER_AGENT_AUTH_TOKEN", bootstrapToken);
|
||||
}
|
||||
envVars.putAll(config.customEnvVars());
|
||||
return envVars;
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
* Configuration class that creates security service beans and validates
|
||||
* that required security properties are set.
|
||||
* <p>
|
||||
* Fails fast on startup if {@code CAMELEER_AUTH_TOKEN} is not set.
|
||||
* Fails fast on startup if {@code CAMELEER_SERVER_SECURITY_BOOTSTRAPTOKEN} is not set.
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(SecurityProperties.class)
|
||||
@@ -40,7 +40,7 @@ public class SecurityBeanConfig {
|
||||
String token = properties.getBootstrapToken();
|
||||
if (token == null || token.isBlank()) {
|
||||
throw new IllegalStateException(
|
||||
"CAMELEER_AUTH_TOKEN environment variable must be set");
|
||||
"CAMELEER_SERVER_SECURITY_BOOTSTRAPTOKEN environment variable must be set");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for security settings.
|
||||
* Bound from the {@code security.*} namespace in application.yml.
|
||||
* Bound from the {@code cameleer.server.security.*} namespace in application.yml.
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "security")
|
||||
@ConfigurationProperties(prefix = "cameleer.server.security")
|
||||
public class SecurityProperties {
|
||||
|
||||
private long accessTokenExpiryMs = 3_600_000;
|
||||
|
||||
@@ -7,7 +7,7 @@ spring:
|
||||
max-file-size: 200MB
|
||||
max-request-size: 200MB
|
||||
datasource:
|
||||
url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/cameleer3?currentSchema=tenant_${cameleer.tenant.id}}
|
||||
url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/cameleer3?currentSchema=tenant_${cameleer.server.tenant.id}}
|
||||
username: ${SPRING_DATASOURCE_USERNAME:cameleer}
|
||||
password: ${SPRING_DATASOURCE_PASSWORD:cameleer_dev}
|
||||
driver-class-name: org.postgresql.Driver
|
||||
@@ -24,60 +24,61 @@ spring:
|
||||
deserialization:
|
||||
fail-on-unknown-properties: false
|
||||
|
||||
agent-registry:
|
||||
heartbeat-interval-ms: 30000
|
||||
stale-threshold-ms: 90000
|
||||
dead-threshold-ms: 300000
|
||||
ping-interval-ms: 15000
|
||||
command-expiry-ms: 60000
|
||||
lifecycle-check-interval-ms: 10000
|
||||
|
||||
ingestion:
|
||||
buffer-capacity: 50000
|
||||
batch-size: 5000
|
||||
flush-interval-ms: 5000
|
||||
|
||||
cameleer:
|
||||
tenant:
|
||||
id: ${CAMELEER_TENANT_ID:default}
|
||||
runtime:
|
||||
enabled: ${CAMELEER_RUNTIME_ENABLED:true}
|
||||
jar-storage-path: ${CAMELEER_JAR_STORAGE_PATH:/data/jars}
|
||||
base-image: ${CAMELEER_RUNTIME_BASE_IMAGE:cameleer-runtime-base:latest}
|
||||
docker-network: ${CAMELEER_DOCKER_NETWORK:cameleer}
|
||||
agent-health-port: 9464
|
||||
health-check-timeout: 60
|
||||
container-memory-limit: ${CAMELEER_CONTAINER_MEMORY_LIMIT:512m}
|
||||
container-cpu-shares: ${CAMELEER_CONTAINER_CPU_SHARES:512}
|
||||
routing-mode: ${CAMELEER_ROUTING_MODE:path}
|
||||
routing-domain: ${CAMELEER_ROUTING_DOMAIN:localhost}
|
||||
server-url: ${CAMELEER_SERVER_URL:}
|
||||
jar-docker-volume: ${CAMELEER_JAR_DOCKER_VOLUME:}
|
||||
body-size-limit: ${CAMELEER_BODY_SIZE_LIMIT:16384}
|
||||
indexer:
|
||||
debounce-ms: ${CAMELEER_INDEXER_DEBOUNCE_MS:2000}
|
||||
queue-size: ${CAMELEER_INDEXER_QUEUE_SIZE:10000}
|
||||
|
||||
license:
|
||||
token: ${CAMELEER_LICENSE_TOKEN:}
|
||||
file: ${CAMELEER_LICENSE_FILE:}
|
||||
public-key: ${CAMELEER_LICENSE_PUBLIC_KEY:}
|
||||
|
||||
security:
|
||||
access-token-expiry-ms: 3600000
|
||||
refresh-token-expiry-ms: 604800000
|
||||
bootstrap-token: ${CAMELEER_AUTH_TOKEN:}
|
||||
bootstrap-token-previous: ${CAMELEER_AUTH_TOKEN_PREVIOUS:}
|
||||
ui-user: ${CAMELEER_UI_USER:admin}
|
||||
ui-password: ${CAMELEER_UI_PASSWORD:admin}
|
||||
ui-origin: ${CAMELEER_UI_ORIGIN:http://localhost:5173}
|
||||
jwt-secret: ${CAMELEER_JWT_SECRET:}
|
||||
oidc-issuer-uri: ${CAMELEER_OIDC_ISSUER_URI:}
|
||||
oidc-jwk-set-uri: ${CAMELEER_OIDC_JWK_SET_URI:}
|
||||
oidc-audience: ${CAMELEER_OIDC_AUDIENCE:}
|
||||
oidc-tls-skip-verify: ${CAMELEER_OIDC_TLS_SKIP_VERIFY:false}
|
||||
cors-allowed-origins: ${CAMELEER_CORS_ALLOWED_ORIGINS:}
|
||||
|
||||
server:
|
||||
tenant:
|
||||
id: ${CAMELEER_SERVER_TENANT_ID:default}
|
||||
agentregistry:
|
||||
heartbeatintervalms: 30000
|
||||
stalethresholdms: 90000
|
||||
deadthresholdms: 300000
|
||||
pingintervalms: 15000
|
||||
commandexpiryms: 60000
|
||||
lifecyclecheckintervalms: 10000
|
||||
ingestion:
|
||||
buffercapacity: 50000
|
||||
batchsize: 5000
|
||||
flushintervalms: 5000
|
||||
bodysizelimit: ${CAMELEER_SERVER_INGESTION_BODYSIZELIMIT:16384}
|
||||
runtime:
|
||||
enabled: ${CAMELEER_SERVER_RUNTIME_ENABLED:true}
|
||||
jarstoragepath: ${CAMELEER_SERVER_RUNTIME_JARSTORAGEPATH:/data/jars}
|
||||
baseimage: ${CAMELEER_SERVER_RUNTIME_BASEIMAGE:cameleer-runtime-base:latest}
|
||||
dockernetwork: ${CAMELEER_SERVER_RUNTIME_DOCKERNETWORK:cameleer}
|
||||
agenthealthport: 9464
|
||||
healthchecktimeout: 60
|
||||
containermemorylimit: ${CAMELEER_SERVER_RUNTIME_CONTAINERMEMORYLIMIT:512m}
|
||||
containercpushares: ${CAMELEER_SERVER_RUNTIME_CONTAINERCPUSHARES:512}
|
||||
routingmode: ${CAMELEER_SERVER_RUNTIME_ROUTINGMODE:path}
|
||||
routingdomain: ${CAMELEER_SERVER_RUNTIME_ROUTINGDOMAIN:localhost}
|
||||
serverurl: ${CAMELEER_SERVER_RUNTIME_SERVERURL:}
|
||||
jardockervolume: ${CAMELEER_SERVER_RUNTIME_JARDOCKERVOLUME:}
|
||||
indexer:
|
||||
debouncems: ${CAMELEER_SERVER_INDEXER_DEBOUNCEMS:2000}
|
||||
queuesize: ${CAMELEER_SERVER_INDEXER_QUEUESIZE:10000}
|
||||
license:
|
||||
token: ${CAMELEER_SERVER_LICENSE_TOKEN:}
|
||||
file: ${CAMELEER_SERVER_LICENSE_FILE:}
|
||||
publickey: ${CAMELEER_SERVER_LICENSE_PUBLICKEY:}
|
||||
security:
|
||||
accesstokenexpiryms: 3600000
|
||||
refreshtokenexpiryms: 604800000
|
||||
bootstraptoken: ${CAMELEER_SERVER_SECURITY_BOOTSTRAPTOKEN:}
|
||||
bootstraptokenprevious: ${CAMELEER_SERVER_SECURITY_BOOTSTRAPTOKENPREVIOUS:}
|
||||
uiuser: ${CAMELEER_SERVER_SECURITY_UIUSER:admin}
|
||||
uipassword: ${CAMELEER_SERVER_SECURITY_UIPASSWORD:admin}
|
||||
uiorigin: ${CAMELEER_SERVER_SECURITY_UIORIGIN:http://localhost:5173}
|
||||
jwtsecret: ${CAMELEER_SERVER_SECURITY_JWTSECRET:}
|
||||
oidcissueruri: ${CAMELEER_SERVER_SECURITY_OIDCISSUERURI:}
|
||||
oidcjwkseturi: ${CAMELEER_SERVER_SECURITY_OIDCJWKSETURI:}
|
||||
oidcaudience: ${CAMELEER_SERVER_SECURITY_OIDCAUDIENCE:}
|
||||
oidctlsskipverify: ${CAMELEER_SERVER_SECURITY_OIDCTLSSKIPVERIFY:false}
|
||||
corsallowedorigins: ${CAMELEER_SERVER_SECURITY_CORSALLOWEDORIGINS:}
|
||||
clickhouse:
|
||||
enabled: ${CAMELEER_SERVER_CLICKHOUSE_ENABLED:true}
|
||||
url: ${CAMELEER_SERVER_CLICKHOUSE_URL:jdbc:clickhouse://localhost:8123/cameleer}
|
||||
username: ${CAMELEER_SERVER_CLICKHOUSE_USERNAME:default}
|
||||
password: ${CAMELEER_SERVER_CLICKHOUSE_PASSWORD:}
|
||||
|
||||
springdoc:
|
||||
api-docs:
|
||||
@@ -85,12 +86,6 @@ springdoc:
|
||||
swagger-ui:
|
||||
path: /api/v1/swagger-ui
|
||||
|
||||
clickhouse:
|
||||
enabled: ${CLICKHOUSE_ENABLED:true}
|
||||
url: ${CLICKHOUSE_URL:jdbc:clickhouse://localhost:8123/cameleer}
|
||||
username: ${CLICKHOUSE_USERNAME:default}
|
||||
password: ${CLICKHOUSE_PASSWORD:}
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.clickhouse: INFO
|
||||
|
||||
@@ -30,7 +30,7 @@ public class TestSecurityHelper {
|
||||
* Registers a test agent and returns a valid JWT access token with AGENT role.
|
||||
*/
|
||||
public String registerTestAgent(String instanceId) {
|
||||
agentRegistryService.register(instanceId, "test", "test-group", "default", "1.0", List.of(), Map.of());
|
||||
agentRegistryService.register(instanceId, instanceId, "test-group", "default", "1.0", List.of(), Map.of());
|
||||
return jwtService.createAccessToken(instanceId, "test-group", List.of("AGENT"));
|
||||
}
|
||||
|
||||
|
||||
@@ -41,13 +41,12 @@ class AgentCommandControllerIT extends AbstractPostgresIT {
|
||||
String json = """
|
||||
{
|
||||
"instanceId": "%s",
|
||||
"displayName": "%s",
|
||||
"applicationId": "%s",
|
||||
"version": "1.0.0",
|
||||
"routeIds": ["route-1"],
|
||||
"capabilities": {}
|
||||
}
|
||||
""".formatted(agentId, name, application);
|
||||
""".formatted(agentId, application);
|
||||
|
||||
return restTemplate.postForEntity(
|
||||
"/api/v1/agents/register",
|
||||
|
||||
@@ -39,13 +39,12 @@ class AgentRegistrationControllerIT extends AbstractPostgresIT {
|
||||
String json = """
|
||||
{
|
||||
"instanceId": "%s",
|
||||
"displayName": "%s",
|
||||
"applicationId": "test-group",
|
||||
"version": "1.0.0",
|
||||
"routeIds": ["route-1", "route-2"],
|
||||
"capabilities": {"tracing": true}
|
||||
}
|
||||
""".formatted(agentId, name);
|
||||
""".formatted(agentId);
|
||||
|
||||
return restTemplate.postForEntity(
|
||||
"/api/v1/agents/register",
|
||||
|
||||
@@ -56,13 +56,12 @@ class AgentSseControllerIT extends AbstractPostgresIT {
|
||||
String json = """
|
||||
{
|
||||
"instanceId": "%s",
|
||||
"displayName": "%s",
|
||||
"applicationId": "%s",
|
||||
"version": "1.0.0",
|
||||
"routeIds": ["route-1"],
|
||||
"capabilities": {}
|
||||
}
|
||||
""".formatted(agentId, name, application);
|
||||
""".formatted(agentId, application);
|
||||
|
||||
return restTemplate.postForEntity(
|
||||
"/api/v1/agents/register",
|
||||
|
||||
@@ -28,7 +28,6 @@ class BootstrapTokenIT extends AbstractPostgresIT {
|
||||
private static final String REGISTRATION_JSON = """
|
||||
{
|
||||
"instanceId": "bootstrap-test-agent",
|
||||
"displayName": "Bootstrap Test",
|
||||
"applicationId": "test-group",
|
||||
"version": "1.0.0",
|
||||
"routeIds": [],
|
||||
@@ -96,7 +95,6 @@ class BootstrapTokenIT extends AbstractPostgresIT {
|
||||
String json = """
|
||||
{
|
||||
"instanceId": "bootstrap-test-previous",
|
||||
"displayName": "Previous Token Test",
|
||||
"applicationId": "test-group",
|
||||
"version": "1.0.0",
|
||||
"routeIds": [],
|
||||
|
||||
@@ -38,7 +38,6 @@ class JwtRefreshIT extends AbstractPostgresIT {
|
||||
String json = """
|
||||
{
|
||||
"instanceId": "%s",
|
||||
"displayName": "Refresh Test Agent",
|
||||
"applicationId": "test-group",
|
||||
"version": "1.0.0",
|
||||
"routeIds": [],
|
||||
|
||||
@@ -31,7 +31,6 @@ class RegistrationSecurityIT extends AbstractPostgresIT {
|
||||
String json = """
|
||||
{
|
||||
"instanceId": "%s",
|
||||
"displayName": "Security Test Agent",
|
||||
"applicationId": "test-group",
|
||||
"version": "1.0.0",
|
||||
"routeIds": [],
|
||||
|
||||
@@ -89,7 +89,6 @@ class SseSigningIT extends AbstractPostgresIT {
|
||||
String json = """
|
||||
{
|
||||
"instanceId": "%s",
|
||||
"displayName": "SSE Signing Test Agent",
|
||||
"applicationId": "test-group",
|
||||
"version": "1.0.0",
|
||||
"routeIds": ["route-1"],
|
||||
|
||||
@@ -3,17 +3,15 @@ spring:
|
||||
enabled: true
|
||||
|
||||
cameleer:
|
||||
indexer:
|
||||
debounce-ms: 100
|
||||
|
||||
ingestion:
|
||||
buffer-capacity: 100
|
||||
batch-size: 10
|
||||
flush-interval-ms: 100
|
||||
|
||||
agent-registry:
|
||||
ping-interval-ms: 1000
|
||||
|
||||
security:
|
||||
bootstrap-token: test-bootstrap-token
|
||||
bootstrap-token-previous: old-bootstrap-token
|
||||
server:
|
||||
indexer:
|
||||
debouncems: 100
|
||||
ingestion:
|
||||
buffercapacity: 100
|
||||
batchsize: 10
|
||||
flushintervalms: 100
|
||||
agentregistry:
|
||||
pingintervalms: 1000
|
||||
security:
|
||||
bootstraptoken: test-bootstrap-token
|
||||
bootstraptokenprevious: old-bootstrap-token
|
||||
|
||||
Reference in New Issue
Block a user