Reputation: 354
I have two containers in my tests using @Testcontainers
with Junit5, a Kafka
and a KafkaConnect
.
@Container
private final KafkaContainer kafka = new KafkaContainer()
.withNetwork(network)
.withNetworkAliases("kafka");
@Container
private final GenericContainer KafkaConnect =
new GenericContainer("confluentinc/cp-kafka-connect:latest")
.withEnv("CONNECT_BOOTSTRAP_SERVERS", "kafka:9092")
.withEnv("CONNECT_REST_PORT", 8083)
.withNetwork(network)
...
When I execute the tests, I find an error because Kafka Connect service in kafkaConnect
is not is not started correctly (mapped port 8083 is not listening). It is because kafkaConnect
is started before kafka
and when the kafka:9092
url is reached during the kafkaConnect
execution no response is obtained since kafka
is not running yet.
Then, I have tried to pospone the kafkaConnect
start up in order to wait for kafka
to ensure kafka:9092
availability.
I have tried different approach to do this but I did not fix the problem. I tried to add some configurations.
startupTimeout
. As far as I know, this config does not pospone the start operation. It just increase the period to check if the container is started.
.withStartupTimeout(Duration.of(240, SECONDS))
I also tried some configurations for waitingFor
, such as timeout-based, which,a s expected, produces the same result than withStartupTimeout
.waitingFor(Wait.defaultWaitStrategy().withStartupTimeout(...))
or port-based, which does not solve my issue because it does not point to kafka
container but kafkaConnect
.
.waitingFor(Wait.forHttp("http://kafka:9092"))
I have also tried to add a number of startup attempts but it does not solve the issue because the kafkaConnect
is relaunch some times but always before kafka
.
As a solution I removed @Container
of kafkaConnect
declaration in order to use manage manually its lifecycle, so I added the explicit starting to testcase, see below
@Test
test() {
kafkaConnect.start();
...
}
This ensure kafkaConnect
is started after kafka
. However, I did not find a solution to define the order during the container definition, by means of strategies, policies or something similar, in order to add dependencies between containers and to avoid a imperative and manual lifecycle management.
is it possible?
Upvotes: 5
Views: 2208
Reputation: 1582
import org.junit.rules.RuleChain;
// @Container <-- Remove annotation.
private final KafkaContainer kafka = new KafkaContainer()...;
// @Container <-- Remove annotation.
private final GenericContainer kafkaConnect =
new GenericContainer("confluentinc/cp-kafka-connect:latest")
.withEnv("CONNECT_BOOTSTRAP_SERVERS", "kafka:9092")
...;
// Start the containers in the correct order. Prevents
// "Mapped port can only be obtained after the container is started"
// error.
@Rule
public final RuleChain chain =
RuleChain
// Started first.
.outerRule(kafka)
// Started later.
.around(kafkaConnect);
Upvotes: 1