Skip to content

Commit 923aebc

Browse files
Add NATS module
1 parent 3fe0976 commit 923aebc

File tree

9 files changed

+400
-0
lines changed

9 files changed

+400
-0
lines changed

.github/ISSUE_TEMPLATE/bug_report.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ body:
4343
- MongoDB
4444
- MSSQLServer
4545
- MySQL
46+
- NATS
4647
- Neo4j
4748
- NGINX
4849
- OceanBase

.github/ISSUE_TEMPLATE/enhancement.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ body:
4343
- MongoDB
4444
- MSSQLServer
4545
- MySQL
46+
- NATS
4647
- Neo4j
4748
- NGINX
4849
- OceanBase

.github/ISSUE_TEMPLATE/feature.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ body:
4343
- MongoDB
4444
- MSSQLServer
4545
- MySQL
46+
- NATS
4647
- Neo4j
4748
- NGINX
4849
- OceanBase

.github/dependabot.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,11 @@ updates:
229229
schedule:
230230
interval: "monthly"
231231
open-pull-requests-limit: 10
232+
- package-ecosystem: "gradle"
233+
directory: "/modules/nats"
234+
schedule:
235+
interval: "monthly"
236+
open-pull-requests-limit: 10
232237
- package-ecosystem: "gradle"
233238
directory: "/modules/neo4j"
234239
schedule:

.github/labeler.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@
143143
- changed-files:
144144
- any-glob-to-any-file:
145145
- modules/mysql/**/*
146+
"modules/nats":
147+
- changed-files:
148+
- any-glob-to-any-file:
149+
- modules/nats/**/*
146150
"modules/neo4j":
147151
- changed-files:
148152
- any-glob-to-any-file:

docs/modules/nats.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# NATS Module
2+
3+
!!! note
4+
This module is INCUBATING. While it is ready for use and operational in the current version of Testcontainers, it is possible that it may receive breaking changes in the future. See [our contributing guidelines](/contributing/#incubating-modules) for more information on our incubating modules policy.
5+
6+
[NATS](https://nats.io) is a simple, secure and high performance open source messaging system for cloud native applications, IoT messaging, and microservices architectures.
7+
8+
## Example
9+
10+
Create a `NatsContainer` to use it in your tests:
11+
12+
<!--codeinclude-->
13+
[Creating a NatsContainer](../../modules/nats/src/test/java/org/testcontainers/nats/NatsContainerTest.java) inside_block:shouldStartNatsContainer
14+
<!--/codeinclude-->
15+
16+
Now your tests can connect to NATS using the connection URL:
17+
18+
<!--codeinclude-->
19+
[Connecting to NATS](../../modules/nats/src/test/java/org/testcontainers/nats/NatsContainerTest.java) inside_block:shouldPublishAndSubscribeMessages
20+
<!--/codeinclude-->
21+
22+
## Options
23+
24+
### Using JetStream
25+
26+
JetStream is NATS' built-in distributed persistence system. You can enable it easily:
27+
28+
<!--codeinclude-->
29+
[Enabling JetStream](../../modules/nats/src/test/java/org/testcontainers/nats/NatsContainerTest.java) inside_block:shouldSupportJetStream
30+
<!--/codeinclude-->
31+
32+
### Using Authentication
33+
34+
You can configure NATS to require username and password authentication:
35+
36+
<!--codeinclude-->
37+
[Using Authentication](../../modules/nats/src/test/java/org/testcontainers/nats/NatsContainerTest.java) inside_block:shouldSupportAuthentication
38+
<!--/codeinclude-->
39+
40+
### Enabling Debug/Trace Logging
41+
42+
For debugging purposes, you can enable verbose logging:
43+
44+
```java
45+
NatsContainer nats = new NatsContainer(DockerImageName.parse("nats:2.10"))
46+
.withDebug() // Enable debug logging
47+
.withProtocolTracing(); // Enable protocol tracing
48+
```
49+
50+
## Accessing Monitoring
51+
52+
NATS provides an HTTP monitoring endpoint that you can access:
53+
54+
```java
55+
String httpMonitoringUrl = natsContainer.getHttpMonitoringUrl();
56+
```
57+
58+
## Adding this module to your project dependencies
59+
60+
Add the following dependency to your `pom.xml`/`build.gradle` file:
61+
62+
=== "Gradle"
63+
```groovy
64+
testImplementation "org.testcontainers:testcontainers-nats:{{latest_version}}"
65+
```
66+
=== "Maven"
67+
```xml
68+
<dependency>
69+
<groupId>org.testcontainers</groupId>
70+
<artifactId>testcontainers-nats</artifactId>
71+
<version>{{latest_version}}</version>
72+
<scope>test</scope>
73+
</dependency>
74+
```

modules/nats/build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
description = "Testcontainers :: NATS"
2+
3+
dependencies {
4+
api project(':testcontainers')
5+
6+
testImplementation 'io.nats:jnats:2.24.0'
7+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package org.testcontainers.nats;
2+
3+
import org.testcontainers.containers.GenericContainer;
4+
import org.testcontainers.containers.wait.strategy.Wait;
5+
import org.testcontainers.utility.DockerImageName;
6+
7+
/**
8+
* Testcontainers implementation for NATS.
9+
* <p>
10+
* Supported image: {@code nats}
11+
* <p>
12+
* Exposed ports:
13+
* <ul>
14+
* <li>4222 (Client connections)</li>
15+
* <li>6222 (Cluster/Route connections)</li>
16+
* <li>8222 (HTTP management/monitoring)</li>
17+
* </ul>
18+
*/
19+
public class NatsContainer extends GenericContainer<NatsContainer> {
20+
21+
/**
22+
* Default port for NATS client connections.
23+
*/
24+
public static final int DEFAULT_NATS_CLIENT_PORT = 4222;
25+
26+
/**
27+
* Default port for NATS cluster/route connections.
28+
*/
29+
public static final int DEFAULT_NATS_ROUTING_PORT = 6222;
30+
31+
/**
32+
* Default port for NATS HTTP monitoring.
33+
*/
34+
public static final int DEFAULT_NATS_HTTP_MONITORING_PORT = 8222;
35+
36+
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("nats");
37+
38+
/**
39+
* Creates a NATS container using a specific docker image name.
40+
*
41+
* @param dockerImageName The docker image to use.
42+
*/
43+
public NatsContainer(String dockerImageName) {
44+
this(DockerImageName.parse(dockerImageName));
45+
}
46+
47+
/**
48+
* Creates a NATS container using a specific docker image.
49+
*
50+
* @param dockerImageName The docker image to use.
51+
*/
52+
public NatsContainer(DockerImageName dockerImageName) {
53+
super(dockerImageName);
54+
dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
55+
56+
withExposedPorts(
57+
DEFAULT_NATS_CLIENT_PORT,
58+
DEFAULT_NATS_ROUTING_PORT,
59+
DEFAULT_NATS_HTTP_MONITORING_PORT);
60+
waitingFor(Wait.forLogMessage(".*Server is ready.*", 1));
61+
}
62+
63+
/**
64+
* Gets the port for client connections.
65+
*
66+
* @return The mapped port for client connections.
67+
*/
68+
public Integer getClientPort() {
69+
return getMappedPort(DEFAULT_NATS_CLIENT_PORT);
70+
}
71+
72+
/**
73+
* Gets the port for cluster/route connections.
74+
*
75+
* @return The mapped port for routing connections.
76+
*/
77+
public Integer getRoutingPort() {
78+
return getMappedPort(DEFAULT_NATS_ROUTING_PORT);
79+
}
80+
81+
/**
82+
* Gets the port for HTTP monitoring.
83+
*
84+
* @return The mapped port for HTTP monitoring.
85+
*/
86+
public Integer getHttpMonitoringPort() {
87+
return getMappedPort(DEFAULT_NATS_HTTP_MONITORING_PORT);
88+
}
89+
90+
/**
91+
* Gets the NATS connection URL.
92+
*
93+
* @return NATS URL for client connections in the format nats://host:port
94+
*/
95+
public String getConnectionUrl() {
96+
return String.format("nats://%s:%d", getHost(), getClientPort());
97+
}
98+
99+
/**
100+
* Gets the NATS monitoring endpoint URL.
101+
*
102+
* @return HTTP URL for monitoring endpoint in the format http://host:port
103+
*/
104+
public String getHttpMonitoringUrl() {
105+
return String.format("http://%s:%d", getHost(), getHttpMonitoringPort());
106+
}
107+
108+
/**
109+
* Enables JetStream for the NATS server.
110+
*
111+
* @return This container instance
112+
*/
113+
public NatsContainer withJetStream() {
114+
withCommand("--jetstream");
115+
return this;
116+
}
117+
118+
/**
119+
* Configures authentication with username and password.
120+
*
121+
* @param username The username for authentication
122+
* @param password The password for authentication
123+
* @return This container instance
124+
*/
125+
public NatsContainer withAuth(String username, String password) {
126+
withCommand("--user", username, "--pass", password);
127+
return this;
128+
}
129+
130+
/**
131+
* Enables debug logging for the NATS server.
132+
*
133+
* @return This container instance
134+
*/
135+
public NatsContainer withDebug() {
136+
withCommand("-D");
137+
return this;
138+
}
139+
140+
/**
141+
* Enables protocol tracing for the NATS server.
142+
*
143+
* @return This container instance
144+
*/
145+
public NatsContainer withProtocolTracing() {
146+
withCommand("-V");
147+
return this;
148+
}
149+
}

0 commit comments

Comments
 (0)