Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ body:
- MongoDB
- MSSQLServer
- MySQL
- NATS
- Neo4j
- NGINX
- OceanBase
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/enhancement.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ body:
- MongoDB
- MSSQLServer
- MySQL
- NATS
- Neo4j
- NGINX
- OceanBase
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/feature.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ body:
- MongoDB
- MSSQLServer
- MySQL
- NATS
- Neo4j
- NGINX
- OceanBase
Expand Down
5 changes: 5 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ updates:
schedule:
interval: "monthly"
open-pull-requests-limit: 10
- package-ecosystem: "gradle"
directory: "/modules/nats"
schedule:
interval: "monthly"
open-pull-requests-limit: 10
- package-ecosystem: "gradle"
directory: "/modules/neo4j"
schedule:
Expand Down
4 changes: 4 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@
- changed-files:
- any-glob-to-any-file:
- modules/mysql/**/*
"modules/nats":
- changed-files:
- any-glob-to-any-file:
- modules/nats/**/*
"modules/neo4j":
- changed-files:
- any-glob-to-any-file:
Expand Down
74 changes: 74 additions & 0 deletions docs/modules/nats.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# NATS Module

!!! note
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.

[NATS](https://nats.io) is a simple, secure and high performance open source messaging system for cloud native applications, IoT messaging, and microservices architectures.

## Example

Create a `NatsContainer` to use it in your tests:

<!--codeinclude-->
[Creating a NatsContainer](../../modules/nats/src/test/java/org/testcontainers/nats/NatsContainerTest.java) inside_block:shouldStartNatsContainer
<!--/codeinclude-->

Now your tests can connect to NATS using the connection URL:

<!--codeinclude-->
[Connecting to NATS](../../modules/nats/src/test/java/org/testcontainers/nats/NatsContainerTest.java) inside_block:shouldPublishAndSubscribeMessages
<!--/codeinclude-->

## Options

### Using JetStream

JetStream is NATS' built-in distributed persistence system. You can enable it easily:

<!--codeinclude-->
[Enabling JetStream](../../modules/nats/src/test/java/org/testcontainers/nats/NatsContainerTest.java) inside_block:shouldSupportJetStream
<!--/codeinclude-->

### Using Authentication

You can configure NATS to require username and password authentication:

<!--codeinclude-->
[Using Authentication](../../modules/nats/src/test/java/org/testcontainers/nats/NatsContainerTest.java) inside_block:shouldSupportAuthentication
<!--/codeinclude-->

### Enabling Debug/Trace Logging

For debugging purposes, you can enable verbose logging:

```java
NatsContainer nats = new NatsContainer(DockerImageName.parse("nats:2.10"))
.withDebug() // Enable debug logging
.withProtocolTracing(); // Enable protocol tracing
```

## Accessing Monitoring

NATS provides an HTTP monitoring endpoint that you can access:

```java
String httpMonitoringUrl = natsContainer.getHttpMonitoringUrl();
```

## Adding this module to your project dependencies

Add the following dependency to your `pom.xml`/`build.gradle` file:

=== "Gradle"
```groovy
testImplementation "org.testcontainers:testcontainers-nats:{{latest_version}}"
```
=== "Maven"
```xml
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-nats</artifactId>
<version>{{latest_version}}</version>
<scope>test</scope>
</dependency>
```
7 changes: 7 additions & 0 deletions modules/nats/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
description = "Testcontainers :: NATS"

dependencies {
api project(':testcontainers')

testImplementation 'io.nats:jnats:2.24.0'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package org.testcontainers.nats;

import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName;

/**
* Testcontainers implementation for NATS.
* <p>
* Supported image: {@code nats}
* <p>
* Exposed ports:
* <ul>
* <li>4222 (Client connections)</li>
* <li>6222 (Cluster/Route connections)</li>
* <li>8222 (HTTP management/monitoring)</li>
* </ul>
*/
public class NatsContainer extends GenericContainer<NatsContainer> {

/**
* Default port for NATS client connections.
*/
public static final int DEFAULT_NATS_CLIENT_PORT = 4222;

/**
* Default port for NATS cluster/route connections.
*/
public static final int DEFAULT_NATS_ROUTING_PORT = 6222;

/**
* Default port for NATS HTTP monitoring.
*/
public static final int DEFAULT_NATS_HTTP_MONITORING_PORT = 8222;

private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("nats");

/**
* Creates a NATS container using a specific docker image name.
*
* @param dockerImageName The docker image to use.
*/
public NatsContainer(String dockerImageName) {
this(DockerImageName.parse(dockerImageName));
}

/**
* Creates a NATS container using a specific docker image.
*
* @param dockerImageName The docker image to use.
*/
public NatsContainer(DockerImageName dockerImageName) {
super(dockerImageName);
dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);

withExposedPorts(
DEFAULT_NATS_CLIENT_PORT,
DEFAULT_NATS_ROUTING_PORT,
DEFAULT_NATS_HTTP_MONITORING_PORT);
waitingFor(Wait.forLogMessage(".*Server is ready.*", 1));
}

/**
* Gets the port for client connections.
*
* @return The mapped port for client connections.
*/
public Integer getClientPort() {
return getMappedPort(DEFAULT_NATS_CLIENT_PORT);
}

/**
* Gets the port for cluster/route connections.
*
* @return The mapped port for routing connections.
*/
public Integer getRoutingPort() {
return getMappedPort(DEFAULT_NATS_ROUTING_PORT);
}

/**
* Gets the port for HTTP monitoring.
*
* @return The mapped port for HTTP monitoring.
*/
public Integer getHttpMonitoringPort() {
return getMappedPort(DEFAULT_NATS_HTTP_MONITORING_PORT);
}

/**
* Gets the NATS connection URL.
*
* @return NATS URL for client connections in the format nats://host:port
*/
public String getConnectionUrl() {
return String.format("nats://%s:%d", getHost(), getClientPort());
}

/**
* Gets the NATS monitoring endpoint URL.
*
* @return HTTP URL for monitoring endpoint in the format http://host:port
*/
public String getHttpMonitoringUrl() {
return String.format("http://%s:%d", getHost(), getHttpMonitoringPort());
}

/**
* Enables JetStream for the NATS server.
*
* @return This container instance
*/
public NatsContainer withJetStream() {
withCommand("--jetstream");
return this;
}

/**
* Configures authentication with username and password.
*
* @param username The username for authentication
* @param password The password for authentication
* @return This container instance
*/
public NatsContainer withAuth(String username, String password) {
withCommand("--user", username, "--pass", password);
return this;
}

/**
* Enables debug logging for the NATS server.
*
* @return This container instance
*/
public NatsContainer withDebug() {
withCommand("-D");
return this;
}

/**
* Enables protocol tracing for the NATS server.
*
* @return This container instance
*/
public NatsContainer withProtocolTracing() {
withCommand("-V");
return this;
}
}
Loading