diff --git a/common-authentication/src/main/java/org/alfresco/hxi_connector/common/adapters/messaging/repository/ProcessingStarter.java b/common-authentication/src/main/java/org/alfresco/hxi_connector/common/adapters/messaging/repository/ProcessingStarter.java index 245d06522..0edb3872f 100644 --- a/common-authentication/src/main/java/org/alfresco/hxi_connector/common/adapters/messaging/repository/ProcessingStarter.java +++ b/common-authentication/src/main/java/org/alfresco/hxi_connector/common/adapters/messaging/repository/ProcessingStarter.java @@ -25,6 +25,9 @@ */ package org.alfresco.hxi_connector.common.adapters.messaging.repository; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.camel.CamelContext; @@ -42,7 +45,20 @@ public class ProcessingStarter @SuppressWarnings("PMD.SignatureDeclareThrowsException") public void startProcessing() throws Exception { - log.info("Starting camel routes"); + log.info("Starting Camel routes: \n\t{}", getRoutesIds()); camelContext.getRouteController().startAllRoutes(); + + while (camelContext.getRouteController().isStartingRoutes()) + { + TimeUnit.MILLISECONDS.sleep(100); + } + log.atInfo().log("All Camel routes started successfully"); + } + + private String getRoutesIds() + { + return camelContext.getRoutes().stream() + .map(route -> route.getId().concat(" - ").concat(route.getEndpoint().toString())) + .collect(Collectors.joining("\n\t")); } } diff --git a/common-test/src/main/java/org/alfresco/hxi_connector/common/test/docker/util/DockerContainers.java b/common-test/src/main/java/org/alfresco/hxi_connector/common/test/docker/util/DockerContainers.java index 0555eb29b..bff01a8be 100644 --- a/common-test/src/main/java/org/alfresco/hxi_connector/common/test/docker/util/DockerContainers.java +++ b/common-test/src/main/java/org/alfresco/hxi_connector/common/test/docker/util/DockerContainers.java @@ -286,9 +286,10 @@ public static GenericContainer createLiveIngesterContainerWithin(Network netw .withEnv("SPRING_ACTIVEMQ_BROKERURL", "nio://activemq:61616") .withEnv("ALFRESCO_TRANSFORM_SHAREDFILESTORE_BASEURL", "http://shared-file-store:8099") .withEnv("ALFRESCO_REPOSITORY_HEALTH_PROBE_INTERVAL_SECONDS", "1") - .withExposedPorts(5007) - .withStartupTimeout(Duration.ofMinutes(2)) - .waitingFor(Wait.forLogMessage(".*Started LiveIngesterApplication.*", 1)) + .withExposedPorts(8080, 5007) + .waitingFor(Wait.forHttp("/actuator/health/readiness") + .forPort(8080) + .withStartupTimeout(Duration.ofMinutes(2))) .withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("LiveIngesterContainer"))); Optional.ofNullable(network).ifPresent(n -> liveIngester.withNetwork(n).withNetworkAliases(LIVE_INGESTER_ALIAS)); @@ -319,8 +320,10 @@ public static GenericContainer createPredictionApplierContainerWithin(Network GenericContainer predictionApplier = new GenericContainer<>(DockerImageName.parse(PREDICTION_APPLIER_IMAGE).withTag(HXI_CONNECTOR_TAG)) .withEnv("JAVA_TOOL_OPTIONS", "-agentlib:jdwp=transport=dt_socket,address=*:5009,server=y,suspend=n") .withEnv("LOGGING_LEVEL_ORG_ALFRESCO", "DEBUG") - .withExposedPorts(5009) - .withStartupTimeout(Duration.ofMinutes(2)) + .withExposedPorts(8080, 5009) + .waitingFor(Wait.forHttp("/actuator/health/readiness") + .forPort(8080) + .withStartupTimeout(Duration.ofMinutes(2))) .withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("PredictionApplierContainer"))); Optional.ofNullable(network).ifPresent(n -> predictionApplier.withNetwork(n).withNetworkAliases(PREDICTION_APPLIER_ALIAS)); diff --git a/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/CreateNodeE2eTest.java b/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/CreateNodeE2eTest.java index d3f0179e5..c1bfa43ad 100644 --- a/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/CreateNodeE2eTest.java +++ b/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/CreateNodeE2eTest.java @@ -92,7 +92,7 @@ public class CreateNodeE2eTest { private static final ObjectMapper objectMapper = new ObjectMapper(); protected static final String BUCKET_NAME = "test-hxinsight-bucket"; - private static final int INITIAL_DELAY_MS = 500; + private static final int DELAY_MS = 500; private static final String PARENT_ID = "-my-"; private static final String DUMMY_CONTENT = "Dummy's file dummy content"; private static final String ALLOW_ACCESS_PROPERTY = "ALLOW_ACCESS"; @@ -134,7 +134,7 @@ public void beforeAll() throws IOException, InterruptedException repositoryClient = new RepositoryClient(repository.getBaseUrl(), ADMIN_USER); WireMock.configureFor(hxInsightMock.getHost(), hxInsightMock.getPort()); // wait for repo to load transform config - RetryUtils.retryWithBackoff(() -> assertThat(transformRouter.getLogs()).contains("GET Transform Config version"), 800); + RetryUtils.retryWithBackoff(() -> assertThat(transformRouter.getLogs()).contains("GET Transform Config version"), 1000); } @AfterEach @@ -163,7 +163,7 @@ final void testCreateNodeContainingImageFile() throws IOException WireMock.verify(moreThanOrExactly(2), postRequestedFor(urlEqualTo("/ingestion-events")) .withRequestBody(containing(createdNode.id()).and(containing("sourceTimestamp"))) .withHeader(USER_AGENT, matching(getAppInfoRegex()))); - }, INITIAL_DELAY_MS); + }, DELAY_MS); } @Test @@ -191,7 +191,7 @@ final void testCreateNodeContainingTextFile() throws IOException WireMock.verify(moreThanOrExactly(2), postRequestedFor(urlEqualTo("/ingestion-events")) .withRequestBody(containing(createdNode.id()).and(containing("sourceTimestamp"))) .withHeader(USER_AGENT, matching(getAppInfoRegex()))); - }, INITIAL_DELAY_MS); + }, DELAY_MS); } @Test @@ -226,7 +226,7 @@ final void testCreateNodeWithDefaultPermissions() assertTrue(properties.has(DENY_ACCESS_PROPERTY)); assertEquals(Set.of(), asSet(properties.get(DENY_ACCESS_PROPERTY).get("value"))); - }, INITIAL_DELAY_MS); + }, DELAY_MS); } @SneakyThrows diff --git a/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/DeleteNodeE2eTest.java b/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/DeleteNodeE2eTest.java index f7258fa59..41ca0ed54 100644 --- a/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/DeleteNodeE2eTest.java +++ b/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/DeleteNodeE2eTest.java @@ -30,7 +30,6 @@ import static com.github.tomakehurst.wiremock.client.WireMock.matching; import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static org.alfresco.hxi_connector.common.constant.HttpHeaders.USER_AGENT; import static org.alfresco.hxi_connector.common.test.docker.repository.RepositoryType.ENTERPRISE; @@ -69,7 +68,7 @@ @SuppressWarnings("PMD.FieldNamingConventions") public class DeleteNodeE2eTest { - private static final int DELAY_MS = 700; + private static final int DELAY_MS = 1200; private static final String PARENT_ID = "-my-"; private static final String DUMMY_CONTENT = "Dummy's file dummy content"; @@ -105,7 +104,7 @@ void testReceiveDeleteEvent() throws IOException @Cleanup InputStream fileContent = new ByteArrayInputStream(DUMMY_CONTENT.getBytes()); Node createdNode = repositoryClient.createNodeWithContent(PARENT_ID, "dummy.txt", fileContent, "text/plain"); - RetryUtils.retryWithBackoff(() -> verify(exactly(1), postRequestedFor(urlEqualTo("/ingestion-events")) + RetryUtils.retryWithBackoff(() -> WireMock.verify(exactly(1), postRequestedFor(urlEqualTo("/ingestion-events")) .withRequestBody(containing(createdNode.id()))), DELAY_MS); WireMock.reset(); @@ -113,7 +112,7 @@ void testReceiveDeleteEvent() throws IOException repositoryClient.deleteNode(createdNode.id()); // then - RetryUtils.retryWithBackoff(() -> verify(exactly(1), postRequestedFor(urlEqualTo("/ingestion-events")) + RetryUtils.retryWithBackoff(() -> WireMock.verify(exactly(1), postRequestedFor(urlEqualTo("/ingestion-events")) .withRequestBody(containing("\"objectId\":\"%s\"".formatted(createdNode.id()))) .withRequestBody(containing("\"sourceId\":\"alfresco-dummy-source-id-0a63de491876\"")) .withRequestBody(containing("\"sourceTimestamp\"")) diff --git a/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/LiveIngesterWithUnreachableACSE2eTest.java b/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/LiveIngesterWithUnreachableACSE2eTest.java index 7a85f676e..65c96c643 100644 --- a/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/LiveIngesterWithUnreachableACSE2eTest.java +++ b/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/LiveIngesterWithUnreachableACSE2eTest.java @@ -45,6 +45,7 @@ import org.testcontainers.containers.Network; import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.containers.localstack.LocalStackContainer; +import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.wiremock.integrations.testcontainers.WireMockContainer; @@ -83,6 +84,7 @@ public class LiveIngesterWithUnreachableACSE2eTest .dependsOn(postgres, activemq, transformRouter, sfs); @Container private static final GenericContainer liveIngester = createLiveIngesterContainer() + .waitingFor(Wait.forLogMessage(".*Started LiveIngesterApplication.*", 1)) .withEnv("ALFRESCO_REPOSITORY_BASE_URL", "http://localhost:1938/alfresco") // <- random unreachable port .dependsOn(activemq, hxInsightMock, awsMock, repository); diff --git a/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/PredictionApplierWithUnreachableACSE2eTest.java b/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/PredictionApplierWithUnreachableACSE2eTest.java index 653181473..5125963c6 100644 --- a/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/PredictionApplierWithUnreachableACSE2eTest.java +++ b/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/PredictionApplierWithUnreachableACSE2eTest.java @@ -42,6 +42,7 @@ import org.testcontainers.containers.Network; import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.containers.localstack.LocalStackContainer; +import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.wiremock.integrations.testcontainers.WireMockContainer; @@ -78,11 +79,13 @@ public class PredictionApplierWithUnreachableACSE2eTest .dependsOn(postgres, activemq, transformRouter, sfs); @Container private static final GenericContainer liveIngester = createLiveIngesterContainer() + .waitingFor(Wait.forLogMessage(".*Started LiveIngesterApplication.*", 1)) .withEnv("ALFRESCO_REPOSITORY_BASE_URL", "http://localhost:1938/alfresco") // <- random unreachable port .dependsOn(activemq, hxInsightMock, awsMock, repository); @Container private static final GenericContainer predictionApplier = createPredictionApplierContainer() + .waitingFor(Wait.forLogMessage(".*Started PredictionApplierApplication.*", 1)) .withEnv("ALFRESCO_REPOSITORY_BASE_URL", "http://localhost:1938/alfresco") // <- random unreachable port .dependsOn(activemq, hxInsightMock, repository, liveIngester); diff --git a/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/UpdateNodeE2eTest.java b/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/UpdateNodeE2eTest.java index 5f1e42ddb..2a2fad495 100644 --- a/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/UpdateNodeE2eTest.java +++ b/e2e-test/src/test/java/org/alfresco/hxi_connector/e2e_test/UpdateNodeE2eTest.java @@ -37,7 +37,6 @@ import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathTemplate; -import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static com.github.tomakehurst.wiremock.stubbing.Scenario.STARTED; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -141,7 +140,7 @@ public class UpdateNodeE2eTest .dependsOn(postgres, activemq); @Container private static final GenericContainer liveIngester = createLiveIngesterContainer() - .dependsOn(activemq, repository, hxInsightMock); + .dependsOn(activemq, hxInsightMock, repository); @Container private static final GenericContainer predictionApplier = createPredictionApplierContainer() .dependsOn(activemq, hxInsightMock, repository, liveIngester); @@ -162,7 +161,7 @@ public void setUp() throws IOException @Cleanup InputStream fileContent = new ByteArrayInputStream(DUMMY_CONTENT.getBytes()); createdNode = repositoryClient.createNodeWithContent(PARENT_ID, "dummy.txt", fileContent, "text/plain"); - RetryUtils.retryWithBackoff(() -> verify(moreThanOrExactly(1), postRequestedFor(urlEqualTo("/ingestion-events")) + RetryUtils.retryWithBackoff(() -> WireMock.verify(moreThanOrExactly(1), postRequestedFor(urlEqualTo("/ingestion-events")) .withRequestBody(containing(createdNode.id()))), DELAY_MS); WireMock.reset(); } @@ -187,7 +186,7 @@ void testApplyPredictionToNode() .containsKey(PROPERTY_TO_UPDATE) .extracting(map -> map.get(PROPERTY_TO_UPDATE)).isEqualTo(PREDICTED_VALUE); }, DELAY_MS); - verify(exactly(0), anyRequestedFor(urlEqualTo("/ingestion-events"))); + WireMock.verify(exactly(0), anyRequestedFor(urlEqualTo("/ingestion-events"))); } @Test @@ -206,7 +205,7 @@ void testApplyPredictionToUpdatedNode() // when Node updatedNode = repositoryClient.updateNodeWithContent(createdNode.id(), UPDATE_NODE_PROPERTIES); - RetryUtils.retryWithBackoff(() -> verify(exactly(1), postRequestedFor(urlEqualTo("/ingestion-events")) + RetryUtils.retryWithBackoff(() -> WireMock.verify(exactly(1), postRequestedFor(urlEqualTo("/ingestion-events")) .withRequestBody(containing(updatedNode.id())) .withHeader(USER_AGENT, matching(getAppInfoRegex())))); WireMock.reset(); @@ -223,7 +222,7 @@ void testApplyPredictionToUpdatedNode() .containsKey(PROPERTY_TO_UPDATE) .extracting(map -> map.get(PROPERTY_TO_UPDATE)).isEqualTo(USER_VALUE); }, DELAY_MS); - verify(exactly(0), anyRequestedFor(urlEqualTo("/ingestion-events"))); + WireMock.verify(exactly(0), anyRequestedFor(urlEqualTo("/ingestion-events"))); } @Test @@ -234,7 +233,7 @@ final void testSendTimestampToHxi() Node updatedNode = repositoryClient.updateNodeWithContent(createdNode.id(), UPDATE_NODE_PROPERTIES); // then - RetryUtils.retryWithBackoff(() -> verify(exactly(1), postRequestedFor(urlEqualTo("/ingestion-events")) + RetryUtils.retryWithBackoff(() -> WireMock.verify(exactly(1), postRequestedFor(urlEqualTo("/ingestion-events")) .withRequestBody(containing(updatedNode.id())) .withRequestBody(containing("sourceTimestamp")) .withHeader(USER_AGENT, matching(getAppInfoRegex()))));