All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m27s
CI / docker (push) Successful in 1m10s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 1m40s
SonarQube / sonarqube (push) Successful in 4m29s
BREAKING: wipe dev PostgreSQL before deploying — V1 checksum changes. Agents must now send environmentId on registration (400 if missing). Two tables previously keyed on app name alone caused cross-environment data bleed: writing config for (app=X, env=dev) would overwrite the row used by (app=X, env=prod) agents, and agent startup fetches ignored env entirely. - V1 schema: application_config and app_settings are now PK (app, env). - Repositories: env-keyed finders/saves; env is the authoritative column, stamped on the stored JSON so the row agrees with itself. - ApplicationConfigController.getConfig is dual-mode — AGENT role uses JWT env claim (agents cannot spoof env); non-agent callers provide env via ?environment= query param. - AppSettingsController endpoints now require ?environment=. - SensitiveKeysAdminController fan-out iterates (app, env) slices so each env gets its own merged keys. - DiagramController ingestion stamps env on TaggedDiagram; ClickHouse route_diagrams INSERT + findProcessorRouteMapping are env-scoped. - AgentRegistrationController: environmentId is required on register; removed all "default" fallbacks from register/refresh/heartbeat auto-heal. - UI hooks (useApplicationConfig, useProcessorRouteMapping, useAppSettings, useAllAppSettings, useUpdateAppSettings) take env, wired to useEnvironmentStore at all call sites. - New ConfigEnvIsolationIT covers env-isolation for both repositories. Plan in docs/superpowers/plans/2026-04-16-environment-scoping.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9.2 KiB
9.2 KiB
paths
| paths | |
|---|---|
|
App Module Key Classes
cameleer-server-app/src/main/java/com/cameleer/server/app/
controller/ — REST endpoints
AgentRegistrationController— POST /register (requiresenvironmentIdin body; 400 if missing/blank), POST /heartbeat (env from bodyenvironmentId→ JWTenvclaim; 400 if neither present during auto-heal), GET / (list), POST /refresh-token (rejects tokens with noenvclaim)AgentSseController— GET /sse (Server-Sent Events connection)AgentCommandController— POST /broadcast, POST /{agentId}, POST /{agentId}/ackAppController— CRUD /api/v1/apps, POST /{appId}/upload-jar, GET /{appId}/versionsDeploymentController— GET/POST /api/v1/apps/{appId}/deployments, POST /{id}/stop, POST /{id}/promote, GET /{id}/logsEnvironmentAdminController— CRUD /api/v1/admin/environments, PUT /{id}/jar-retentionExecutionController— GET /api/v1/executions (search + detail)SearchController— POST /api/v1/search, GET /routes, GET /top-errors, GET /punchcardLogQueryController— GET /api/v1/logs (filters: source, application, agentId, exchangeId, level, logger, q, environment, time range)LogIngestionController— POST /api/v1/data/logs (acceptsList<LogEntry>JSON array, each entry hassource: app/agent). Logs WARN for: missing agent identity, unregistered agents, empty payloads, buffer-full drops, deserialization failures. Normal acceptance at DEBUG.CatalogController— GET /api/v1/catalog (unified app catalog merging PG managed apps + in-memory agents + CH stats), DELETE /api/v1/catalog/{applicationId} (ADMIN: dismiss app, purge all CH data + PG record). Auto-filters discovered apps older thandiscoveryttldayswith no live agents.ChunkIngestionController— POST /api/v1/ingestion/chunk/{executions|metrics|diagrams}UserAdminController— CRUD /api/v1/admin/users, POST /{id}/roles, POST /{id}/set-passwordRoleAdminController— CRUD /api/v1/admin/rolesGroupAdminController— CRUD /api/v1/admin/groupsOidcConfigAdminController— GET/POST /api/v1/admin/oidc, POST /testSensitiveKeysAdminController— GET/PUT /api/v1/admin/sensitive-keys. GET returns 200 with config or 204 if not configured. PUT accepts{ keys: [...] }with optional?pushToAgents=true. The fan-out iterates over every distinct(application, environment)slice (from persistedapplication_configrows plus currently-registered agents) and pushes per-slice merged keys — intentional global baseline + per-env overrides. Stored inserver_configtable (keysensitive_keys).AuditLogController— GET /api/v1/admin/auditMetricsController— GET /api/v1/metrics, GET /timeseriesDiagramController— GET /api/v1/diagrams/{id}, POST /api/v1/data/diagrams. Ingestion resolves applicationId + environment from the agent registry (keyed on JWT subject) and stamps both on the storedTaggedDiagram.route_diagramsCH table has anenvironmentcolumn; queries likefindProcessorRouteMapping(app, env)filter by it.DiagramRenderController— POST /api/v1/diagrams/render (ELK layout)ClaimMappingAdminController— CRUD /api/v1/admin/claim-mappings, POST /test (accepts inline rules + claims for preview without saving)LicenseAdminController— GET/POST /api/v1/admin/licenseAgentEventsController— GET /api/v1/agent-events (agent state change history)AgentMetricsController— GET /api/v1/agent-metrics (JVM/Camel metrics per agent instance)AppSettingsController— GET/PUT /api/v1/admin/app-settings (list), /api/v1/admin/app-settings/{appId} (per-app). All endpoints require?environment=.ApplicationConfigController—/api/v1/config(agent/admin observability config: traced processors, taps, route recording, per-app sensitive keys). GET list requires?environment=. GET/PUT/DELETE for a single app are env-scoped: for AGENT role the env comes from the JWTenvclaim (query param ignored, agents cannot spoof env); for non-agent callers env must be supplied via?environment=(user JWTs carry a placeholder env="default" that is NOT authoritative).defaultConfig(application, environment)is returned when no row exists.ClickHouseAdminController— GET /api/v1/admin/clickhouse (ClickHouse admin, conditional on infrastructure endpoints)DatabaseAdminController— GET /api/v1/admin/database (PG admin, conditional on infrastructure endpoints)DetailController— GET /api/v1/detail (execution detail with processor tree)EventIngestionController— POST /api/v1/data/events (agent event ingestion)RbacStatsController— GET /api/v1/admin/rbac/statsRouteCatalogController— GET /api/v1/routes/catalog (merged route catalog from registry + ClickHouse)RouteMetricsController— GET /api/v1/route-metrics (per-route Camel metrics)ThresholdAdminController— CRUD /api/v1/admin/thresholdsUsageAnalyticsController— GET /api/v1/admin/usage (ClickHouse usage_events)
runtime/ — Docker orchestration
DockerRuntimeOrchestrator— implements RuntimeOrchestrator; Docker Java client (zerodep transport), container lifecycleDeploymentExecutor— @Async staged deploy: PRE_FLIGHT -> PULL_IMAGE -> CREATE_NETWORK -> START_REPLICAS -> HEALTH_CHECK -> SWAP_TRAFFIC -> COMPLETE. Container names are{tenantId}-{envSlug}-{appSlug}-{replicaIndex}(globally unique on Docker daemon). Sets per-replicaCAMELEER_AGENT_INSTANCEIDenv var to{envSlug}-{appSlug}-{replicaIndex}.DockerNetworkManager— ensures bridge networks (cameleer-traefik, cameleer-env-{slug}), connects containersDockerEventMonitor— persistent Docker event stream listener (die, oom, start, stop), updates deployment statusTraefikLabelBuilder— generates Traefik Docker labels for path-based or subdomain routing. Also emitscameleer.replicaandcameleer.instance-idlabels per container for labels-first identity.PrometheusLabelBuilder— generates Prometheus Docker labels (prometheus.scrape/path/port) per runtime type fordocker_sd_configsauto-discoveryContainerLogForwarder— streams Docker container stdout/stderr to ClickHouse withsource='container'. One follow-stream thread per container, batches lines every 2s/50 lines viaClickHouseLogStore.insertBufferedBatch(). 60-second max capture timeout.DisabledRuntimeOrchestrator— no-op when runtime not enabled
metrics/ — Prometheus observability
ServerMetrics— centralized business metrics: gauges (agents by state, SSE connections, buffer depths), counters (ingestion drops, agent transitions, deployment outcomes, auth failures), timers (flush duration, deployment duration). Exposed via/api/v1/prometheus.
storage/ — PostgreSQL repositories (JdbcTemplate)
PostgresAppRepository,PostgresAppVersionRepository,PostgresEnvironmentRepositoryPostgresDeploymentRepository— includes JSONB replica_states, deploy_stage, findByContainerIdPostgresUserRepository,PostgresRoleRepository,PostgresGroupRepositoryPostgresAuditRepository,PostgresOidcConfigRepository,PostgresClaimMappingRepository,PostgresSensitiveKeysRepositoryPostgresAppSettingsRepository,PostgresApplicationConfigRepository,PostgresThresholdRepository. Bothapp_settingsandapplication_configare env-scoped (PK(app_id, environment)/(application, environment)); finders take(app, env)— no env-agnostic variants.
storage/ — ClickHouse stores
ClickHouseExecutionStore,ClickHouseMetricsStore,ClickHouseMetricsQueryStoreClickHouseStatsStore— pre-aggregated stats, punchcardClickHouseDiagramStore,ClickHouseAgentEventRepositoryClickHouseUsageTracker— usage_events for billingClickHouseRouteCatalogStore— persistent route catalog with first_seen cache, warm-loaded on startup
search/ — ClickHouse search and log stores
ClickHouseLogStore— log storage and query, MDC-based exchange/processor correlationClickHouseSearchIndex— full-text search
security/ — Spring Security
SecurityConfig— WebSecurityFilterChain, JWT filter, CORS, OIDC conditionalJwtAuthenticationFilter— OncePerRequestFilter, validates Bearer tokensJwtServiceImpl— HMAC-SHA256 JWT (Nimbus JOSE)OidcAuthController— /api/v1/auth/oidc (login-uri, token-exchange, logout)OidcTokenExchanger— code -> tokens, role extraction from access_token then id_tokenOidcProviderHelper— OIDC discovery, JWK source cache
agent/ — Agent lifecycle
SseConnectionManager— manages per-agent SSE connections, delivers commandsAgentLifecycleMonitor— @Scheduled 10s, LIVE->STALE->DEAD transitionsSsePayloadSigner— Ed25519 signs SSE payloads for agent verification
retention/ — JAR cleanup
JarRetentionJob— @Scheduled 03:00 daily, per-environment retention, skips deployed versions
config/ — Spring beans
RuntimeOrchestratorAutoConfig— conditional Docker/Disabled orchestrator + NetworkManager + EventMonitorRuntimeBeanConfig— DeploymentExecutor, AppService, EnvironmentServiceSecurityBeanConfig— JwtService, Ed25519, BootstrapTokenValidatorStorageBeanConfig— all repositoriesClickHouseConfig— ClickHouse JdbcTemplate, schema initializer