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'",