Browse Source

Merge pull request #12925 from smatvienko-tb/feature/valkey

ValKey 8.0 (alternative to Redis > 7.2)
pull/13474/head
Viacheslav Klimov 1 year ago
committed by GitHub
parent
commit
4f804629fa
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 41
      dao/src/test/java/org/thingsboard/server/dao/AbstractRedisClusterContainer.java
  2. 5
      dao/src/test/java/org/thingsboard/server/dao/AbstractRedisContainer.java
  3. 2
      dao/src/test/java/org/thingsboard/server/dao/RedisClusterSqlTestSuite.java
  4. 3
      dao/src/test/java/org/thingsboard/server/dao/RedisJUnit5Test.java
  5. 4
      docker/.env
  6. 20
      docker/.gitignore
  7. 8
      docker/README.md
  8. 5
      docker/cache-redis-cluster.env
  9. 2
      docker/cache-redis.env
  10. 5
      docker/cache-valkey-cluster.env
  11. 4
      docker/cache-valkey-sentinel.env
  12. 2
      docker/cache-valkey.env
  13. 62
      docker/compose-utils.sh
  14. 58
      docker/docker-compose.redis-cluster.volumes.yml
  15. 157
      docker/docker-compose.redis-cluster.yml
  16. 120
      docker/docker-compose.redis-sentinel.yml
  17. 58
      docker/docker-compose.valkey-cluster.volumes.yml
  18. 152
      docker/docker-compose.valkey-cluster.yml
  19. 26
      docker/docker-compose.valkey-sentinel.volumes.yml
  20. 120
      docker/docker-compose.valkey-sentinel.yml
  21. 8
      docker/docker-compose.valkey.volumes.yml
  22. 64
      docker/docker-compose.valkey.yml
  23. 8
      msa/black-box-tests/README.md
  24. 54
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java
  25. 110
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java
  26. 8
      msa/black-box-tests/src/test/resources/docker-compose.valkey-ssl.volumes.yml
  27. 102
      msa/black-box-tests/src/test/resources/docker-compose.valkey-ssl.yml
  28. 28
      msa/black-box-tests/src/test/resources/redis-certs/redis.crt
  29. 28
      msa/black-box-tests/src/test/resources/redis-certs/redis.key
  30. 32
      msa/black-box-tests/src/test/resources/redis-certs/redisCA.crt
  31. 9
      msa/black-box-tests/src/test/resources/valkey-certs/valkey.crt
  32. 8
      msa/black-box-tests/src/test/resources/valkey-certs/valkey.key
  33. 11
      msa/black-box-tests/src/test/resources/valkey-certs/valkeyCA.crt

41
dao/src/test/java/org/thingsboard/server/dao/AbstractRedisClusterContainer.java

@ -16,6 +16,7 @@
package org.thingsboard.server.dao;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.api.Assertions;
import org.junit.ClassRule;
import org.junit.rules.ExternalResource;
import org.testcontainers.containers.GenericContainer;
@ -23,27 +24,33 @@ import org.testcontainers.containers.Network;
import org.testcontainers.containers.output.OutputFrame;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Slf4j
public class AbstractRedisClusterContainer {
static final String nodes = "127.0.0.1:6371,127.0.0.1:6372,127.0.0.1:6373,127.0.0.1:6374,127.0.0.1:6375,127.0.0.1:6376";
static final String NODES = "127.0.0.1:6371,127.0.0.1:6372,127.0.0.1:6373,127.0.0.1:6374,127.0.0.1:6375,127.0.0.1:6376";
static final String IMAGE = "bitnami/valkey-cluster:8.0";
static final Map<String,String> ENVS = Map.of(
"VALKEY_CLUSTER_ANNOUNCE_IP", "127.0.0.1",
"VALKEY_CLUSTER_DYNAMIC_IPS", "no",
"ALLOW_EMPTY_PASSWORD", "yes",
"VALKEY_NODES", NODES
);
@ClassRule(order = 0)
public static Network network = Network.newNetwork();
@ClassRule(order = 1)
public static GenericContainer redis1 = new GenericContainer("bitnami/redis-cluster:latest").withEnv("REDIS_PORT_NUMBER", "6371").withNetworkMode("host").withLogConsumer(x -> log.warn("{}", ((OutputFrame) x).getUtf8StringWithoutLineEnding())).withEnv("ALLOW_EMPTY_PASSWORD", "yes").withEnv("REDIS_NODES", nodes);
public static GenericContainer redis1 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6371").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog);
@ClassRule(order = 2)
public static GenericContainer redis2 = new GenericContainer("bitnami/redis-cluster:latest").withEnv("REDIS_PORT_NUMBER", "6372").withNetworkMode("host").withLogConsumer(x -> log.warn("{}", ((OutputFrame) x).getUtf8StringWithoutLineEnding())).withEnv("ALLOW_EMPTY_PASSWORD", "yes").withEnv("REDIS_NODES", nodes);
public static GenericContainer redis2 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6372").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog);
@ClassRule(order = 3)
public static GenericContainer redis3 = new GenericContainer("bitnami/redis-cluster:latest").withEnv("REDIS_PORT_NUMBER", "6373").withNetworkMode("host").withLogConsumer(x -> log.warn("{}", ((OutputFrame) x).getUtf8StringWithoutLineEnding())).withEnv("ALLOW_EMPTY_PASSWORD", "yes").withEnv("REDIS_NODES", nodes);
public static GenericContainer redis3 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6373").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog);
@ClassRule(order = 4)
public static GenericContainer redis4 = new GenericContainer("bitnami/redis-cluster:latest").withEnv("REDIS_PORT_NUMBER", "6374").withNetworkMode("host").withLogConsumer(x -> log.warn("{}", ((OutputFrame) x).getUtf8StringWithoutLineEnding())).withEnv("ALLOW_EMPTY_PASSWORD", "yes").withEnv("REDIS_NODES", nodes);
public static GenericContainer redis4 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6374").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog);
@ClassRule(order = 5)
public static GenericContainer redis5 = new GenericContainer("bitnami/redis-cluster:latest").withEnv("REDIS_PORT_NUMBER", "6375").withNetworkMode("host").withLogConsumer(x -> log.warn("{}", ((OutputFrame) x).getUtf8StringWithoutLineEnding())).withEnv("ALLOW_EMPTY_PASSWORD", "yes").withEnv("REDIS_NODES", nodes);
public static GenericContainer redis5 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6375").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog);
@ClassRule(order = 6)
public static GenericContainer redis6 = new GenericContainer("bitnami/redis-cluster:latest").withEnv("REDIS_PORT_NUMBER", "6376").withNetworkMode("host").withLogConsumer(x -> log.warn("{}", ((OutputFrame) x).getUtf8StringWithoutLineEnding())).withEnv("ALLOW_EMPTY_PASSWORD", "yes").withEnv("REDIS_NODES", nodes);
public static GenericContainer redis6 = new GenericContainer(IMAGE).withEnv(ENVS).withEnv("VALKEY_PORT_NUMBER", "6376").withNetworkMode("host").withLogConsumer(AbstractRedisClusterContainer::consumeLog);
@ClassRule(order = 100)
@ -59,19 +66,18 @@ public class AbstractRedisClusterContainer {
Thread.sleep(TimeUnit.SECONDS.toMillis(5)); // otherwise not all containers have time to start
String clusterCreateCommand = "echo yes | redis-cli --cluster create " +
"127.0.0.1:6371 127.0.0.1:6372 127.0.0.1:6373 127.0.0.1:6374 127.0.0.1:6375 127.0.0.1:6376 " +
"--cluster-replicas 1";
log.warn("Command to init Redis Cluster: {}", clusterCreateCommand);
String clusterCreateCommand = "valkey-cli --cluster create " + NODES.replace(","," ") + " --cluster-replicas 1 --cluster-yes";
log.warn("Command to init ValKey Cluster: {}", clusterCreateCommand);
var result = redis6.execInContainer("/bin/sh", "-c", clusterCreateCommand);
log.warn("Init cluster result: {}", result);
Assertions.assertThat(result.getExitCode()).isEqualTo(0);
Thread.sleep(TimeUnit.SECONDS.toMillis(5)); // otherwise cluster not always ready
log.warn("Connect to nodes: {}", nodes);
log.warn("Connect to nodes: {}", NODES);
System.setProperty("cache.type", "redis");
System.setProperty("redis.connection.type", "cluster");
System.setProperty("redis.cluster.nodes", nodes);
System.setProperty("redis.cluster.nodes", NODES);
System.setProperty("redis.cluster.useDefaultPoolConfig", "false");
}
@ -83,9 +89,12 @@ public class AbstractRedisClusterContainer {
redis4.stop();
redis5.stop();
redis6.stop();
List.of("cache.type", "redis.connection.type", "redis.cluster.nodes", "redis.cluster.useDefaultPoolConfig\"")
List.of("cache.type", "redis.connection.type", "redis.cluster.nodes", "redis.cluster.useDefaultPoolConfig")
.forEach(System.getProperties()::remove);
}
};
private static void consumeLog(Object x) {
log.warn("{}", ((OutputFrame) x).getUtf8StringWithoutLineEnding());
}
}

5
dao/src/test/java/org/thingsboard/server/dao/AbstractRedisContainer.java

@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
import org.junit.ClassRule;
import org.junit.rules.ExternalResource;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.OutputFrame;
import java.util.List;
@ -26,7 +27,9 @@ import java.util.List;
public class AbstractRedisContainer {
@ClassRule(order = 0)
public static GenericContainer redis = new GenericContainer("redis:7.2")
public static GenericContainer redis = new GenericContainer("bitnami/valkey:8.0")
.withEnv("ALLOW_EMPTY_PASSWORD","yes")
.withLogConsumer(s -> log.warn(((OutputFrame) s).getUtf8String().trim()))
.withExposedPorts(6379);
@ClassRule(order = 1)

2
dao/src/test/java/org/thingsboard/server/dao/RedisClusterSqlTestSuite.java

@ -21,7 +21,7 @@ import org.junit.runner.RunWith;
@RunWith(ClasspathSuite.class)
@ClassnameFilters(
//All the same tests using redis instead of caffeine.
//All the same tests using ValKey instead of caffeine.
{
"org.thingsboard.server.dao.service.*ServiceSqlTest",
}

3
dao/src/test/java/org/thingsboard/server/dao/RedisJUnit5Test.java

@ -33,7 +33,8 @@ import static org.assertj.core.api.Assertions.assertThat;
public class RedisJUnit5Test {
@Container
private static final GenericContainer REDIS = new GenericContainer("redis:7.2-bookworm")
private static final GenericContainer REDIS = new GenericContainer("bitnami/valkey:8.0")
.withEnv("ALLOW_EMPTY_PASSWORD","yes")
.withLogConsumer(s -> log.error(((OutputFrame) s).getUtf8String().trim()))
.withExposedPorts(6379);

4
docker/.env

@ -1,7 +1,7 @@
TB_QUEUE_TYPE=kafka
# redis or redis-cluster or redis-sentinel
CACHE=redis
# valkey or valkey-cluster or valkey-sentinel
CACHE=valkey
DOCKER_REPO=thingsboard

20
docker/.gitignore

@ -6,15 +6,15 @@ tb-node/postgres/**
tb-node/cassandra/**
tb-transports/*/log
tb-vc-executor/log/**
tb-node/redis-cluster-data-0/**
tb-node/redis-cluster-data-1/**
tb-node/redis-cluster-data-2/**
tb-node/redis-cluster-data-3/**
tb-node/redis-cluster-data-4/**
tb-node/redis-cluster-data-5/**
tb-node/redis-sentinel-data-master/**
tb-node/redis-sentinel-data-slave/**
tb-node/redis-sentinel-data-sentinel/**
tb-node/redis-data/**
tb-node/valkey-cluster-data-0/**
tb-node/valkey-cluster-data-1/**
tb-node/valkey-cluster-data-2/**
tb-node/valkey-cluster-data-3/**
tb-node/valkey-cluster-data-4/**
tb-node/valkey-cluster-data-5/**
tb-node/valkey-sentinel-data-primary/**
tb-node/valkey-sentinel-data-replica/**
tb-node/valkey-sentinel-data-sentinel/**
tb-node/valkey-data/**
!.env

8
docker/README.md

@ -19,11 +19,11 @@ In order to set database type change the value of `DATABASE` variable in `.env`
In order to set cache type change the value of `CACHE` variable in `.env` file to one of the following:
- `redis` - use Redis standalone cache (1 node - 1 master);
- `redis-cluster` - use Redis cluster cache (6 nodes - 3 masters, 3 slaves);
- `redis-sentinel` - use Redis sentinel cache (3 nodes - 1 master, 1 slave, 1 sentinel)
- `valkey` - use Valkey standalone cache (1 node - 1 primary);
- `valkey-cluster` - use Valkey cluster cache (6 nodes - 3 primaries, 3 replicas);
- `valkey-sentinel` - use Valkey sentinel cache (3 nodes - 1 primary, 1 replica, 1 sentinel)
**NOTE**: According to the cache type corresponding docker service will be deployed (see `docker-compose.redis.yml`, `docker-compose.redis-cluster.yml`, `docker-compose.redis-sentinel.yml` for details).
**NOTE**: According to the cache type corresponding docker service will be deployed (see `docker-compose.valkey.yml`, `docker-compose.valkey-cluster.yml`, `docker-compose.valkey-sentinel.yml` for details).
Execute the following command to create log folders for the services and chown of these folders to the docker container users.
To be able to change user, **chown** command is used, which requires sudo permissions (script will request password for a sudo access):

5
docker/cache-redis-cluster.env

@ -1,5 +0,0 @@
CACHE_TYPE=redis
REDIS_CONNECTION_TYPE=cluster
REDIS_NODES=redis-node-0:6379,redis-node-1:6379,redis-node-2:6379,redis-node-3:6379,redis-node-4:6379,redis-node-5:6379
REDIS_USE_DEFAULT_POOL_CONFIG=false
REDIS_PASSWORD=thingsboard

2
docker/cache-redis.env

@ -1,2 +0,0 @@
CACHE_TYPE=redis
REDIS_HOST=redis

5
docker/cache-valkey-cluster.env

@ -0,0 +1,5 @@
CACHE_TYPE=redis
REDIS_CONNECTION_TYPE=cluster
REDIS_NODES=valkey-node-0:6379,valkey-node-1:6379,valkey-node-2:6379,valkey-node-3:6379,valkey-node-4:6379,valkey-node-5:6379
REDIS_USE_DEFAULT_POOL_CONFIG=false
REDIS_PASSWORD=thingsboard

4
docker/cache-redis-sentinel.env → docker/cache-valkey-sentinel.env

@ -1,7 +1,7 @@
CACHE_TYPE=redis
REDIS_CONNECTION_TYPE=sentinel
REDIS_MASTER=mymaster
REDIS_SENTINELS=redis-sentinel:26379
REDIS_MASTER=myprimary
REDIS_SENTINELS=valkey-sentinel:26379
REDIS_SENTINEL_PASSWORD=sentinel
REDIS_USE_DEFAULT_POOL_CONFIG=false
REDIS_PASSWORD=thingsboard

2
docker/cache-valkey.env

@ -0,0 +1,2 @@
CACHE_TYPE=redis
REDIS_HOST=valkey

62
docker/compose-utils.sh

@ -64,19 +64,19 @@ function additionalComposeMonitoringArgs() {
function additionalComposeCacheArgs() {
source .env
CACHE_COMPOSE_ARGS=""
CACHE="${CACHE:-redis}"
CACHE="${CACHE:-valkey}"
case $CACHE in
redis)
CACHE_COMPOSE_ARGS="-f docker-compose.redis.yml"
valkey)
CACHE_COMPOSE_ARGS="-f docker-compose.valkey.yml"
;;
redis-cluster)
CACHE_COMPOSE_ARGS="-f docker-compose.redis-cluster.yml"
valkey-cluster)
CACHE_COMPOSE_ARGS="-f docker-compose.valkey-cluster.yml"
;;
redis-sentinel)
CACHE_COMPOSE_ARGS="-f docker-compose.redis-sentinel.yml"
valkey-sentinel)
CACHE_COMPOSE_ARGS="-f docker-compose.valkey-sentinel.yml"
;;
*)
echo "Unknown CACHE value specified in the .env file: '${CACHE}'. Should be either 'redis' or 'redis-cluster' or 'redis-sentinel'." >&2
echo "Unknown CACHE value specified in the .env file: '${CACHE}'. Should be either 'valkey' or 'valkey-cluster' or 'valkey-sentinel'." >&2
exit 1
esac
echo $CACHE_COMPOSE_ARGS
@ -97,19 +97,19 @@ function additionalStartupServices() {
exit 1
esac
CACHE="${CACHE:-redis}"
CACHE="${CACHE:-valkey}"
case $CACHE in
redis)
ADDITIONAL_STARTUP_SERVICES="$ADDITIONAL_STARTUP_SERVICES redis"
valkey)
ADDITIONAL_STARTUP_SERVICES="$ADDITIONAL_STARTUP_SERVICES valkey"
;;
redis-cluster)
ADDITIONAL_STARTUP_SERVICES="$ADDITIONAL_STARTUP_SERVICES redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5"
valkey-cluster)
ADDITIONAL_STARTUP_SERVICES="$ADDITIONAL_STARTUP_SERVICES valkey-node-0 valkey-node-1 valkey-node-2 valkey-node-3 valkey-node-4 valkey-node-5"
;;
redis-sentinel)
ADDITIONAL_STARTUP_SERVICES="$ADDITIONAL_STARTUP_SERVICES redis-master redis-slave redis-sentinel"
valkey-sentinel)
ADDITIONAL_STARTUP_SERVICES="$ADDITIONAL_STARTUP_SERVICES valkey-primary valkey-replica valkey-sentinel"
;;
*)
echo "Unknown CACHE value specified in the .env file: '${CACHE}'. Should be either 'redis' or 'redis-cluster' or 'redis-sentinel'." >&2
echo "Unknown CACHE value specified in the .env file: '${CACHE}'. Should be either 'valkey' or 'valkey-cluster' or 'valkey-sentinel'." >&2
exit 1
esac
@ -154,32 +154,32 @@ function permissionList() {
"
fi
CACHE="${CACHE:-redis}"
CACHE="${CACHE:-valkey}"
case $CACHE in
redis)
valkey)
PERMISSION_LIST="$PERMISSION_LIST
1001 1001 tb-node/redis-data
1001 1001 tb-node/valkey-data
"
;;
redis-cluster)
valkey-cluster)
PERMISSION_LIST="$PERMISSION_LIST
1001 1001 tb-node/redis-cluster-data-0
1001 1001 tb-node/redis-cluster-data-1
1001 1001 tb-node/redis-cluster-data-2
1001 1001 tb-node/redis-cluster-data-3
1001 1001 tb-node/redis-cluster-data-4
1001 1001 tb-node/redis-cluster-data-5
1001 1001 tb-node/valkey-cluster-data-0
1001 1001 tb-node/valkey-cluster-data-1
1001 1001 tb-node/valkey-cluster-data-2
1001 1001 tb-node/valkey-cluster-data-3
1001 1001 tb-node/valkey-cluster-data-4
1001 1001 tb-node/valkey-cluster-data-5
"
;;
redis-sentinel)
valkey-sentinel)
PERMISSION_LIST="$PERMISSION_LIST
1001 1001 tb-node/redis-sentinel-data-master
1001 1001 tb-node/redis-sentinel-data-slave
1001 1001 tb-node/redis-sentinel-data-sentinel
1001 1001 tb-node/valkey-sentinel-data-primary
1001 1001 tb-node/valkey-sentinel-data-replica
1001 1001 tb-node/valkey-sentinel-data-sentinel
"
;;
*)
echo "Unknown CACHE value specified in the .env file: '${CACHE}'. Should be either 'redis' or 'redis-cluster' or 'redis-sentinel'." >&2
echo "Unknown CACHE value specified in the .env file: '${CACHE}'. Should be either 'valkey' or 'valkey-cluster' or 'valkey-sentinel'." >&2
exit 1
esac

58
docker/docker-compose.redis-cluster.volumes.yml

@ -1,58 +0,0 @@
#
# Copyright © 2016-2025 The Thingsboard Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
version: '3.0'
services:
# Redis cluster
redis-node-0:
volumes:
- redis-cluster-data-0:/bitnami/redis/data
redis-node-1:
volumes:
- redis-cluster-data-1:/bitnami/redis/data
redis-node-2:
volumes:
- redis-cluster-data-2:/bitnami/redis/data
redis-node-3:
volumes:
- redis-cluster-data-3:/bitnami/redis/data
redis-node-4:
volumes:
- redis-cluster-data-4:/bitnami/redis/data
redis-node-5:
volumes:
- redis-cluster-data-5:/bitnami/redis/data
volumes:
redis-cluster-data-0:
external:
name: ${REDIS_CLUSTER_DATA_VOLUME_0}
redis-cluster-data-1:
external:
name: ${REDIS_CLUSTER_DATA_VOLUME_1}
redis-cluster-data-2:
external:
name: ${REDIS_CLUSTER_DATA_VOLUME_2}
redis-cluster-data-3:
external:
name: ${REDIS_CLUSTER_DATA_VOLUME_3}
redis-cluster-data-4:
external:
name: ${REDIS_CLUSTER_DATA_VOLUME_4}
redis-cluster-data-5:
external:
name: ${REDIS_CLUSTER_DATA_VOLUME_5}

157
docker/docker-compose.redis-cluster.yml

@ -1,157 +0,0 @@
#
# Copyright © 2016-2025 The Thingsboard Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
version: '3.0'
services:
# Redis cluster
# The latest version of Redis compatible with ThingsBoard is 7.2
redis-node-0:
image: bitnami/redis-cluster:7.2
volumes:
- ./tb-node/redis-cluster-data-0:/bitnami/redis/data
environment:
- 'REDIS_PASSWORD=thingsboard'
- 'REDISCLI_AUTH=thingsboard'
- 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5'
redis-node-1:
image: bitnami/redis-cluster:7.2
volumes:
- ./tb-node/redis-cluster-data-1:/bitnami/redis/data
depends_on:
- redis-node-0
environment:
- 'REDIS_PASSWORD=thingsboard'
- 'REDISCLI_AUTH=thingsboard'
- 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5'
redis-node-2:
image: bitnami/redis-cluster:7.2
volumes:
- ./tb-node/redis-cluster-data-2:/bitnami/redis/data
depends_on:
- redis-node-1
environment:
- 'REDIS_PASSWORD=thingsboard'
- 'REDISCLI_AUTH=thingsboard'
- 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5'
redis-node-3:
image: bitnami/redis-cluster:7.2
volumes:
- ./tb-node/redis-cluster-data-3:/bitnami/redis/data
depends_on:
- redis-node-2
environment:
- 'REDIS_PASSWORD=thingsboard'
- 'REDISCLI_AUTH=thingsboard'
- 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5'
redis-node-4:
image: bitnami/redis-cluster:7.2
volumes:
- ./tb-node/redis-cluster-data-4:/bitnami/redis/data
depends_on:
- redis-node-3
environment:
- 'REDIS_PASSWORD=thingsboard'
- 'REDISCLI_AUTH=thingsboard'
- 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5'
redis-node-5:
image: bitnami/redis-cluster:7.2
volumes:
- ./tb-node/redis-cluster-data-5:/bitnami/redis/data
depends_on:
- redis-node-0
- redis-node-1
- redis-node-2
- redis-node-3
- redis-node-4
environment:
- 'REDIS_PASSWORD=thingsboard'
- 'REDISCLI_AUTH=thingsboard'
- 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5'
- 'REDIS_CLUSTER_REPLICAS=1'
- 'REDIS_CLUSTER_CREATOR=yes'
# ThingsBoard setup to use redis-cluster
tb-core1:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5
tb-core2:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5
tb-rule-engine1:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5
tb-rule-engine2:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5
tb-mqtt-transport1:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5
tb-mqtt-transport2:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5
tb-http-transport1:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5
tb-http-transport2:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5
tb-coap-transport:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5
tb-lwm2m-transport:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5
tb-snmp-transport:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5
tb-vc-executor1:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5
tb-vc-executor2:
env_file:
- cache-redis-cluster.env
depends_on:
- redis-node-5

120
docker/docker-compose.redis-sentinel.yml

@ -1,120 +0,0 @@
#
# Copyright © 2016-2025 The Thingsboard Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
version: '3.0'
services:
# Redis sentinel
# The latest version of Redis compatible with ThingsBoard is 7.2
redis-master:
image: 'bitnami/redis:7.2'
volumes:
- ./tb-node/redis-sentinel-data-master:/bitnami/redis/data
environment:
- 'REDIS_REPLICATION_MODE=master'
- 'REDIS_PASSWORD=thingsboard'
redis-slave:
image: 'bitnami/redis:7.2'
volumes:
- ./tb-node/redis-sentinel-data-slave:/bitnami/redis/data
environment:
- 'REDIS_REPLICATION_MODE=slave'
- 'REDIS_MASTER_HOST=redis-master'
- 'REDIS_MASTER_PASSWORD=thingsboard'
- 'REDIS_PASSWORD=thingsboard'
depends_on:
- redis-master
redis-sentinel:
image: 'bitnami/redis-sentinel:7.2'
volumes:
- ./tb-node/redis-sentinel-data-sentinel:/bitnami/redis/data
environment:
- 'REDIS_MASTER_HOST=redis-master'
- 'REDIS_MASTER_SET=mymaster'
- 'REDIS_SENTINEL_PASSWORD=sentinel'
- 'REDIS_MASTER_PASSWORD=thingsboard'
depends_on:
- redis-master
- redis-slave
# ThingsBoard setup to use redis-sentinel
tb-core1:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel
tb-core2:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel
tb-rule-engine1:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel
tb-rule-engine2:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel
tb-mqtt-transport1:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel
tb-mqtt-transport2:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel
tb-http-transport1:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel
tb-http-transport2:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel
tb-coap-transport:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel
tb-lwm2m-transport:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel
tb-snmp-transport:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel
tb-vc-executor1:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel
tb-vc-executor2:
env_file:
- cache-redis-sentinel.env
depends_on:
- redis-sentinel

58
docker/docker-compose.valkey-cluster.volumes.yml

@ -0,0 +1,58 @@
#
# Copyright © 2016-2025 The Thingsboard Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
version: '3.0'
services:
# Valkey cluster
valkey-node-0:
volumes:
- valkey-cluster-data-0:/bitnami/valkey/data
valkey-node-1:
volumes:
- valkey-cluster-data-1:/bitnami/valkey/data
valkey-node-2:
volumes:
- valkey-cluster-data-2:/bitnami/valkey/data
valkey-node-3:
volumes:
- valkey-cluster-data-3:/bitnami/valkey/data
valkey-node-4:
volumes:
- valkey-cluster-data-4:/bitnami/valkey/data
valkey-node-5:
volumes:
- valkey-cluster-data-5:/bitnami/valkey/data
volumes:
valkey-cluster-data-0:
external:
name: ${VALKEY_CLUSTER_DATA_VOLUME_0}
valkey-cluster-data-1:
external:
name: ${VALKEY_CLUSTER_DATA_VOLUME_1}
valkey-cluster-data-2:
external:
name: ${VALKEY_CLUSTER_DATA_VOLUME_2}
valkey-cluster-data-3:
external:
name: ${VALKEY_CLUSTER_DATA_VOLUME_3}
valkey-cluster-data-4:
external:
name: ${VALKEY_CLUSTER_DATA_VOLUME_4}
valkey-cluster-data-5:
external:
name: ${VALKEY_CLUSTER_DATA_VOLUME_5}

152
docker/docker-compose.valkey-cluster.yml

@ -0,0 +1,152 @@
#
# Copyright © 2016-2025 The Thingsboard Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
version: '3.0'
services:
# Valkey cluster
# The latest version of Valkey compatible with ThingsBoard is 8.0
valkey-node-0:
image: bitnami/valkey-cluster:8.0
volumes:
- ./tb-node/valkey-cluster-data-0:/bitnami/valkey/data
environment:
- 'VALKEY_PASSWORD=thingsboard'
- 'VALKEY_NODES=valkey-node-0 valkey-node-1 valkey-node-2 valkey-node-3 valkey-node-4 valkey-node-5'
valkey-node-1:
image: bitnami/valkey-cluster:8.0
volumes:
- ./tb-node/valkey-cluster-data-1:/bitnami/valkey/data
depends_on:
- valkey-node-0
environment:
- 'VALKEY_PASSWORD=thingsboard'
- 'VALKEY_NODES=valkey-node-0 valkey-node-1 valkey-node-2 valkey-node-3 valkey-node-4 valkey-node-5'
valkey-node-2:
image: bitnami/valkey-cluster:8.0
volumes:
- ./tb-node/valkey-cluster-data-2:/bitnami/valkey/data
depends_on:
- valkey-node-1
environment:
- 'VALKEY_PASSWORD=thingsboard'
- 'VALKEY_NODES=valkey-node-0 valkey-node-1 valkey-node-2 valkey-node-3 valkey-node-4 valkey-node-5'
valkey-node-3:
image: bitnami/valkey-cluster:8.0
volumes:
- ./tb-node/valkey-cluster-data-3:/bitnami/valkey/data
depends_on:
- valkey-node-2
environment:
- 'VALKEY_PASSWORD=thingsboard'
- 'VALKEY_NODES=valkey-node-0 valkey-node-1 valkey-node-2 valkey-node-3 valkey-node-4 valkey-node-5'
valkey-node-4:
image: bitnami/valkey-cluster:8.0
volumes:
- ./tb-node/valkey-cluster-data-4:/bitnami/valkey/data
depends_on:
- valkey-node-3
environment:
- 'VALKEY_PASSWORD=thingsboard'
- 'VALKEY_NODES=valkey-node-0 valkey-node-1 valkey-node-2 valkey-node-3 valkey-node-4 valkey-node-5'
valkey-node-5:
image: bitnami/valkey-cluster:8.0
volumes:
- ./tb-node/valkey-cluster-data-5:/bitnami/valkey/data
depends_on:
- valkey-node-0
- valkey-node-1
- valkey-node-2
- valkey-node-3
- valkey-node-4
environment:
- 'VALKEY_PASSWORD=thingsboard'
- 'REDISCLI_AUTH=thingsboard'
- 'VALKEY_NODES=valkey-node-0 valkey-node-1 valkey-node-2 valkey-node-3 valkey-node-4 valkey-node-5'
- 'VALKEY_CLUSTER_REPLICAS=1'
- 'VALKEY_CLUSTER_CREATOR=yes'
# ThingsBoard setup to use valkey-cluster
tb-core1:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5
tb-core2:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5
tb-rule-engine1:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5
tb-rule-engine2:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5
tb-mqtt-transport1:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5
tb-mqtt-transport2:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5
tb-http-transport1:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5
tb-http-transport2:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5
tb-coap-transport:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5
tb-lwm2m-transport:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5
tb-snmp-transport:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5
tb-vc-executor1:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5
tb-vc-executor2:
env_file:
- cache-valkey-cluster.env
depends_on:
- valkey-node-5

26
docker/docker-compose.redis-sentinel.volumes.yml → docker/docker-compose.valkey-sentinel.volumes.yml

@ -17,24 +17,24 @@
version: '3.0'
services:
# Redis sentinel
redis-master:
# Valkey sentinel
valkey-primary:
volumes:
- redis-sentinel-data-master:/bitnami/redis/data
redis-slave:
- valkey-sentinel-data-primary:/bitnami/valkey/data
valkey-replica:
volumes:
- redis-sentinel-data-slave:/bitnami/redis/data
redis-sentinel:
- valkey-sentinel-data-replica:/bitnami/valkey/data
valkey-sentinel:
volumes:
- redis-sentinel-data-sentinel:/bitnami/redis/data
- valkey-sentinel-data-sentinel:/bitnami/valkey/data
volumes:
redis-sentinel-data-master:
valkey-sentinel-data-primary:
external:
name: ${REDIS_SENTINEL_DATA_VOLUME_MASTER}
redis-sentinel-data-slave:
name: ${VALKEY_SENTINEL_DATA_VOLUME_PRIMARY}
valkey-sentinel-data-replica:
external:
name: ${REDIS_SENTINEL_DATA_VOLUME_SLAVE}
redis-sentinel-data-sentinel:
name: ${VALKEY_SENTINEL_DATA_VOLUME_REPLICA}
valkey-sentinel-data-sentinel:
external:
name: ${REDIS_SENTINEL_DATA_VOLUME_SENTINEL}
name: ${VALKEY_SENTINEL_DATA_VOLUME_SENTINEL}

120
docker/docker-compose.valkey-sentinel.yml

@ -0,0 +1,120 @@
#
# Copyright © 2016-2025 The Thingsboard Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
version: '3.0'
services:
# Valkey sentinel
# The latest version of Valkey compatible with ThingsBoard is 8.0
valkey-primary:
image: 'bitnami/valkey:8.0'
volumes:
- ./tb-node/valkey-sentinel-data-primary:/bitnami/valkey/data
environment:
- 'VALKEY_REPLICATION_MODE=primary'
- 'VALKEY_PASSWORD=thingsboard'
valkey-replica:
image: 'bitnami/valkey:8.0'
volumes:
- ./tb-node/valkey-sentinel-data-replica:/bitnami/valkey/data
environment:
- 'VALKEY_REPLICATION_MODE=replica'
- 'VALKEY_PRIMARY_HOST=valkey-primary'
- 'VALKEY_PRIMARY_PASSWORD=thingsboard'
- 'VALKEY_PASSWORD=thingsboard'
depends_on:
- valkey-primary
valkey-sentinel:
image: 'bitnami/valkey-sentinel:8.0'
volumes:
- ./tb-node/valkey-sentinel-data-sentinel:/bitnami/valkey/data
environment:
- 'VALKEY_PRIMARY_HOST=valkey-primary'
- 'VALKEY_MASTER_SET=myprimary'
- 'VALKEY_SENTINEL_PASSWORD=sentinel'
- 'VALKEY_PRIMARY_PASSWORD=thingsboard'
depends_on:
- valkey-primary
- valkey-replica
# ThingsBoard setup to use valkey-sentinel
tb-core1:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel
tb-core2:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel
tb-rule-engine1:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel
tb-rule-engine2:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel
tb-mqtt-transport1:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel
tb-mqtt-transport2:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel
tb-http-transport1:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel
tb-http-transport2:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel
tb-coap-transport:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel
tb-lwm2m-transport:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel
tb-snmp-transport:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel
tb-vc-executor1:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel
tb-vc-executor2:
env_file:
- cache-valkey-sentinel.env
depends_on:
- valkey-sentinel

8
docker/docker-compose.redis.volumes.yml → docker/docker-compose.valkey.volumes.yml

@ -17,11 +17,11 @@
version: '3.0'
services:
redis:
valkey:
volumes:
- redis-data:/bitnami/redis/data
- valkey-data:/bitnami/valkey/data
volumes:
redis-data:
valkey-data:
external:
name: ${REDIS_DATA_VOLUME}
name: ${VALKEY_DATA_VOLUME}

64
docker/docker-compose.redis.yml → docker/docker-compose.valkey.yml

@ -17,82 +17,82 @@
version: '3.0'
services:
# Redis standalone
# The latest version of Redis compatible with ThingsBoard is 7.2
redis:
# Valkey standalone
# The latest version of Valkey compatible with ThingsBoard is 8.0
valkey:
restart: always
image: bitnami/redis:7.2
image: bitnami/valkey:8.0
environment:
# ALLOW_EMPTY_PASSWORD is recommended only for development.
ALLOW_EMPTY_PASSWORD: "yes"
ports:
- '6379:6379'
volumes:
- ./tb-node/redis-data:/bitnami/redis/data
- ./tb-node/valkey-data:/bitnami/valkey/data
# ThingsBoard setup to use redis-standalone
# ThingsBoard setup to use valkey-standalone
tb-core1:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey
tb-core2:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey
tb-rule-engine1:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey
tb-rule-engine2:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey
tb-mqtt-transport1:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey
tb-mqtt-transport2:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey
tb-http-transport1:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey
tb-http-transport2:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey
tb-coap-transport:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey
tb-lwm2m-transport:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey
tb-snmp-transport:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey
tb-vc-executor1:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey
tb-vc-executor2:
env_file:
- cache-redis.env
- cache-valkey.env
depends_on:
- redis
- valkey

8
msa/black-box-tests/README.md

@ -18,19 +18,19 @@ As result, in REPOSITORY column, next images should be present:
thingsboard/tb-web-ui
thingsboard/tb-js-executor
- Run the black box tests (without ui tests) in the [msa/black-box-tests](../black-box-tests) directory with Redis standalone:
- Run the black box tests (without ui tests) in the [msa/black-box-tests](../black-box-tests) directory with Valkey standalone:
mvn clean install -DblackBoxTests.skip=false
- Run the black box tests (without ui tests) in the [msa/black-box-tests](../black-box-tests) directory with Redis standalone with TLS:
- Run the black box tests (without ui tests) in the [msa/black-box-tests](../black-box-tests) directory with Valkey standalone with TLS:
mvn clean install -DblackBoxTests.skip=false -DblackBoxTests.redisSsl=true
- Run the black box tests in the [msa/black-box-tests](../black-box-tests) directory with Redis cluster:
- Run the black box tests in the [msa/black-box-tests](../black-box-tests) directory with the Valkey cluster:
mvn clean install -DblackBoxTests.skip=false -DblackBoxTests.redisCluster=true
- Run the black box tests in the [msa/black-box-tests](../black-box-tests) directory with Redis sentinel:
- Run the black box tests in the [msa/black-box-tests](../black-box-tests) directory with Valkey sentinel:
mvn clean install -DblackBoxTests.skip=false -DblackBoxTests.redisSentinel=true

54
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java

@ -41,9 +41,9 @@ import static org.testng.Assert.fail;
@Slf4j
public class ContainerTestSuite {
final static boolean IS_REDIS_CLUSTER = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisCluster"));
final static boolean IS_REDIS_SENTINEL = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisSentinel"));
final static boolean IS_REDIS_SSL = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisSsl"));
final static boolean IS_VALKEY_CLUSTER = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisCluster"));
final static boolean IS_VALKEY_SENTINEL = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisSentinel"));
final static boolean IS_VALKEY_SSL = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisSsl"));
final static boolean IS_HYBRID_MODE = Boolean.parseBoolean(System.getProperty("blackBoxTests.hybridMode"));
private static final String SOURCE_DIR = "./../../docker/";
private static final String TB_CORE_LOG_REGEXP = ".*Starting polling for events.*";
@ -80,9 +80,9 @@ public class ContainerTestSuite {
public void start() {
installTb = new ThingsBoardDbInstaller();
installTb.createVolumes();
log.info("System property of blackBoxTests.redisCluster is {}", IS_REDIS_CLUSTER);
log.info("System property of blackBoxTests.redisSentinel is {}", IS_REDIS_SENTINEL);
log.info("System property of blackBoxTests.redisSsl is {}", IS_REDIS_SSL);
log.info("System property of blackBoxTests.redisCluster is {}", IS_VALKEY_CLUSTER);
log.info("System property of blackBoxTests.redisSentinel is {}", IS_VALKEY_SENTINEL);
log.info("System property of blackBoxTests.redisSsl is {}", IS_VALKEY_SSL);
log.info("System property of blackBoxTests.hybridMode is {}", IS_HYBRID_MODE);
boolean skipTailChildContainers = Boolean.parseBoolean(System.getProperty("blackBoxTests.skipTailChildContainers"));
try {
@ -105,10 +105,10 @@ public class ContainerTestSuite {
}
}
if (IS_REDIS_SSL) {
addToFile(targetDir, "cache-redis.env",
if (IS_VALKEY_SSL) {
addToFile(targetDir, "cache-valkey.env",
Map.of("TB_REDIS_SSL_ENABLED", "true",
"TB_REDIS_SSL_PEM_CERT", "/redis/certs/redisCA.crt"));
"TB_REDIS_SSL_PEM_CERT", "/valkey/certs/valkeyCA.crt"));
}
List<File> composeFiles = new ArrayList<>(Arrays.asList(
@ -121,8 +121,8 @@ public class ContainerTestSuite {
new File(targetDir + (IS_HYBRID_MODE ? "docker-compose.hybrid-test-extras.yml" : "docker-compose.postgres-test-extras.yml")),
new File(targetDir + "docker-compose.postgres.volumes.yml"),
new File(targetDir + "docker-compose.kafka.yml"),
new File(targetDir + resolveRedisComposeFile()),
new File(targetDir + resolveRedisComposeVolumesFile()),
new File(targetDir + resolveValkeyComposeFile()),
new File(targetDir + resolveValkeyComposeVolumesFile()),
new File(targetDir + ("docker-selenium.yml"))
));
addToFile(targetDir, "queue-kafka.env", Map.of("TB_QUEUE_PREFIX", "test"));
@ -165,30 +165,30 @@ public class ContainerTestSuite {
}
}
private static String resolveRedisComposeFile() {
if (IS_REDIS_CLUSTER) {
return "docker-compose.redis-cluster.yml";
private static String resolveValkeyComposeFile() {
if (IS_VALKEY_CLUSTER) {
return "docker-compose.valkey-cluster.yml";
}
if (IS_REDIS_SENTINEL) {
return "docker-compose.redis-sentinel.yml";
if (IS_VALKEY_SENTINEL) {
return "docker-compose.valkey-sentinel.yml";
}
if (IS_REDIS_SSL) {
return "docker-compose.redis-ssl.yml";
if (IS_VALKEY_SSL) {
return "docker-compose.valkey-ssl.yml";
}
return "docker-compose.redis.yml";
return "docker-compose.valkey.yml";
}
private static String resolveRedisComposeVolumesFile() {
if (IS_REDIS_CLUSTER) {
return "docker-compose.redis-cluster.volumes.yml";
private static String resolveValkeyComposeVolumesFile() {
if (IS_VALKEY_CLUSTER) {
return "docker-compose.valkey-cluster.volumes.yml";
}
if (IS_REDIS_SENTINEL) {
return "docker-compose.redis-sentinel.volumes.yml";
if (IS_VALKEY_SENTINEL) {
return "docker-compose.valkey-sentinel.volumes.yml";
}
if (IS_REDIS_SSL) {
return "docker-compose.redis-ssl.volumes.yml";
if (IS_VALKEY_SSL) {
return "docker-compose.valkey-ssl.volumes.yml";
}
return "docker-compose.redis.volumes.yml";
return "docker-compose.valkey.volumes.yml";
}
public void stop() {

110
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java

@ -32,15 +32,15 @@ import java.util.stream.IntStream;
@Slf4j
public class ThingsBoardDbInstaller {
final static boolean IS_REDIS_CLUSTER = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisCluster"));
final static boolean IS_REDIS_SENTINEL = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisSentinel"));
final static boolean IS_VALKEY_CLUSTER = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisCluster"));
final static boolean IS_VALKEY_SENTINEL = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisSentinel"));
final static boolean IS_HYBRID_MODE = Boolean.parseBoolean(System.getProperty("blackBoxTests.hybridMode"));
private final static String POSTGRES_DATA_VOLUME = "tb-postgres-test-data-volume";
private final static String CASSANDRA_DATA_VOLUME = "tb-cassandra-test-data-volume";
private final static String REDIS_DATA_VOLUME = "tb-redis-data-volume";
private final static String REDIS_CLUSTER_DATA_VOLUME = "tb-redis-cluster-data-volume";
private final static String REDIS_SENTINEL_DATA_VOLUME = "tb-redis-sentinel-data-volume";
private final static String VALKEY_DATA_VOLUME = "tb-valkey-data-volume";
private final static String VALKEY_CLUSTER_DATA_VOLUME = "tb-valkey-cluster-data-volume";
private final static String VALKEY_SENTINEL_DATA_VOLUME = "tb-valkey-sentinel-data-volume";
private final static String TB_LOG_VOLUME = "tb-log-test-volume";
private final static String TB_COAP_TRANSPORT_LOG_VOLUME = "tb-coap-transport-log-test-volume";
private final static String TB_LWM2M_TRANSPORT_LOG_VOLUME = "tb-lwm2m-transport-log-test-volume";
@ -56,9 +56,9 @@ public class ThingsBoardDbInstaller {
private final String postgresDataVolume;
private final String cassandraDataVolume;
private final String redisDataVolume;
private final String redisClusterDataVolume;
private final String redisSentinelDataVolume;
private final String valkeyDataVolume;
private final String valkeyClusterDataVolume;
private final String valkeySentinelDataVolume;
private final String tbLogVolume;
private final String tbCoapTransportLogVolume;
private final String tbLwm2mTransportLogVolume;
@ -70,8 +70,8 @@ public class ThingsBoardDbInstaller {
private final Map<String, String> env;
public ThingsBoardDbInstaller() {
log.info("System property of blackBoxTests.redisCluster is {}", IS_REDIS_CLUSTER);
log.info("System property of blackBoxTests.redisCluster is {}", IS_REDIS_SENTINEL);
log.info("System property of blackBoxTests.redisCluster is {}", IS_VALKEY_CLUSTER);
log.info("System property of blackBoxTests.redisCluster is {}", IS_VALKEY_SENTINEL);
log.info("System property of blackBoxTests.hybridMode is {}", IS_HYBRID_MODE);
List<File> composeFiles = new ArrayList<>(Arrays.asList(
new File("./../../docker/docker-compose.yml"),
@ -80,8 +80,8 @@ public class ThingsBoardDbInstaller {
? new File("./../../docker/docker-compose.hybrid.yml")
: new File("./../../docker/docker-compose.postgres.yml"),
new File("./../../docker/docker-compose.postgres.volumes.yml"),
resolveRedisComposeFile(),
resolveRedisComposeVolumesFile()
resolveValkeyComposeFile(),
resolveValkeyComposeVolumesFile()
));
if (IS_HYBRID_MODE) {
composeFiles.add(new File("./../../docker/docker-compose.cassandra.volumes.yml"));
@ -95,9 +95,9 @@ public class ThingsBoardDbInstaller {
postgresDataVolume = project + "_" + POSTGRES_DATA_VOLUME;
cassandraDataVolume = project + "_" + CASSANDRA_DATA_VOLUME;
redisDataVolume = project + "_" + REDIS_DATA_VOLUME;
redisClusterDataVolume = project + "_" + REDIS_CLUSTER_DATA_VOLUME;
redisSentinelDataVolume = project + "_" + REDIS_SENTINEL_DATA_VOLUME;
valkeyDataVolume = project + "_" + VALKEY_DATA_VOLUME;
valkeyClusterDataVolume = project + "_" + VALKEY_CLUSTER_DATA_VOLUME;
valkeySentinelDataVolume = project + "_" + VALKEY_SENTINEL_DATA_VOLUME;
tbLogVolume = project + "_" + TB_LOG_VOLUME;
tbCoapTransportLogVolume = project + "_" + TB_COAP_TRANSPORT_LOG_VOLUME;
tbLwm2mTransportLogVolume = project + "_" + TB_LWM2M_TRANSPORT_LOG_VOLUME;
@ -123,38 +123,38 @@ public class ThingsBoardDbInstaller {
env.put("TB_SNMP_TRANSPORT_LOG_VOLUME", tbSnmpTransportLogVolume);
env.put("TB_VC_EXECUTOR_LOG_VOLUME", tbVcExecutorLogVolume);
env.put("TB_EDQS_LOG_VOLUME", tbEdqsLogVolume);
if (IS_REDIS_CLUSTER) {
if (IS_VALKEY_CLUSTER) {
for (int i = 0; i < 6; i++) {
env.put("REDIS_CLUSTER_DATA_VOLUME_" + i, redisClusterDataVolume + '-' + i);
env.put("VALKEY_CLUSTER_DATA_VOLUME_" + i, valkeyClusterDataVolume + '-' + i);
}
} else if (IS_REDIS_SENTINEL) {
env.put("REDIS_SENTINEL_DATA_VOLUME_MASTER", redisSentinelDataVolume + "-" + "master");
env.put("REDIS_SENTINEL_DATA_VOLUME_SLAVE", redisSentinelDataVolume + "-" + "slave");
env.put("REDIS_SENTINEL_DATA_VOLUME_SENTINEL", redisSentinelDataVolume + "-" + "sentinel");
} else if (IS_VALKEY_SENTINEL) {
env.put("VALKEY_SENTINEL_DATA_VOLUME_PRIMARY", valkeySentinelDataVolume + "-" + "primary");
env.put("VALKEY_SENTINEL_DATA_VOLUME_REPLICA", valkeySentinelDataVolume + "-" + "replica");
env.put("VALKEY_SENTINEL_DATA_VOLUME_SENTINEL", valkeySentinelDataVolume + "-" + "sentinel");
} else {
env.put("REDIS_DATA_VOLUME", redisDataVolume);
env.put("VALKEY_DATA_VOLUME", valkeyDataVolume);
}
dockerCompose.withEnv(env);
}
private static File resolveRedisComposeVolumesFile() {
if (IS_REDIS_CLUSTER) {
return new File("./../../docker/docker-compose.redis-cluster.volumes.yml");
private static File resolveValkeyComposeVolumesFile() {
if (IS_VALKEY_CLUSTER) {
return new File("./../../docker/docker-compose.valkey-cluster.volumes.yml");
}
if (IS_REDIS_SENTINEL) {
return new File("./../../docker/docker-compose.redis-sentinel.volumes.yml");
if (IS_VALKEY_SENTINEL) {
return new File("./../../docker/docker-compose.valkey-sentinel.volumes.yml");
}
return new File("./../../docker/docker-compose.redis.volumes.yml");
return new File("./../../docker/docker-compose.valkey.volumes.yml");
}
private static File resolveRedisComposeFile() {
if (IS_REDIS_CLUSTER) {
return new File("./../../docker/docker-compose.redis-cluster.yml");
private static File resolveValkeyComposeFile() {
if (IS_VALKEY_CLUSTER) {
return new File("./../../docker/docker-compose.valkey-cluster.yml");
}
if (IS_REDIS_SENTINEL) {
return new File("./../../docker/docker-compose.redis-sentinel.yml");
if (IS_VALKEY_SENTINEL) {
return new File("./../../docker/docker-compose.valkey-sentinel.yml");
}
return new File("./../../docker/docker-compose.redis.yml");
return new File("./../../docker/docker-compose.valkey.yml");
}
public Map<String, String> getEnv() {
@ -200,27 +200,27 @@ public class ThingsBoardDbInstaller {
if (IS_HYBRID_MODE) {
additionalServices.append(" cassandra");
}
if (IS_REDIS_CLUSTER) {
if (IS_VALKEY_CLUSTER) {
for (int i = 0; i < 6; i++) {
additionalServices.append(" redis-node-").append(i);
dockerCompose.withCommand("volume create " + redisClusterDataVolume + '-' + i);
additionalServices.append(" valkey-node-").append(i);
dockerCompose.withCommand("volume create " + valkeyClusterDataVolume + '-' + i);
dockerCompose.invokeDocker();
}
} else if (IS_REDIS_SENTINEL) {
additionalServices.append(" redis-master");
dockerCompose.withCommand("volume create " + redisSentinelDataVolume + "-" + "master");
} else if (IS_VALKEY_SENTINEL) {
additionalServices.append(" valkey-primary");
dockerCompose.withCommand("volume create " + valkeySentinelDataVolume + "-" + "primary");
dockerCompose.invokeDocker();
additionalServices.append(" redis-slave");
dockerCompose.withCommand("volume create " + redisSentinelDataVolume + '-' + "slave");
additionalServices.append(" valkey-replica");
dockerCompose.withCommand("volume create " + valkeySentinelDataVolume + '-' + "replica");
dockerCompose.invokeDocker();
additionalServices.append(" redis-sentinel");
dockerCompose.withCommand("volume create " + redisSentinelDataVolume + '-' + "sentinel");
additionalServices.append(" valkey-sentinel");
dockerCompose.withCommand("volume create " + valkeySentinelDataVolume + '-' + "sentinel");
dockerCompose.invokeDocker();
} else {
additionalServices.append(" redis");
dockerCompose.withCommand("volume create " + redisDataVolume);
additionalServices.append(" valkey");
dockerCompose.withCommand("volume create " + valkeyDataVolume);
dockerCompose.invokeDocker();
}
@ -261,7 +261,7 @@ public class ThingsBoardDbInstaller {
.add(tbSnmpTransportLogVolume)
.add(tbVcExecutorLogVolume)
.add(tbEdqsLogVolume)
.add(resolveRedisComposeVolumeLog());
.add(resolveValkeyComposeVolumeLog());
if (IS_HYBRID_MODE) {
rmVolumesCommand.add(cassandraDataVolume);
@ -270,16 +270,16 @@ public class ThingsBoardDbInstaller {
dockerCompose.withCommand(rmVolumesCommand.toString());
}
private String resolveRedisComposeVolumeLog() {
if (IS_REDIS_CLUSTER) {
return IntStream.range(0, 6).mapToObj(i -> " " + redisClusterDataVolume + "-" + i).collect(Collectors.joining());
private String resolveValkeyComposeVolumeLog() {
if (IS_VALKEY_CLUSTER) {
return IntStream.range(0, 6).mapToObj(i -> " " + valkeyClusterDataVolume + "-" + i).collect(Collectors.joining());
}
if (IS_REDIS_SENTINEL) {
return redisSentinelDataVolume + "-" + "master " + " " +
redisSentinelDataVolume + "-" + "slave" + " " +
redisSentinelDataVolume + " " + "sentinel";
if (IS_VALKEY_SENTINEL) {
return valkeySentinelDataVolume + "-" + "primary " + " " +
valkeySentinelDataVolume + "-" + "replica" + " " +
valkeySentinelDataVolume + " " + "sentinel";
}
return redisDataVolume;
return valkeyDataVolume;
}
private void copyLogs(String volumeName, String targetDir) {

8
msa/black-box-tests/src/test/resources/docker-compose.redis-ssl.volumes.yml → msa/black-box-tests/src/test/resources/docker-compose.valkey-ssl.volumes.yml

@ -17,11 +17,11 @@
version: '3.0'
services:
redis:
valkey:
volumes:
- redis-data:/bitnami/redis/data
- valkey-data:/bitnami/valkey/data
volumes:
redis-data:
valkey-data:
external:
name: ${REDIS_DATA_VOLUME}
name: ${VALKEY_DATA_VOLUME}

102
msa/black-box-tests/src/test/resources/docker-compose.redis-ssl.yml → msa/black-box-tests/src/test/resources/docker-compose.valkey-ssl.yml

@ -17,114 +17,114 @@
version: '3.0'
services:
# Redis standalone
# The latest version of Redis compatible with ThingsBoard is 7.2
redis:
# Valkey standalone
# The latest version of Valkey compatible with ThingsBoard is 8.0
valkey:
restart: always
image: bitnami/redis:7.2
image: bitnami/valkey:8.0
environment:
# ALLOW_EMPTY_PASSWORD is recommended only for development.
- 'ALLOW_EMPTY_PASSWORD=yes'
- 'REDIS_TLS_ENABLED=yes'
- 'REDIS_TLS_CERT_FILE=/redis/certs/redis.crt'
- 'REDIS_TLS_KEY_FILE=/redis/certs/redis.key'
- 'REDIS_TLS_CA_FILE=/redis/certs/redisCA.crt'
- 'REDIS_TLS_AUTH_CLIENTS=no'
- 'VALKEY_TLS_ENABLED=yes'
- 'VALKEY_TLS_CERT_FILE=/valkey/certs/valkey.crt'
- 'VALKEY_TLS_KEY_FILE=/valkey/certs/valkey.key'
- 'VALKEY_TLS_CA_FILE=/valkey/certs/valkeyCA.crt'
- 'VALKEY_TLS_AUTH_CLIENTS=no'
ports:
- '6379:6379'
volumes:
- ./tb-node/redis-data:/bitnami/redis/data
- ./redis-certs:/redis/certs
- ./tb-node/valkey-data:/bitnami/valkey/data
- ./valkey-certs:/valkey/certs
# ThingsBoard setup to use redis-standalone
# ThingsBoard setup to use valkey-standalone
tb-core1:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey
tb-core2:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey
tb-rule-engine1:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey
tb-rule-engine2:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey
tb-mqtt-transport1:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey
tb-mqtt-transport2:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey
tb-http-transport1:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey
tb-http-transport2:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey
tb-coap-transport:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey
tb-lwm2m-transport:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey
tb-snmp-transport:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey
tb-vc-executor1:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey
tb-vc-executor2:
env_file:
- cache-redis.env
- cache-valkey.env
volumes:
- ./redis-certs:/redis/certs
- ./valkey-certs:/valkey/certs
depends_on:
- redis
- valkey

28
msa/black-box-tests/src/test/resources/redis-certs/redis.crt

@ -1,28 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIE1TCCAr2gAwIBAgIUFdFLz/q0EosJc39HhIac9+XpyRkwDQYJKoZIhvcNAQEL
BQAwWTELMAkGA1UEBhMCdWExDTALBgNVBAgMBGt5aXYxDTALBgNVBAcMBGt5aXYx
CzAJBgNVBAoMAnRiMQswCQYDVQQLDAJ0YjESMBAGA1UEAwwJbG9jYWxob3N0MB4X
DTIzMDkwNDE1NTA0MVoXDTI0MDkwMzE1NTA0MVowYjELMAkGA1UEBhMCQ1IxEzAR
BgNVBAgMCkNoYW5kcmlsbGExEzARBgNVBAcMCkNoYW5kcmlsbGExEjAQBgNVBAMM
CUhPU1RfTkFNRTEVMBMGA1UECgwMTmV3IFJlcHVibGljMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEA+ICaK/aSklkUIih3cl4k4RYJL8rLS68d5JVSxpCQ
8MwuAakdU+ptD0b6X4+CcNtR96UlcO3cR15GLLT6s29Kw4Ta5SME+yhuFLUIrWxA
/gJ/pkJGkq1vXYZzdUFjtMlF+VbIw+r2hhSkbTR1hV08iRlvflafS8JB/tznqTFy
QIXu08heRtxVaC6SMHLeHmZdgdJrSOulwg/ctcP6tki+ZU9v+TH71M3mTIOLzuSz
7sqnFMPgW7ER0Utc4fndRfz17LA1NZdSrN0Ch5IO+EZ9gf/25w8makbx7lZoZASm
sAd0Uyq9ZPC0ok+oJjeDwanl/Bo7CGEgdxaFYNKpnizyUQIDAQABo4GLMIGIMAsG
A1UdDwQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGgYDVR0R
BBMwEYIJbG9jYWxob3N0hwR/AAABMB0GA1UdDgQWBBRAIkMMxT30wZYoNQuDM7uT
qwb+VzAfBgNVHSMEGDAWgBSfpEhvBqWx6usjDlGx7lEx8Fl21DANBgkqhkiG9w0B
AQsFAAOCAgEAMeaZ5K0w2kPSqcZbzV4WwGShrhnSYdsA4dlZhAUNNxsoXX590Ppe
lla+vhFSdk/IwjFxLzmiau5+JlCySeOJv2AaG56JvBBU1Wl8LOk01a7qRctiKRth
AGFGKZoJ50h5W1A0NV7KwcGIkQdebAFPdMmkOd6Do98ZhkzYLRuAK3U0K4wNQJuf
gPt9XtIugRNQOwxolXAj81FfhjZ5CnoaCQYJBFyIenwg4uGjg+D0F9WtAlRq8ww+
XpWpVw8QgPDk+SVoGXUsBs+wMCDlGu4ozN2lIvG1N5n1q0qn39SUYOSBkEsdM+AS
Yu6LMP4J1SPOwT5UJN2jK7fAYBdChF39nV/xiatfUSy8rWUFQSwGv6JD3X0MAYfT
DyOiYdX8o+AnetjfBHHwVXDobh5d1GiC2DwoUNW7KoEdj5mmhDZKiB2S47/5J7El
UA9CevmmDvf/tN9itPrutSwcb7uwLYRsf7Gx3D3P/2+nQHUKyNcyQCNtgR7RKHBS
EjeedMgtKvrqsdPnk6Ygwj8EMh4owDIDcieqnPZAxhqJOJT2ZORdzyelmpv5aDGc
0XnnRHRInSUgQStfPa9ghOBpSXlhxL1EJFFik+yFOjH4GivhoynCb7zjW+MjlPDV
LAsnmMukBR95ZkpxMnRUEoLTEvTaxmg4Vr/mqXeQUKdU8A812Wrk2hc=
-----END CERTIFICATE-----

28
msa/black-box-tests/src/test/resources/redis-certs/redis.key

@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD4gJor9pKSWRQi
KHdyXiThFgkvystLrx3klVLGkJDwzC4BqR1T6m0PRvpfj4Jw21H3pSVw7dxHXkYs
tPqzb0rDhNrlIwT7KG4UtQitbED+An+mQkaSrW9dhnN1QWO0yUX5VsjD6vaGFKRt
NHWFXTyJGW9+Vp9LwkH+3OepMXJAhe7TyF5G3FVoLpIwct4eZl2B0mtI66XCD9y1
w/q2SL5lT2/5MfvUzeZMg4vO5LPuyqcUw+BbsRHRS1zh+d1F/PXssDU1l1Ks3QKH
kg74Rn2B//bnDyZqRvHuVmhkBKawB3RTKr1k8LSiT6gmN4PBqeX8GjsIYSB3FoVg
0qmeLPJRAgMBAAECggEAE6sCCMa8NQ8N0+JGCew/mP0Ifxra2kOi5wuWgJbCkfxn
C8SZyKF+Pj5M5LFUDqCdLS+J9hUtYQyqGzG7weXmEfF67bXG2CYMCGGHrUorHq+N
8NfABC3r6YgRrU8emBlyC1j+DNuU5WnO1cHYJ1UIzIUR2Pr8Ip/eX1CWmUKLm2WW
YvUGzvTG0mM0l9/Q8pcTndAxDuL90GG6TrxtQoy7Ir6dYxTVKHgOwa6RX86VrCkm
jl6Wu7Bvo2fnPvPVx8p1mgWNgtBbnc/VAYjeF7Yi7CETWHTxGM4iGtZNL8/xxlW7
sm2SmWEu72EupLYgytA9w+EptjbwWfcTaWbWUXTFHQKBgQD5nmYLVvZUR1oc9g2a
Q7XpFQ/jVvwedeKGolMbWTFrEhl1+D8lKN/S3SoRCOALOUJFUCU+L1snN3MsJ5Es
Gb0FLSH1LBBfuHqP+aHn/uGLMW8e7P9thh4DQ1tIzKE5xhh+JDJJqd15YJlsDy1F
0aKWyulS4o9XK5q86rs5QbI4MwKBgQD+2uXEAiFwEXq7pw2e8STrnt0jp09KU6b1
z/ykyArBdcVkrEudZ+jIrR/6rlSKK+SKQxtx8MG9M/Nm09KFRCAWblxHBwQ87ZnU
8tMAmPHrikLKk1dbbU3BQ3cZkIWMryCo4wzuxeT4mc2goTGNZpNZDpjqjCXbnCgP
T29aPHG3awKBgGFv8UlP4su3JnfTnC+xaprXO+J0G+oP/iKrzmEIif/Pity/0HZC
5Eu9RSRtIHeBHFtOE5uYhK5kOLLtpv9d9KjGm1DGqIWUz1LQEOEsXwIkg8nAnVw1
VBXV/xYFupGAwCLNIkwa4Hb2vCywJ+3vDNZr0nQmN+nA/Z/syLRq7pR9AoGBALqp
l3pd2SHdG5jP/VD57IHLRMs1YwTcikAmizQh9IbH/MEE1QlALya0buTLxM3C4kxG
ZJaqsSwkHdWltd64DAyB3oKDaB48JNzs0ZDxdNeA1/TJwEUNpNK12EjYKojlSDWK
v1Evjspq1EofZkzb4XZsE6JO7feQw2KbWsKr3NprAoGBAKSSAjDpncxb+9Pr0Lwa
AS7ATgMhot6+lbtZZV6egTGUVvtgd1LyE2ZJkE+5XJRu49X1lSJdDpFT66rG5eNV
+rYnDqXL8c0Z/j1L96z1UMY6DLPj3n+07zgLiNIrOR4UKP/+TGB9MHHFMEpYnij0
m/f6dg0Ujw6CW31Hq2QdJ9P7
-----END PRIVATE KEY-----

32
msa/black-box-tests/src/test/resources/redis-certs/redisCA.crt

@ -1,32 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFkzCCA3ugAwIBAgIUK9fjeDv+ESrdFSHMqsod5djzTh4wDQYJKoZIhvcNAQEL
BQAwWTELMAkGA1UEBhMCdWExDTALBgNVBAgMBGt5aXYxDTALBgNVBAcMBGt5aXYx
CzAJBgNVBAoMAnRiMQswCQYDVQQLDAJ0YjESMBAGA1UEAwwJbG9jYWxob3N0MB4X
DTIzMDkwNDE1MDUxN1oXDTMzMDkwMTE1MDUxN1owWTELMAkGA1UEBhMCdWExDTAL
BgNVBAgMBGt5aXYxDTALBgNVBAcMBGt5aXYxCzAJBgNVBAoMAnRiMQswCQYDVQQL
DAJ0YjESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
MIICCgKCAgEAsaxpM/OLfx0jNVHAiD4dmJ4t5vZQNINtaI/GgnXNv9iM3aDvbYr/
Cp8mJgkOvI9BZqDEcLscBv+H4mxCqS2IFBqJbtkYHExBgg7V13NRtJwqsWVz0rBG
V1SFou2JSzPkQ6IDxJI+AUW6DfsbCs3o6VRPbriMfY06rNagerG1osaD9yn/EsH9
BTdALravcvU8mxOghzWH54EzwDUA0mKUetgvgfqkzjDlqzXFnOsIinnDi0Ia3idF
RaBVs7bKokl0Zp1mdtvsEpG4lcmhDtNIogcmeH2LW2zEneHuDX2BGsN9CCwEGj3k
cftuxEck2mQVDoDgX1IpIUGBhIaAixj+UXh8RNSwU96GBwKbFNy/CXNj5+34DcL0
kBh7p77rcrzm6xEGpP/3YYPoRVBRAX64x4QqzqF5oj6Sf2NGKH9RILmLWdqmq/up
6cMYyzAEOr3nIQ/7OfkdvxOt0oUzeB7QPYbTvM9bCqe3XA+JH1pnLhgySPxdTeVe
nUExge8WPJmdTlH1McminFDiJruFRa069hbky/b5z8BjIBN5S3lC4PdEE9YmDSL1
u26HnRVwtqC32fkDNI1PT/4p2VaB+DmIxkFXrVUnV0TiyCyxu4jIgXhUiJRHgBn9
zwB7lEZUhMriOBGJqHa0H0TtnH8z/5GYmipeJZllmQbhI+sMyYBS/+cCAwEAAaNT
MFEwHQYDVR0OBBYEFJ+kSG8GpbHq6yMOUbHuUTHwWXbUMB8GA1UdIwQYMBaAFJ+k
SG8GpbHq6yMOUbHuUTHwWXbUMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
BQADggIBABCt/bx7/YbvR/0PE4nIzxVovPItR+oYcInRrbwT+VWvL22Su7rf71lc
1vlil4xjdVxSEi6s5KZ69PLJKKXukt1MBCUStDK1HKPPB1SAhtD6nuvkh7YL+2im
A5gmtg3KkD2ZD2mWCHAa8K7NEMah1XiMVMo+ByFNPQExqOk2i3+5kjBrlfElsm0Q
ixM++93T62gTibOjuO8uPP0NUcIHI+RcEalc1hJjFof4gWLnIulaeuUydXw7RhzE
HzeOeZiZWrvW2mjfiANMn27TV5K0dZoh/4+YLqkKn1bdQsYVIWxWx8jZ0Nj0yzMb
Ekkodny3F+BHqkSUb3whRWDKN82valnCSJFAKZFZzueAJgCjANTNdr7S7UUIxZyi
QKll59T4O1yhawRu/cZ6TQWzV7RWdTerFfIjHMwsohDUxlkoACJebLahsBG9IHGN
Tn+P2djY6CXBctbTXhRiYqeb79/TPU0EETv7/ilNHS/tssWcKWkFdai3yMzLvxeH
YTVPMzeAWW/PnQOwYTkgeaj7SIK5bbm5n/gpWk31R5gRWhgJc9FZSa9+oZWbWeYh
3XfsuCuTH+jSs0g+jJUx/cpIVrO38r2hSuhDPugmHgM6yEnKMubhChCPCyXjO0z9
brEMQ1T9r2sKOYuyNDhN/W9/QsTb/RO4Ug2lYlzRTdehqvimHspW
-----END CERTIFICATE-----

9
msa/black-box-tests/src/test/resources/valkey-certs/valkey.crt

@ -0,0 +1,9 @@
-----BEGIN CERTIFICATE-----
MIIBLTCB1AIUSQ2Ce8LOpzqOJhL2aXCTVrd45twwCgYIKoZIzj0EAwIwHDEaMBgG
A1UEAwwRVmFsa2V5IEVDIFJvb3QgQ0EwHhcNMjUwNTI4MDYxNTI5WhcNMjYwNTI4
MDYxNTI5WjAXMRUwEwYDVQQDDAx2YWxrZXkubG9jYWwwWTATBgcqhkjOPQIBBggq
hkjOPQMBBwNCAATSpimU25+2yIKGNwSQgPN2QaEcfWnj4c8PcTjeXg/1C2+fpMyl
jgknA64GUM2VeoVbG0mTkywlRU57+2yVLKYrMAoGCCqGSM49BAMCA0gAMEUCIDi0
ri1mBU64a8C0L/QZet0C/+HsbhItq40AmtZyEKWlAiEA8FJG51ZvncgYx8PCLGS7
WmBCqfnG58W4ga4M6YhEnYA=
-----END CERTIFICATE-----

8
msa/black-box-tests/src/test/resources/valkey-certs/valkey.key

@ -0,0 +1,8 @@
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIHsaG9ozysmDm7xv+d+i/vl7xJUHcgL93/9rvQfd3PWDoAoGCCqGSM49
AwEHoUQDQgAE0qYplNuftsiChjcEkIDzdkGhHH1p4+HPD3E43l4P9Qtvn6TMpY4J
JwOuBlDNlXqFWxtJk5MsJUVOe/tslSymKw==
-----END EC PRIVATE KEY-----

11
msa/black-box-tests/src/test/resources/valkey-certs/valkeyCA.crt

@ -0,0 +1,11 @@
-----BEGIN CERTIFICATE-----
MIIBjDCCATOgAwIBAgIUd7nfNuCY22WidK3CdazyMQUzVrAwCgYIKoZIzj0EAwIw
HDEaMBgGA1UEAwwRVmFsa2V5IEVDIFJvb3QgQ0EwHhcNMjUwNTI4MDYxNTE4WhcN
MjcwNTI4MDYxNTE4WjAcMRowGAYDVQQDDBFWYWxrZXkgRUMgUm9vdCBDQTBZMBMG
ByqGSM49AgEGCCqGSM49AwEHA0IABA4DTobDPtQtjBxYR+szO6p/pen9JWYPuXww
AyYMDEvD5ue3itruuDz0td0BMvn5YO+t1d03VKFVGP1ZpB4XO7ujUzBRMB0GA1Ud
DgQWBBSwBnnqUCfMUoaq7adEANr614SLFDAfBgNVHSMEGDAWgBSwBnnqUCfMUoaq
7adEANr614SLFDAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIFCp
9xuuj8Z6iSozSA/3cIugBnQqUSMw9BrS+2Qr6v69AiBz2R+DGXZAKTkOzqgxBXjv
fcdX4LrBpLCn1Pw/IDD+Ug==
-----END CERTIFICATE-----
Loading…
Cancel
Save