diff --git a/cameleer3-server-app/pom.xml b/cameleer3-server-app/pom.xml
index ca66696b..14fc2f5e 100644
--- a/cameleer3-server-app/pom.xml
+++ b/cameleer3-server-app/pom.xml
@@ -90,6 +90,30 @@
org.springframework.boot
spring-boot-maven-plugin
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ 1
+ false
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+ 1
+ false
+
+
+
+
+ integration-test
+ verify
+
+
+
+
diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java
index 288ec733..142e1512 100644
--- a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java
+++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java
@@ -4,6 +4,7 @@ import com.cameleer3.common.model.ExchangeSnapshot;
import com.cameleer3.common.model.ProcessorExecution;
import com.cameleer3.common.model.RouteExecution;
import com.cameleer3.server.core.detail.RawExecutionRow;
+import com.cameleer3.server.core.storage.DiagramRepository;
import com.cameleer3.server.core.storage.ExecutionRepository;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -53,9 +54,11 @@ public class ClickHouseExecutionRepository implements ExecutionRepository {
""";
private final JdbcTemplate jdbcTemplate;
+ private final DiagramRepository diagramRepository;
- public ClickHouseExecutionRepository(JdbcTemplate jdbcTemplate) {
+ public ClickHouseExecutionRepository(JdbcTemplate jdbcTemplate, DiagramRepository diagramRepository) {
this.jdbcTemplate = jdbcTemplate;
+ this.diagramRepository = diagramRepository;
}
@Override
@@ -138,7 +141,10 @@ public class ClickHouseExecutionRepository implements ExecutionRepository {
ps.setObject(col++, inputHeaders); // processor_input_headers
ps.setObject(col++, outputHeaders); // processor_output_headers
ps.setObject(col++, diagramNodeIds); // processor_diagram_node_ids
- ps.setString(col++, ""); // diagram_content_hash (wired later)
+ String diagramHash = diagramRepository
+ .findContentHashForRoute(exec.getRouteId(), "")
+ .orElse("");
+ ps.setString(col++, diagramHash); // diagram_content_hash
}
@Override
diff --git a/cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SearchControllerIT.java b/cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SearchControllerIT.java
index 7a3bfa87..1aa36f92 100644
--- a/cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SearchControllerIT.java
+++ b/cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SearchControllerIT.java
@@ -327,12 +327,12 @@ class SearchControllerIT extends AbstractClickHouseIT {
@Test
void pagination_worksCorrectly() throws Exception {
- // First, get total count of COMPLETED executions (8 from our seed data,
- // but may include data from other test classes)
+ // First, get total count of COMPLETED executions (7 from our seed data:
+ // exec 1 + execs 5-10; execs 2,4 are FAILED, exec 3 is RUNNING)
ResponseEntity countResponse = searchGet("?status=COMPLETED&limit=1");
JsonNode countBody = objectMapper.readTree(countResponse.getBody());
long totalCompleted = countBody.get("total").asLong();
- assertThat(totalCompleted).isGreaterThanOrEqualTo(8);
+ assertThat(totalCompleted).isGreaterThanOrEqualTo(7);
// Now test pagination with offset=2, limit=3
ResponseEntity response = searchPost("""
diff --git a/cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/DiagramLinkingIT.java b/cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/DiagramLinkingIT.java
index f6b57474..2c464323 100644
--- a/cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/DiagramLinkingIT.java
+++ b/cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/DiagramLinkingIT.java
@@ -91,7 +91,7 @@ class DiagramLinkingIT extends AbstractClickHouseIT {
assertThat(execResponse.getStatusCode()).isEqualTo(HttpStatus.ACCEPTED);
// 4. Verify diagram_content_hash is a non-empty SHA-256 hash (64 hex chars)
- await().atMost(10, SECONDS).untilAsserted(() -> {
+ await().atMost(10, SECONDS).ignoreExceptions().untilAsserted(() -> {
String hash = jdbcTemplate.queryForObject(
"SELECT diagram_content_hash FROM route_executions WHERE route_id = 'diagram-link-route'",
String.class);
@@ -140,7 +140,7 @@ class DiagramLinkingIT extends AbstractClickHouseIT {
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.ACCEPTED);
// Verify diagram_content_hash is empty string (graceful fallback)
- await().atMost(10, SECONDS).untilAsserted(() -> {
+ await().atMost(10, SECONDS).ignoreExceptions().untilAsserted(() -> {
String hash = jdbcTemplate.queryForObject(
"SELECT diagram_content_hash FROM route_executions WHERE route_id = 'no-diagram-route'",
String.class);
diff --git a/cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/IngestionSchemaIT.java b/cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/IngestionSchemaIT.java
index e8e756ad..23710a6c 100644
--- a/cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/IngestionSchemaIT.java
+++ b/cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/IngestionSchemaIT.java
@@ -84,7 +84,7 @@ class IngestionSchemaIT extends AbstractClickHouseIT {
postExecution(json);
- await().atMost(10, SECONDS).untilAsserted(() -> {
+ await().atMost(30, SECONDS).ignoreExceptions().untilAsserted(() -> {
// Use individual typed queries to avoid ClickHouse Array cast issues
var depths = queryArray(
"SELECT processor_depths FROM route_executions WHERE route_id = 'schema-test-tree'");
@@ -160,7 +160,7 @@ class IngestionSchemaIT extends AbstractClickHouseIT {
postExecution(json);
- await().atMost(10, SECONDS).untilAsserted(() -> {
+ await().atMost(30, SECONDS).ignoreExceptions().untilAsserted(() -> {
// Bodies should contain all sources
String bodies = jdbcTemplate.queryForObject(
"SELECT exchange_bodies FROM route_executions WHERE route_id = 'schema-test-bodies'",
@@ -206,7 +206,7 @@ class IngestionSchemaIT extends AbstractClickHouseIT {
postExecution(json);
- await().atMost(10, SECONDS).untilAsserted(() -> {
+ await().atMost(30, SECONDS).ignoreExceptions().untilAsserted(() -> {
// Empty but not null
String bodies = jdbcTemplate.queryForObject(
"SELECT exchange_bodies FROM route_executions WHERE route_id = 'schema-test-null-snap'",