Skip to content

Commit 761c1fa

Browse files
Merge pull request #260 from thingsboard/valkey
ValKey 8.0 (alternative to Redis > 7.2)
2 parents de9fa91 + 17488fb commit 761c1fa

28 files changed

+432
-391
lines changed

application/src/test/java/org/thingsboard/mqtt/broker/AbstractPubSubIntegrationTest.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import org.springframework.test.context.web.WebAppConfiguration;
4545
import org.testcontainers.containers.GenericContainer;
4646
import org.testcontainers.containers.KafkaContainer;
47-
import org.testcontainers.containers.output.OutputFrame;
4847
import org.testcontainers.utility.DockerImageName;
4948
import org.thingsboard.mqtt.broker.common.data.BrokerConstants;
5049
import org.thingsboard.mqtt.broker.common.data.security.MqttAuthProvider;
@@ -129,27 +128,26 @@ public static class TestPublishMsg {
129128
public static KafkaContainer kafka = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:7.9.2"));
130129

131130
@ClassRule
132-
public static GenericContainer redis = new GenericContainer("redis:7.2.5")
131+
public static GenericContainer<?> valkey = new GenericContainer<>("valkey/valkey:8.0")
133132
.withExposedPorts(6379)
134-
.withLogConsumer(x -> log.warn("{}", ((OutputFrame) x).getUtf8StringWithoutLineEnding()))
135-
.withEnv("REDIS_PASSWORD", "password")
136-
.withCommand("redis-server", "--requirepass", "password");
133+
.withLogConsumer(x -> log.warn("{}", x.getUtf8StringWithoutLineEnding()))
134+
.withCommand("valkey-server", "--requirepass", "password");
137135

138136
@ClassRule
139137
public static ExternalResource resource = new ExternalResource() {
140138
@Override
141139
protected void before() {
142-
redis.start();
140+
valkey.start();
143141
System.setProperty("redis.connection.type", "standalone");
144-
System.setProperty("redis.standalone.host", redis.getHost());
145-
System.setProperty("redis.standalone.port", String.valueOf(redis.getMappedPort(6379)));
142+
System.setProperty("redis.standalone.host", valkey.getHost());
143+
System.setProperty("redis.standalone.port", String.valueOf(valkey.getMappedPort(6379)));
146144
System.setProperty("redis.password", "password");
147145
}
148146

149147
@Override
150148
protected void after() {
151-
redis.stop();
152-
List.of("redis.connection.type", "redis.standalone.host", "redis.standalone.port")
149+
valkey.stop();
150+
List.of("redis.connection.type", "redis.standalone.host", "redis.standalone.port", "redis.password")
153151
.forEach(System.getProperties()::remove);
154152
}
155153
};
@@ -219,10 +217,14 @@ private void resetMqttAuthProviderToDefaultConfiguration(MqttAuthProviderType ty
219217
MqttAuthProvider mqttAuthProvider = getMqttAuthProvider(type);
220218
mqttAuthProvider.setEnabled(false);
221219
switch (type) {
222-
case MQTT_BASIC -> mqttAuthProvider.setConfiguration(MqttAuthProvider.defaultBasicAuthProvider(false).getConfiguration());
223-
case X_509 -> mqttAuthProvider.setConfiguration(MqttAuthProvider.defaultSslAuthProvider(false).getConfiguration());
224-
case JWT -> mqttAuthProvider.setConfiguration(MqttAuthProvider.defaultJwtAuthProvider(false).getConfiguration());
225-
case SCRAM -> mqttAuthProvider.setConfiguration(MqttAuthProvider.defaultScramAuthProvider(false).getConfiguration());
220+
case MQTT_BASIC ->
221+
mqttAuthProvider.setConfiguration(MqttAuthProvider.defaultBasicAuthProvider(false).getConfiguration());
222+
case X_509 ->
223+
mqttAuthProvider.setConfiguration(MqttAuthProvider.defaultSslAuthProvider(false).getConfiguration());
224+
case JWT ->
225+
mqttAuthProvider.setConfiguration(MqttAuthProvider.defaultJwtAuthProvider(false).getConfiguration());
226+
case SCRAM ->
227+
mqttAuthProvider.setConfiguration(MqttAuthProvider.defaultScramAuthProvider(false).getConfiguration());
226228
}
227229
mqttAuthProviderManagerService.saveAuthProvider(mqttAuthProvider);
228230
}

dao/src/test/java/org/thingsboard/mqtt/broker/dao/AbstractRedisClusterContainer.java

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,86 +16,87 @@
1616
package org.thingsboard.mqtt.broker.dao;
1717

1818
import lombok.extern.slf4j.Slf4j;
19+
import org.assertj.core.api.Assertions;
1920
import org.junit.ClassRule;
2021
import org.junit.rules.ExternalResource;
2122
import org.testcontainers.containers.GenericContainer;
22-
import org.testcontainers.containers.Network;
23+
import org.testcontainers.containers.output.OutputFrame;
2324
import org.testcontainers.containers.wait.strategy.Wait;
25+
import org.testcontainers.lifecycle.Startables;
2426

2527
import java.time.Duration;
2628
import java.util.List;
2729
import java.util.concurrent.TimeUnit;
30+
import java.util.stream.Stream;
2831

2932
@Slf4j
3033
public class AbstractRedisClusterContainer {
3134

32-
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";
35+
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";
36+
static final String IMAGE = "valkey/valkey:8.0";
37+
static final String PASSWORD = "your-strong-password";
3338

34-
private static GenericContainer<?> redis(String port) {
35-
return new GenericContainer<>("bitnamilegacy/redis-cluster:7.2.5")
36-
.withEnv("REDIS_PORT_NUMBER", port)
39+
private static GenericContainer<?> valkey(String port) {
40+
return new GenericContainer<>(IMAGE)
3741
.withNetworkMode("host")
38-
.withLogConsumer(x -> log.warn("{}", x.getUtf8StringWithoutLineEnding()))
39-
.withEnv("REDIS_PASSWORD", "password")
40-
.withEnv("REDIS_NODES", nodes)
41-
.waitingFor(Wait.forListeningPort().withStartupTimeout(Duration.ofSeconds(30)));
42+
.withLogConsumer(AbstractRedisClusterContainer::consumeLog)
43+
.waitingFor(Wait.forListeningPort().withStartupTimeout(Duration.ofSeconds(30)))
44+
.withCommand("valkey-server",
45+
"--port " + port,
46+
"--requirepass " + PASSWORD, // Password for clients connecting to this node
47+
"--masterauth " + PASSWORD, // Password for replicas to authenticate with masters
48+
"--cluster-enabled yes",
49+
"--cluster-config-file nodes.conf",
50+
"--cluster-node-timeout 5000",
51+
"--appendonly no"
52+
);
4253
}
4354

44-
@ClassRule
45-
public static Network network = Network.newNetwork();
46-
@ClassRule
47-
public static GenericContainer<?> redis1 = redis("6371");
48-
@ClassRule
49-
public static GenericContainer<?> redis2 = redis("6372");
50-
@ClassRule
51-
public static GenericContainer<?> redis3 = redis("6373");
52-
@ClassRule
53-
public static GenericContainer<?> redis4 = redis("6374");
54-
@ClassRule
55-
public static GenericContainer<?> redis5 = redis("6375");
56-
@ClassRule
57-
public static GenericContainer<?> redis6 = redis("6376");
55+
@ClassRule(order = 1)
56+
public static GenericContainer<?> valkey1 = valkey("6371");
57+
@ClassRule(order = 2)
58+
public static GenericContainer<?> valkey2 = valkey("6372");
59+
@ClassRule(order = 3)
60+
public static GenericContainer<?> valkey3 = valkey("6373");
61+
@ClassRule(order = 4)
62+
public static GenericContainer<?> valkey4 = valkey("6374");
63+
@ClassRule(order = 5)
64+
public static GenericContainer<?> valkey5 = valkey("6375");
65+
@ClassRule(order = 6)
66+
public static GenericContainer<?> valkey6 = valkey("6376");
5867

59-
@ClassRule
68+
@ClassRule(order = 100)
6069
public static ExternalResource resource = new ExternalResource() {
6170
@Override
6271
protected void before() throws Throwable {
63-
redis1.start();
64-
redis2.start();
65-
redis3.start();
66-
redis4.start();
67-
redis5.start();
68-
redis6.start();
72+
Startables.deepStart(Stream.of(valkey1, valkey2, valkey3, valkey4, valkey5, valkey6)).join();
6973

7074
Thread.sleep(TimeUnit.SECONDS.toMillis(5)); // otherwise not all containers have time to start
7175

72-
String clusterCreateCommand = "echo yes | redis-cli --cluster create " +
73-
nodes.replace(",", " ") +
74-
" --cluster-replicas 1";
75-
log.warn("Command to init Redis Cluster: {}", clusterCreateCommand);
76-
var result = redis6.execInContainer("/bin/sh", "-c", "export REDISCLI_AUTH=password && " + clusterCreateCommand);
76+
String clusterCreateCommand = "valkey-cli -a " + PASSWORD + " --cluster create " + NODES.replace(",", " ") + " --cluster-replicas 1 --cluster-yes";
77+
log.warn("Command to init ValKey Cluster: {}", clusterCreateCommand);
78+
var result = valkey6.execInContainer("/bin/sh", "-c", clusterCreateCommand);
7779
log.warn("Init cluster result: {}", result);
80+
Assertions.assertThat(result.getExitCode()).isEqualTo(0);
7881

7982
Thread.sleep(TimeUnit.SECONDS.toMillis(5)); // otherwise cluster not always ready
8083

81-
log.warn("Connect to nodes: {}", nodes);
82-
System.setProperty("redis.password", "password");
84+
log.warn("Connect to nodes: {}", NODES);
85+
System.setProperty("redis.password", PASSWORD);
8386
System.setProperty("redis.connection.type", "cluster");
84-
System.setProperty("redis.cluster.nodes", nodes);
87+
System.setProperty("redis.cluster.nodes", NODES);
8588
System.setProperty("redis.cluster.useDefaultPoolConfig", "false");
8689
}
8790

8891
@Override
8992
protected void after() {
90-
redis1.stop();
91-
redis2.stop();
92-
redis3.stop();
93-
redis4.stop();
94-
redis5.stop();
95-
redis6.stop();
93+
Stream.of(valkey1, valkey2, valkey3, valkey4, valkey5, valkey6).parallel().forEach(GenericContainer::stop);
9694
List.of("redis.password", "redis.connection.type", "redis.cluster.nodes", "redis.cluster.useDefaultPoolConfig")
9795
.forEach(System.getProperties()::remove);
9896
}
9997
};
10098

99+
private static void consumeLog(Object x) {
100+
log.warn("{}", ((OutputFrame) x).getUtf8StringWithoutLineEnding());
101+
}
101102
}

dao/src/test/java/org/thingsboard/mqtt/broker/dao/AbstractRedisContainer.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,30 @@
2828
@Slf4j
2929
public class AbstractRedisContainer {
3030

31-
@ClassRule
32-
public static GenericContainer<?> redis = new GenericContainer<>("redis:7.2.5")
31+
@ClassRule(order = 0)
32+
public static GenericContainer<?> valkey = new GenericContainer<>("valkey/valkey:8.0")
3333
.withExposedPorts(6379)
3434
.withLogConsumer(x -> log.warn("{}", x.getUtf8StringWithoutLineEnding()))
35-
.withEnv("REDIS_PASSWORD", "password")
36-
.withCommand("redis-server", "--requirepass", "password")
35+
.withCommand("valkey-server", "--requirepass", "password")
3736
.waitingFor(Wait.forListeningPort()).withStartupTimeout(Duration.ofSeconds(10));
3837

39-
@ClassRule
38+
@ClassRule(order = 1)
4039
public static ExternalResource resource = new ExternalResource() {
4140
@Override
4241
protected void before() throws Throwable {
43-
redis.start();
42+
valkey.start();
4443

4544
Thread.sleep(TimeUnit.SECONDS.toMillis(5));
4645

4746
System.setProperty("redis.connection.type", "standalone");
48-
System.setProperty("redis.standalone.host", redis.getHost());
49-
System.setProperty("redis.standalone.port", String.valueOf(redis.getMappedPort(6379)));
47+
System.setProperty("redis.standalone.host", valkey.getHost());
48+
System.setProperty("redis.standalone.port", String.valueOf(valkey.getMappedPort(6379)));
5049
System.setProperty("redis.password", "password");
5150
}
5251

5352
@Override
5453
protected void after() {
55-
redis.stop();
54+
valkey.stop();
5655
List.of("redis.connection.type", "redis.standalone.host", "redis.standalone.port", "redis.password")
5756
.forEach(System.getProperties()::remove);
5857
}

docker/.env

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@ TBMQ_2_NAME=tbmq2
1212
TBMQ_IE_1_NAME=tbmq-ie1
1313
TBMQ_IE_2_NAME=tbmq-ie2
1414

15-
REDIS_NAME=redis
15+
VALKEY_NAME=valkey
1616

17-
REDIS_MASTER_NAME=redis-master
18-
REDIS_SLAVE_NAME=redis-slave
19-
REDIS_SENTINEL_NAME=redis-sentinel
17+
VALKEY_PRIMARY_NAME=valkey-primary
18+
VALKEY_SLAVE_NAME=valkey-slave
19+
VALKEY_SENTINEL_NAME=valkey-sentinel
2020

21-
REDIS_NODE_0_NAME=redis-node-0
22-
REDIS_NODE_1_NAME=redis-node-1
23-
REDIS_NODE_2_NAME=redis-node-2
24-
REDIS_NODE_3_NAME=redis-node-3
25-
REDIS_NODE_4_NAME=redis-node-4
26-
REDIS_NODE_5_NAME=redis-node-5
21+
VALKEY_NODE_0_NAME=valkey-node-0
22+
VALKEY_NODE_1_NAME=valkey-node-1
23+
VALKEY_NODE_2_NAME=valkey-node-2
24+
VALKEY_NODE_3_NAME=valkey-node-3
25+
VALKEY_NODE_4_NAME=valkey-node-4
26+
VALKEY_NODE_5_NAME=valkey-node-5
2727

28-
# redis or redis-cluster or redis-sentinel
29-
CACHE=redis
28+
# valkey or valkey-cluster or valkey-sentinel
29+
CACHE=valkey
3030

3131
# Limit memory usage for Java applications
3232
#JAVA_OPTS=-Xmx2048M -Xms2048M -Xss384k -XX:+AlwaysPreTouch

docker/cache-redis.env

Lines changed: 0 additions & 1 deletion
This file was deleted.

docker/cache-redis-cluster.env renamed to docker/cache-valkey-cluster.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
REDIS_CONNECTION_TYPE=cluster
2-
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
2+
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
33
REDIS_CLUSTER_USE_DEFAULT_POOL_CONFIG=false
44
REDIS_PASSWORD=thingsboard
55
REDIS_LETTUCE_CLUSTER_TOPOLOGY_REFRESH_ENABLED=true
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
REDIS_CONNECTION_TYPE=sentinel
2-
REDIS_MASTER=mymaster
3-
REDIS_SENTINELS=redis-sentinel:26379
2+
REDIS_MASTER=myprimary
3+
REDIS_SENTINELS=valkey-sentinel:26379
44
REDIS_SENTINEL_PASSWORD=sentinel
55
REDIS_SENTINEL_USE_DEFAULT_POOL_CONFIG=false
66
REDIS_PASSWORD=thingsboard

docker/cache-valkey.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
REDIS_HOST=valkey

0 commit comments

Comments
 (0)