Skip to content

Commit 0409694

Browse files
committed
chore: Allow custom client names for LocalStack Testcontainers services and improve logging
1 parent 4ccf9ef commit 0409694

File tree

6 files changed

+117
-7
lines changed

6 files changed

+117
-7
lines changed

connectors/citrus-testcontainers/src/main/java/org/citrusframework/testcontainers/actions/StartTestcontainersAction.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ public StartTestcontainersAction(AbstractBuilder<C, ? extends StartTestcontainer
5858

5959
@Override
6060
public void doExecute(TestContext context) {
61+
logger.info("Starting Testcontainers container '{}'", containerName);
62+
6163
container.start();
6264

6365
if (containerName != null && !context.getReferenceResolver().isResolvable(containerName)) {
@@ -67,10 +69,17 @@ public void doExecute(TestContext context) {
6769
exposeConnectionSettings(container, context);
6870

6971
if (autoRemoveResources) {
72+
if (logger.isDebugEnabled()) {
73+
logger.debug("Auto remove enabled for Testcontainers container '{}' " +
74+
"- container will be stopped automatically after the test", getContainerName(container, containerName));
75+
}
76+
7077
context.doFinally(testcontainers()
7178
.stop()
7279
.container(container));
7380
}
81+
82+
logger.info("Successfully started Testcontainers container '{}' with id {}", getContainerName(container, containerName), container.getContainerId());
7483
}
7584

7685
/**

connectors/citrus-testcontainers/src/main/java/org/citrusframework/testcontainers/actions/StopTestcontainersAction.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616

1717
package org.citrusframework.testcontainers.actions;
1818

19+
import java.util.Optional;
20+
1921
import org.citrusframework.context.TestContext;
22+
import org.citrusframework.exceptions.CitrusRuntimeException;
2023
import org.testcontainers.containers.GenericContainer;
2124

2225
public class StopTestcontainersAction extends AbstractTestcontainersAction {
@@ -34,12 +37,29 @@ public StopTestcontainersAction(Builder builder) {
3437
@Override
3538
public void doExecute(TestContext context) {
3639
if (container != null) {
37-
container.stop();
38-
} else if (containerName != null && context.getReferenceResolver().isResolvable(containerName)) {
39-
Object maybeContainer = context.getReferenceResolver().resolve(containerName);
40-
if (maybeContainer instanceof GenericContainer<?> genericContainer) {
41-
genericContainer.stop();
40+
stop(container, "");
41+
} else if (containerName != null) {
42+
if (context.getReferenceResolver().isResolvable(containerName)) {
43+
Object maybeContainer = context.getReferenceResolver().resolve(containerName);
44+
if (maybeContainer instanceof GenericContainer<?> genericContainer) {
45+
stop(genericContainer, containerName);
46+
}
47+
} else {
48+
logger.warn("Unable to stop Testcontainers container '{}'", containerName);
4249
}
50+
} else {
51+
throw new CitrusRuntimeException("Unable to stop Testcontainers container - neither container nor container name provided");
52+
}
53+
}
54+
55+
private void stop(GenericContainer<?> container, String name) {
56+
String containerName = getContainerName(container, name);
57+
if (container.isRunning()) {
58+
String containerId = Optional.ofNullable(container.getContainerId()).orElse("unknown");
59+
container.stop();
60+
logger.info("Successfully stopped Testcontainers container '{}' with id {}", containerName, containerId);
61+
} else {
62+
logger.info("Testcontainers container '{}' is stopped", containerName);
4363
}
4464
}
4565

connectors/citrus-testcontainers/src/main/java/org/citrusframework/testcontainers/actions/TestcontainersAction.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,30 @@
1717
package org.citrusframework.testcontainers.actions;
1818

1919
import org.citrusframework.TestAction;
20+
import org.testcontainers.containers.GenericContainer;
2021

2122
/**
2223
* Base action representing interactions with Testcontainers.
2324
*/
2425
public interface TestcontainersAction extends TestAction {
2526

27+
default String getContainerName(GenericContainer<?> container, String containerName) {
28+
String name = container.getDockerImageName();
29+
30+
if (container.getContainerInfo() != null) {
31+
name = container.getContainerInfo().getName();
32+
} else if (container.getContainerId() != null) {
33+
name = container.getCurrentContainerInfo().getName();
34+
}
35+
36+
name = name.startsWith("/") ? name.substring(1) : name;
37+
38+
if (containerName != null && !containerName.equals(name)) {
39+
return "%s (%s)".formatted(containerName, name);
40+
}
41+
42+
return name;
43+
}
44+
2645
}
2746

connectors/citrus-testcontainers/src/main/java/org/citrusframework/testcontainers/aws2/StartLocalStackAction.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ protected void exposeConnectionSettings(LocalStackContainer container, TestConte
5252
if (autoCreateClients) {
5353
for (LocalStackContainer.Service service : container.getServices()) {
5454
String clientName = "%sClient".formatted(service.getServiceName());
55+
clientName = options.getOrDefault(clientName + "Name", clientName);
56+
5557
if (context.getReferenceResolver().isResolvable(clientName)) {
58+
logger.debug("Client {} already exists - do not overwrite", clientName);
5659
// client bean with same name already exists - do not overwrite
5760
continue;
5861
}
@@ -61,9 +64,10 @@ protected void exposeConnectionSettings(LocalStackContainer container, TestConte
6164
if (clientFactory.isPresent()) {
6265
Object client = clientFactory.get().createClient(container, context.resolveDynamicValuesInMap(options));
6366
container.addClient(service, client);
67+
logger.debug("Auto create client {} for service {}", clientName, service.name());
6468
context.getReferenceResolver().bind(clientName, client);
6569
} else {
66-
logger.warn("Missing client factory for service '%s' - no client created for this service".formatted(service));
70+
logger.warn("Missing client factory for service '{}' - no client created for this service", service.name());
6771
}
6872
}
6973
}
@@ -80,7 +84,7 @@ public static class Builder extends AbstractBuilder<LocalStackContainer, StartLo
8084

8185
private boolean autoCreateClients = LocalStackSettings.isAutoCreateClients();
8286

83-
private Map<String, String> options = new HashMap<>();
87+
private final Map<String, String> options = new HashMap<>();
8488

8589
public Builder() {
8690
withStartupTimeout(LocalStackSettings.getStartupTimeout());

connectors/citrus-testcontainers/src/test/java/org/citrusframework/testcontainers/integration/aws2/StartLocalStackContainerIT.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,8 @@ private void verifyContainer(TestContext context) {
5858
} catch (IOException e) {
5959
throw new CitrusRuntimeException("Failed to verify Docker container", e);
6060
}
61+
62+
// verify auto created S3 client
63+
Assert.assertTrue(context.getReferenceResolver().isResolvable("s3Client"));
6164
}
6265
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright the original author or authors.
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License");
6+
~ you may not use this file except in compliance with the License.
7+
~ You may obtain a copy of the License at
8+
~
9+
~ http://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
-->
17+
<Configuration status="INFO">
18+
<Appenders>
19+
<Console name="STDOUT" target="SYSTEM_OUT">
20+
<PatternLayout pattern="%style{%d{yyyy-MM-dd HH:mm:ss.SSS}}{Dim} %highlight{%5p} %style{%pid}{Magenta} %style{---}{Dim} %style{[%15.15t]}{Dim} %style{%-35.35c}{Cyan} %style{:}{Dim} %m%n"/>
21+
</Console>
22+
</Appenders>
23+
24+
<Loggers>
25+
<Root level="INFO">
26+
<AppenderRef ref="STDOUT"/>
27+
</Root>
28+
29+
<!-- Our own classes-->
30+
<Logger name="org.citrusframework" additivity="false" level="INFO">
31+
<AppenderRef ref="STDOUT"/>
32+
</Logger>
33+
34+
<Logger name="Logger.Message_IN" additivity="false" level="DEBUG">
35+
<AppenderRef ref="STDOUT"/>
36+
</Logger>
37+
38+
<Logger name="Logger.Message_OUT" additivity="false" level="DEBUG">
39+
<AppenderRef ref="STDOUT"/>
40+
</Logger>
41+
42+
<Logger name="org.springframework" additivity="false" level="WARN">
43+
<AppenderRef ref="STDOUT"/>
44+
</Logger>
45+
46+
<Logger name="org.eclipse" additivity="false" level="WARN">
47+
<AppenderRef ref="STDOUT"/>
48+
</Logger>
49+
50+
<Logger name="org.apache" additivity="false" level="WARN">
51+
<AppenderRef ref="STDOUT"/>
52+
</Logger>
53+
</Loggers>
54+
55+
</Configuration>

0 commit comments

Comments
 (0)