From 95b9dea5c49190c910e2865acc907bc44582e2d0 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Wed, 1 Apr 2026 00:09:14 +0200 Subject: [PATCH] feat(clickhouse): wire ClickHouseExecutionStore as active ExecutionStore Add cameleer.storage.executions feature flag (default: clickhouse). PostgresExecutionStore activates only when explicitly set to postgres. Add by-seq snapshot endpoint for iteration-aware processor lookup. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../server/app/config/StorageBeanConfig.java | 13 +++++++++++++ .../server/app/controller/DetailController.java | 12 ++++++++++++ .../server/app/storage/PostgresExecutionStore.java | 2 -- .../src/main/resources/application.yml | 1 + deploy/base/server.yaml | 2 ++ 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java index ef51461b..b0fc1143 100644 --- a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java +++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java @@ -6,6 +6,7 @@ import com.cameleer3.server.app.storage.ClickHouseDiagramStore; import com.cameleer3.server.app.storage.ClickHouseMetricsQueryStore; import com.cameleer3.server.app.storage.ClickHouseMetricsStore; import com.cameleer3.server.app.storage.ClickHouseStatsStore; +import com.cameleer3.server.app.storage.PostgresExecutionStore; import com.cameleer3.server.app.storage.PostgresMetricsQueryStore; import com.cameleer3.server.app.storage.PostgresMetricsStore; import com.cameleer3.server.core.admin.AuditRepository; @@ -96,6 +97,18 @@ public class StorageBeanConfig { return new ClickHouseExecutionStore(clickHouseJdbc); } + @Bean + @ConditionalOnProperty(name = "cameleer.storage.executions", havingValue = "clickhouse", matchIfMissing = true) + public ExecutionStore executionStoreClickHouse(ClickHouseExecutionStore chStore) { + return chStore; // Same instance, also exposed as ExecutionStore + } + + @Bean + @ConditionalOnProperty(name = "cameleer.storage.executions", havingValue = "postgres") + public ExecutionStore executionStorePostgres(JdbcTemplate jdbc) { + return new PostgresExecutionStore(jdbc); + } + @Bean @ConditionalOnProperty(name = "clickhouse.enabled", havingValue = "true") public ChunkAccumulator chunkAccumulator( diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DetailController.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DetailController.java index dc705523..b2d198e4 100644 --- a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DetailController.java +++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DetailController.java @@ -81,4 +81,16 @@ public class DetailController { .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); } + + @GetMapping("/{executionId}/processors/by-seq/{seq}/snapshot") + @Operation(summary = "Get exchange snapshot for a processor by seq number") + @ApiResponse(responseCode = "200", description = "Snapshot data") + @ApiResponse(responseCode = "404", description = "Snapshot not found") + public ResponseEntity> processorSnapshotBySeq( + @PathVariable String executionId, + @PathVariable int seq) { + return detailService.getProcessorSnapshotBySeq(executionId, seq) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } } diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java index 9d0263de..b17e95a1 100644 --- a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java +++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java @@ -3,7 +3,6 @@ package com.cameleer3.server.app.storage; import com.cameleer3.server.core.storage.ExecutionStore; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Repository; import java.sql.ResultSet; import java.sql.SQLException; @@ -12,7 +11,6 @@ import java.time.Instant; import java.util.List; import java.util.Optional; -@Repository public class PostgresExecutionStore implements ExecutionStore { private final JdbcTemplate jdbc; diff --git a/cameleer3-server-app/src/main/resources/application.yml b/cameleer3-server-app/src/main/resources/application.yml index 99e64c9e..dd0553b8 100644 --- a/cameleer3-server-app/src/main/resources/application.yml +++ b/cameleer3-server-app/src/main/resources/application.yml @@ -55,6 +55,7 @@ cameleer: diagrams: ${CAMELEER_STORAGE_DIAGRAMS:clickhouse} events: ${CAMELEER_STORAGE_EVENTS:clickhouse} logs: ${CAMELEER_STORAGE_LOGS:clickhouse} + executions: ${CAMELEER_STORAGE_EXECUTIONS:clickhouse} security: access-token-expiry-ms: 3600000 diff --git a/deploy/base/server.yaml b/deploy/base/server.yaml index 9991967d..ceaf7676 100644 --- a/deploy/base/server.yaml +++ b/deploy/base/server.yaml @@ -101,6 +101,8 @@ spec: value: "clickhouse" - name: CAMELEER_STORAGE_LOGS value: "clickhouse" + - name: CAMELEER_STORAGE_EXECUTIONS + value: "clickhouse" resources: requests: