Examples
TQE Testcontainers Usage Examples
Example 1. Starting a TQE Cluster with One Grpc Node
Let's define a configuration file for the grpc node (simple-grpc.yml):
# metrics port (required)
core_port: 1111
# grpc server address (required)
grpc_listen:
- uri: 'tcp://0.0.0.0:18182'
# Indicate that the node is a publisher (grpc-publisher)
publisher:
enabled: true
# connection settings to Tarantool nodes
tarantool:
user: test-super
pass: test
connections:
# Router addresses
routers:
- "router:3301"
# Indicate that the node is also a consumer (grpc-consumer)
consumer:
enabled: true
tarantool:
user: test-super
pass: test
connections:
# List of storage node addresses for Tarantool
storage:
- "master:3301"
Let's define the configuration for Tarantool nodes (simple-queue.yml):
# Credentials
credentials:
users:
# Required test user
test-super:
password: 'test'
roles: [ super ]
admin:
password: 'secret-cluster-cookie'
roles: [ super ]
replicator:
password: 'secret'
roles: [ replication ]
storage:
roles: [ sharding ]
password: storage
# advertise configs for all nodes
iproto:
advertise:
peer:
login: replicator
sharding:
login: storage
password: storage
roles: [ roles.metrics-export ]
# Define a test queue
roles_cfg:
app.roles.queue:
queues:
- name: test
deduplication_mode: keep_latest
disabled_filters_by: [ sharding_key ]
roles.metrics-export:
http:
- listen: 8081
endpoints:
- format: prometheus
path: '/metrics'
groups:
routers:
replicasets:
r-1:
sharding:
roles: [ router ]
# Required role
roles: [ app.roles.api ]
instances:
router:
iproto:
listen:
- uri: router:3301
storages:
replicasets:
shard-1:
replication:
failover: manual
sharding:
roles: [ storage ]
# Required role
roles: [ app.roles.queue ]
leader: master
instances:
master:
iproto:
listen:
- uri: master:3301
To start a TQE cluster, we'll use the following code:
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.testcontainers.containers.TarantoolContainer;
import org.testcontainers.containers.tqe.GrpcContainer;
import org.testcontainers.containers.tqe.TQECluster;
import org.testcontainers.containers.tqe.TQEClusterImpl;
import org.testcontainers.containers.tqe.configuration.FileTQEConfigurator;
import org.testcontainers.containers.tqe.configuration.TQEConfigurator;
import org.testcontainers.utility.DockerImageName;
public class TestClass {
@Test
public void test() {
final Path grpcConfigPath = Paths.get("path/to/simple-grpc.yml");
final Path queueConfigPath = Paths.get("path/to/simple.queue.yml");
final DockerImageName image = DockerImageName.parse("tqe-image-name:tag");
try (TQEConfigurator configurator =
FileTQEConfigurator.builder(image, queueConfigPath, Collections.singleton(grpcConfigPath));
TQECluster cluster = new TQEClusterImpl(configurator)
) {
cluster.start();
// get grpc nodes
final Map<String, GrpcContainer<?>> grpc = cluster.grpc();
Assertions.assertEquals(1, grpc.size());
// get queue nodes
final Map<String, TarantoolContainer<?>> queue = cluster.queue();
Assertions.assertEquals(1, queue.size());
// restart the cluster
cluster.restart(1, TimeUnit.SECONDS, 1, TimeUnit.SECONDS);
}
}
}
Example 2. Cluster with Separate Nodes (Publisher/Publisher)
We'll use the queue configuration (Tarantool cluster) defined in Example 1. Let's define separate configurations for grpc-consumer and grpc-publisher.
Configuration for grpc-publisher (simple-grpc-publisher.yml):
# metrics port (required)
core_port: 1111
# grpc server address (required)
grpc_listen:
- uri: 'tcp://0.0.0.0:18182'
# Indicate that the node is a publisher (grpc-publisher)
publisher:
enabled: true
# connection settings to Tarantool nodes
tarantool:
user: test-super
pass: test
connections:
# Router addresses
routers:
- "router:3301"
Configuration for grpc-consumer (simple-grpc-consumer.yml):
# metrics port (required)
core_port: 1111
# grpc server address (required)
grpc_listen:
- uri: 'tcp://0.0.0.0:18182'
# Indicate that the node is a consumer (grpc-consumer)
consumer:
enabled: true
tarantool:
user: test-super
pass: test
connections:
# List of storage node addresses for Tarantool
storage:
- "master:3301"
To start the cluster, we'll use the following code:
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.testcontainers.containers.TarantoolContainer;
import org.testcontainers.containers.tqe.GrpcContainer;
import org.testcontainers.containers.tqe.TQECluster;
import org.testcontainers.containers.tqe.TQEClusterImpl;
import org.testcontainers.containers.tqe.configuration.FileTQEConfigurator;
import org.testcontainers.containers.tqe.configuration.TQEConfigurator;
import org.testcontainers.utility.DockerImageName;
public class TestClass {
@Test
public void test() {
final Path publisherConfigPath = Paths.get("path/to/simple-grpc-publisher.yml");
final Path consumerConfigPath = Paths.get("path/to/`simple-grpc-consumer.yml`");
final Path queueConfigPath = Paths.get("path/to/simple.queue.yml");
final DockerImageName image = DockerImageName.parse("tqe-image-name:tag");
try (TQEConfigurator configurator =
FileTQEConfigurator.builder(image, queueConfigPath,
Set.of(publisherConfigPath, consumerConfigPath));
TQECluster cluster = new TQEClusterImpl(configurator)
) {
cluster.start();
// get grpc nodes (separate for publisher and consumer)
final Map<String, GrpcContainer<?>> grpc = cluster.grpc();
Assertions.assertEquals(2, grpc.size());
// get queue nodes
final Map<String, TarantoolContainer<?>> queue = cluster.queue();
Assertions.assertEquals(1, queue.size());
// restart the cluster
cluster.restart(1, TimeUnit.SECONDS, 1, TimeUnit.SECONDS);
}
}
}
Example 3. Manipulating Individual Cluster Nodes
To restart or stop individual nodes, you can use the following code:
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import org.testcontainers.containers.tarantool.TarantoolContainer;
import org.testcontainers.containers.tqe.GrpcContainer;
import org.testcontainers.containers.tqe.TQECluster;
import org.testcontainers.containers.tqe.TQEClusterImpl;
import org.testcontainers.containers.tqe.configuration.FileTQEConfigurator;
import org.testcontainers.containers.tqe.configuration.TQEConfigurator;
import org.testcontainers.lifecycle.Startable;
import org.testcontainers.utility.DockerImageName;
public class TestClass {
@Test
public void test() {
final Path publisherConfigPath = Paths.get("path/to/simple-grpc-publisher.yml");
final Path consumerConfigPath = Paths.get("path/to/`simple-grpc-consumer.yml`");
final Path queueConfigPath = Paths.get("path/to/simple.queue.yml");
final DockerImageName image = DockerImageName.parse("tqe-image-name:tag");
try (TQEConfigurator configurator =
FileTQEConfigurator.builder(image, queueConfigPath,
Set.of(publisherConfigPath, consumerConfigPath));
TQECluster cluster = new TQEClusterImpl(configurator)
) {
cluster.start();
// get grpc nodes (separate for publisher and consumer)
final Map<String, GrpcContainer<?>> grpc = cluster.grpc();
// Stop all grpc nodes
grpc.values().parallelStream().forEach(Startable::stop);
// Start them again
grpc.values().parallelStream().forEach(Startable::start);
// get queue nodes
final Map<String, TarantoolContainer<?>> queue = cluster.queue();
// Stop nodes with state preservation
queue.values().parallelStream().forEach(TarantoolContainer::stopWithSafeMount);
// Start them again
queue.values().parallelStream().forEach(TarantoolContainer::start);
}
}
}