Skip to content

Commit 6523e36

Browse files
committed
Merge remote-tracking branch 'container-up/main' into feat/support-databend
2 parents ee556a9 + ce83c36 commit 6523e36

File tree

14 files changed

+567
-54
lines changed

14 files changed

+567
-54
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: windows-test command dispatch
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
windows-test-command-trigger:
12+
permissions:
13+
pull-requests: write # for peter-evans/slash-command-dispatch to create PR reaction
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Trigger windows-test command
18+
uses: peter-evans/slash-command-dispatch@13bc09769d122a64f75aa5037256f6f2d78be8c4 # v4.0.0
19+
with:
20+
token: ${{ secrets.WINDOWS_WORKERS_TOKEN }}
21+
# The command to trigger the pipeline: e.g. /windows-test
22+
# The command name must match the name of the repository_dispatch.type in 'ci-windows.yml' workflow, using '-command' as suffix. E.g. 'windows-test-command'
23+
commands: windows-test
24+
issue-type: pull-request
25+
# The user that owns the above token must belong to the elevated role of 'Maintainers'
26+
permission: maintain
27+
reactions: false

.github/workflows/ci-windows.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ on:
3232
- 'README.md'
3333
- 'RELEASING.md'
3434
- '.sdkmanrc'
35+
repository_dispatch:
36+
types: [windows-test-command]
3537

3638
concurrency:
3739
group: "${{ github.workflow }}-${{ github.head_ref || github.sha }}"
@@ -42,7 +44,7 @@ permissions:
4244

4345
jobs:
4446
core:
45-
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
47+
if: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event.client_payload.slash_command.command == 'windows-test' }}
4648
runs-on: self-hosted
4749
permissions:
4850
checks: write

docs/modules/kafka.md

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,25 @@ Testcontainers can be used to automatically instantiate and manage [Apache Kafka
44

55
Currently, two different Kafka images are supported:
66

7-
* `org.testcontainers.containers.KafkaContainer` supports
7+
* `org.testcontainers.kafka.ConfluentKafkaContainer` supports
88
[confluentinc/cp-kafka](https://hub.docker.com/r/confluentinc/cp-kafka/)
99
* `org.testcontainers.kafka.KafkaContainer` supports [apache/kafka](https://hub.docker.com/r/apache/kafka/) and [apache/kafka-native](https://hub.docker.com/r/apache/kafka-native/)
1010

11+
!!! note
12+
`org.testcontainers.containers.KafkaContainer` is deprecated.
13+
Please use `org.testcontainers.kafka.ConfluentKafkaContainer` or `org.testcontainers.kafka.KafkaContainer` instead, depending on the used image.
14+
1115
## Benefits
1216

1317
* Running a single node Kafka installation with just one line of code
1418
* No need to manage external Zookeeper installation, required by Kafka. But see [below](#zookeeper)
1519

1620
## Example
1721

22+
### Using org.testcontainers.containers.KafkaContainer
23+
1824
Create a `KafkaContainer` to use it in your tests:
25+
1926
<!--codeinclude-->
2027
[Creating a KafkaContainer](../../modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java) inside_block:constructorWithVersion
2128
<!--/codeinclude-->
@@ -28,33 +35,54 @@ Now your tests or any other process running on your machine can get access to ru
2835
[Bootstrap Servers](../../modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java) inside_block:getBootstrapServers
2936
<!--/codeinclude-->
3037

31-
## Options
38+
### Using org.testcontainers.kafka.ConfluentKafkaContainer
39+
40+
!!! note
41+
Compatible with `confluentinc/cp-kafka` images version `7.4.0` and later.
42+
43+
Create a `ConfluentKafkaContainer` to use it in your tests:
44+
45+
<!--codeinclude-->
46+
[Creating a ConlfuentKafkaContainer](../../modules/kafka/src/test/java/org/testcontainers/kafka/ConfluentKafkaContainerTest.java) inside_block:constructorWithVersion
47+
<!--/codeinclude-->
3248

33-
!!! note
34-
The options below are only available for `org.testcontainers.containers.KafkaContainer`
49+
### Using org.testcontainers.kafka.KafkaContainer
50+
51+
Create a `KafkaContainer` to use it in your tests:
52+
53+
<!--codeinclude-->
54+
[Creating a KafkaContainer](../../modules/kafka/src/test/java/org/testcontainers/kafka/KafkaContainerTest.java) inside_block:constructorWithVersion
55+
<!--/codeinclude-->
56+
57+
## Options
3558
3659
### <a name="zookeeper"></a> Using external Zookeeper
3760

61+
!!! note
62+
Only available for `org.testcontainers.containers.KafkaContainer`
63+
3864
If for some reason you want to use an externally running Zookeeper, then just pass its location during construction:
3965
<!--codeinclude-->
4066
[External Zookeeper](../../modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java) inside_block:withExternalZookeeper
4167
<!--/codeinclude-->
4268

4369
### Using Kraft mode
4470

45-
KRaft mode was declared production ready in 3.3.1 (confluentinc/cp-kafka:7.3.x)"
71+
!!! note
72+
Only available for `org.testcontainers.containers.KafkaContainer`
73+
74+
KRaft mode was declared production ready in 3.3.1 (confluentinc/cp-kafka:7.3.x)
4675

4776
<!--codeinclude-->
4877
[Kraft mode](../../modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java) inside_block:withKraftMode
4978
<!--/codeinclude-->
5079

51-
See the [versions interoperability matrix](https://docs.confluent.io/platform/current/installation/versions-interoperability.html) for more details.
80+
See the [versions interoperability matrix](https://docs.confluent.io/platform/current/installation/versions-interoperability.html) for more details.
5281

53-
## Register listeners
82+
### Register listeners
5483

5584
There are scenarios where additional listeners are needed because the consumer/producer can be in another
56-
container in the same network or a different process where the port to connect differs from the default
57-
exposed port `9093`. E.g [Toxiproxy](../../modules/toxiproxy/).
85+
container in the same network or a different process where the port to connect differs from the default exposed port. E.g [Toxiproxy](../../modules/toxiproxy/).
5886

5987
<!--codeinclude-->
6088
[Register additional listener](../../modules/kafka/src/test/java/org/testcontainers/containers/KafkaContainerTest.java) inside_block:registerListener

docs/supported_docker_environment/continuous_integration/gitlab_ci.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ See below for an example runner configuration:
2424
Please also include the following in your GitlabCI pipeline definitions (`.gitlab-ci.yml`) that use Testcontainers:
2525
```yml
2626
variables:
27-
TESTCONTAINERS_HOST_OVERRIDE: "host.docker.internal"
27+
TESTCONTAINERS_HOST_OVERRIDE: "<ip-docker-host>"
2828
```
2929
30-
The environment variable `TESTCONTAINERS_HOST_OVERRIDE` needs to be configured, otherwise, a wrong IP address would be used to resolve the Docker host, which will likely lead to failing tests.
30+
The environment variable `TESTCONTAINERS_HOST_OVERRIDE` needs to be configured, otherwise, a wrong IP address would be used to resolve the Docker host, which will likely lead to failing tests. For Windows and MacOS, use `host.docker.internal`.
3131

3232
## Example using DinD (Docker-in-Docker)
3333

examples/build.gradle

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ subprojects {
1414
mavenCentral()
1515
}
1616

17+
test {
18+
defaultCharacterEncoding = "UTF-8"
19+
testLogging {
20+
displayGranularity 1
21+
showStackTraces = true
22+
exceptionFormat = 'full'
23+
events "STARTED", "PASSED", "FAILED", "SKIPPED"
24+
}
25+
}
26+
1727
checkstyle {
1828
toolVersion = "9.3"
1929
configFile = rootProject.file('../config/checkstyle/checkstyle.xml')

modules/kafka/src/main/java/org/testcontainers/containers/KafkaContainer.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@
2626
* <li>Kafka: 9093</li>
2727
* <li>Zookeeper: 2181</li>
2828
* </ul>
29+
*
30+
* @deprecated use {@link org.testcontainers.kafka.ConfluentKafkaContainer} or
31+
* {@link org.testcontainers.kafka.KafkaContainer} instead
2932
*/
33+
@Deprecated
3034
public class KafkaContainer extends GenericContainer<KafkaContainer> {
3135

3236
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("confluentinc/cp-kafka");
@@ -327,13 +331,7 @@ void withRaft() {
327331
addEnvVar("KAFKA_LISTENERS", kafkaListeners());
328332
addEnvVar("KAFKA_PROCESS_ROLES", "broker,controller");
329333

330-
String firstNetworkAlias = getNetworkAliases().stream().findFirst().orElse(null);
331-
String networkAlias = getNetwork() != null ? firstNetworkAlias : "localhost";
332-
String controllerQuorumVoters = String.format(
333-
"%s@%s:9094",
334-
getEnvVars().get("KAFKA_NODE_ID"),
335-
networkAlias
336-
);
334+
String controllerQuorumVoters = String.format("%s@localhost:9094", getEnvVars().get("KAFKA_NODE_ID"));
337335
this.envVars.computeIfAbsent("KAFKA_CONTROLLER_QUORUM_VOTERS", key -> controllerQuorumVoters);
338336
addEnvVar("KAFKA_CONTROLLER_LISTENER_NAMES", "CONTROLLER");
339337

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package org.testcontainers.kafka;
2+
3+
import com.github.dockerjava.api.command.InspectContainerResponse;
4+
import org.testcontainers.containers.GenericContainer;
5+
import org.testcontainers.images.builder.Transferable;
6+
import org.testcontainers.utility.DockerImageName;
7+
8+
import java.util.ArrayList;
9+
import java.util.HashSet;
10+
import java.util.List;
11+
import java.util.Set;
12+
import java.util.function.Supplier;
13+
14+
/**
15+
* Testcontainers implementation for Confluent Kafka.
16+
* <p>
17+
* Supported image: {@code confluentinc/cp-kafka}
18+
* <p>
19+
* Exposed ports: 9092
20+
*/
21+
public class ConfluentKafkaContainer extends GenericContainer<ConfluentKafkaContainer> {
22+
23+
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("confluentinc/cp-kafka");
24+
25+
private final Set<String> listeners = new HashSet<>();
26+
27+
private final Set<Supplier<String>> advertisedListeners = new HashSet<>();
28+
29+
public ConfluentKafkaContainer(String imageName) {
30+
this(DockerImageName.parse(imageName));
31+
}
32+
33+
public ConfluentKafkaContainer(DockerImageName dockerImageName) {
34+
super(dockerImageName);
35+
dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
36+
37+
withExposedPorts(KafkaHelper.KAFKA_PORT);
38+
withEnv(KafkaHelper.envVars());
39+
40+
withCommand(KafkaHelper.COMMAND);
41+
waitingFor(KafkaHelper.WAIT_STRATEGY);
42+
}
43+
44+
@Override
45+
protected void configure() {
46+
KafkaHelper.resolveListeners(this, this.listeners);
47+
48+
String controllerQuorumVoters = String.format("%s@localhost:9094", getEnvMap().get("KAFKA_NODE_ID"));
49+
withEnv("KAFKA_CONTROLLER_QUORUM_VOTERS", controllerQuorumVoters);
50+
}
51+
52+
@Override
53+
protected void containerIsStarting(InspectContainerResponse containerInfo) {
54+
String brokerAdvertisedListener = String.format(
55+
"BROKER://%s:%s",
56+
containerInfo.getConfig().getHostName(),
57+
"9093"
58+
);
59+
List<String> advertisedListeners = new ArrayList<>();
60+
advertisedListeners.add("PLAINTEXT://" + getBootstrapServers());
61+
advertisedListeners.add(brokerAdvertisedListener);
62+
63+
advertisedListeners.addAll(KafkaHelper.resolveAdvertisedListeners(this.advertisedListeners));
64+
String kafkaAdvertisedListeners = String.join(",", advertisedListeners);
65+
66+
String command = "#!/bin/bash\n";
67+
// exporting KAFKA_ADVERTISED_LISTENERS with the container hostname
68+
command += String.format("export KAFKA_ADVERTISED_LISTENERS=%s\n", kafkaAdvertisedListeners);
69+
70+
command += "/etc/confluent/docker/run \n";
71+
copyFileToContainer(Transferable.of(command, 0777), KafkaHelper.STARTER_SCRIPT);
72+
}
73+
74+
/**
75+
* Add a listener in the format {@code host:port}.
76+
* Host will be included as a network alias.
77+
* <p>
78+
* Use it to register additional connections to the Kafka broker within the same container network.
79+
* <p>
80+
* The listener will be added to the list of default listeners.
81+
* <p>
82+
* Default listeners:
83+
* <ul>
84+
* <li>0.0.0.0:9092</li>
85+
* <li>0.0.0.0:9093</li>
86+
* <li>0.0.0.0:9094</li>
87+
* </ul>
88+
* <p>
89+
* The listener will be added to the list of default advertised listeners.
90+
* <p>
91+
* Default advertised listeners:
92+
* <ul>
93+
* <li>{@code container.getConfig().getHostName():9092}</li>
94+
* <li>{@code container.getHost():container.getMappedPort(9093)}</li>
95+
* </ul>
96+
* @param listener a listener with format {@code host:port}
97+
* @return this {@link ConfluentKafkaContainer} instance
98+
*/
99+
public ConfluentKafkaContainer withListener(String listener) {
100+
this.listeners.add(listener);
101+
this.advertisedListeners.add(() -> listener);
102+
return this;
103+
}
104+
105+
/**
106+
* Add a listener in the format {@code host:port} and a {@link Supplier} for the advertised listener.
107+
* Host from listener will be included as a network alias.
108+
* <p>
109+
* Use it to register additional connections to the Kafka broker from outside the container network
110+
* <p>
111+
* The listener will be added to the list of default listeners.
112+
* <p>
113+
* Default listeners:
114+
* <ul>
115+
* <li>0.0.0.0:9092</li>
116+
* <li>0.0.0.0:9093</li>
117+
* <li>0.0.0.0:9094</li>
118+
* </ul>
119+
* <p>
120+
* The {@link Supplier} will be added to the list of default advertised listeners.
121+
* <p>
122+
* Default advertised listeners:
123+
* <ul>
124+
* <li>{@code container.getConfig().getHostName():9092}</li>
125+
* <li>{@code container.getHost():container.getMappedPort(9093)}</li>
126+
* </ul>
127+
* @param listener a supplier that will provide a listener
128+
* @param advertisedListener a supplier that will provide a listener
129+
* @return this {@link ConfluentKafkaContainer} instance
130+
*/
131+
public ConfluentKafkaContainer withListener(String listener, Supplier<String> advertisedListener) {
132+
this.listeners.add(listener);
133+
this.advertisedListeners.add(advertisedListener);
134+
return this;
135+
}
136+
137+
public String getBootstrapServers() {
138+
return String.format("%s:%s", getHost(), getMappedPort(KafkaHelper.KAFKA_PORT));
139+
}
140+
}

0 commit comments

Comments
 (0)