Skip to content

Commit 30f7785

Browse files
committed
feat: Support Redis Enterprise 7.4
1 parent 82fe833 commit 30f7785

File tree

11 files changed

+167
-38
lines changed

11 files changed

+167
-38
lines changed

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ config {
4949
coverage {
5050
jacoco {
5151
enabled = true
52-
toolVersion = jacocoVersion
52+
toolVersion = jacocoPluginVersion
5353
}
5454
}
5555
}
@@ -76,7 +76,7 @@ subprojects {
7676
}
7777
coverage {
7878
jacoco {
79-
toolVersion = jacocoVersion
79+
toolVersion = jacocoPluginVersion
8080
}
8181
}
8282
}

core/redis-enterprise-admin/redis-enterprise-admin.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ dependencies {
1111
testImplementation(group: 'com.redis', name: 'testcontainers-redis', version: testcontainersRedisVersion) {
1212
exclude group: 'com.redis', module: 'redis-enterprise-admin'
1313
}
14+
testImplementation(group: 'com.redis', name: 'testcontainers-redis-enterprise', version: testcontainersRedisVersion) {
15+
exclude group: 'com.redis', module: 'redis-enterprise-admin'
16+
}
1417
testImplementation group: 'com.redis', name: 'lettucemod', version: lettucemodVersion
1518
}
1619

core/redis-enterprise-admin/src/main/java/com/redis/enterprise/Admin.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
import java.security.KeyStoreException;
99
import java.security.NoSuchAlgorithmException;
1010
import java.time.Duration;
11-
import java.util.HashMap;
11+
import java.util.Collection;
1212
import java.util.List;
13-
import java.util.Map;
13+
import java.util.Optional;
14+
import java.util.stream.Stream;
1415

1516
import javax.net.ssl.SSLContext;
1617

@@ -211,15 +212,20 @@ public List<InstalledModule> getModules() throws IOException, GeneralSecurityExc
211212
}
212213

213214
public Database createDatabase(Database database) throws IOException, GeneralSecurityException {
214-
Map<String, InstalledModule> installedModules = new HashMap<>();
215-
for (InstalledModule module : getModules()) {
216-
installedModules.put(module.getName(), module);
217-
}
215+
Collection<InstalledModule> installedModules = getModules();
218216
for (ModuleConfig moduleConfig : database.getModules()) {
219-
if (!installedModules.containsKey(moduleConfig.getName())) {
217+
Stream<InstalledModule> matches = installedModules.stream()
218+
.filter(m -> m.getName().equals(moduleConfig.getName()))
219+
.sorted((m1, m2) -> Integer.compare(m2.getVersion(), m1.getVersion()));
220+
Optional<InstalledModule> match = matches.findFirst();
221+
if (match.isPresent()) {
222+
InstalledModule installedModule = match.get();
223+
if (moduleConfig.getId() == null) {
224+
moduleConfig.setId(installedModule.getId());
225+
}
226+
} else {
220227
throw new IllegalArgumentException(String.format("Module %s not installed", moduleConfig.getName()));
221228
}
222-
moduleConfig.setId(installedModules.get(moduleConfig.getName()).getId());
223229
}
224230
Database response = post(v1(BDBS), database, Database.class);
225231
long uid = response.getUid();

core/redis-enterprise-admin/src/main/java/com/redis/enterprise/Database.java

Lines changed: 107 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ public static List<String> defaultShardKeyRegexes() {
3737
private Integer port;
3838
private Type type;
3939
private boolean ossCluster;
40-
private ProxyPolicy proxyPolicy;
4140
private IPType ossClusterAPIPreferredIPType;
41+
private ProxyPolicy proxyPolicy;
42+
private String redisVersion;
4243
private List<ShardKeyRegex> shardKeyRegex;
4344
private Integer shardCount;
4445
private ShardPlacement shardPlacement;
@@ -56,8 +57,9 @@ private Database(Builder builder) {
5657
this.port = builder.port;
5758
this.type = builder.type;
5859
this.ossCluster = builder.ossCluster;
59-
this.proxyPolicy = builder.proxyPolicy;
6060
this.ossClusterAPIPreferredIPType = builder.ossClusterAPIPreferredIPType;
61+
this.proxyPolicy = builder.proxyPolicy;
62+
this.redisVersion = builder.redisVersion;
6163
this.shardKeyRegex = builder.shardKeyRegexes.stream().map(ShardKeyRegex::new).collect(Collectors.toList());
6264
this.shardCount = builder.shardCount;
6365
this.shardPlacement = builder.shardPlacement;
@@ -134,6 +136,15 @@ public void setOssCluster(boolean ossCluster) {
134136
this.ossCluster = ossCluster;
135137
}
136138

139+
@JsonProperty("oss_cluster_api_preferred_ip_type")
140+
public IPType getOssClusterAPIPreferredIPType() {
141+
return ossClusterAPIPreferredIPType;
142+
}
143+
144+
public void setOssClusterAPIPreferredIPType(IPType ossClusterAPIPreferredIPType) {
145+
this.ossClusterAPIPreferredIPType = ossClusterAPIPreferredIPType;
146+
}
147+
137148
@JsonProperty("proxy_policy")
138149
public ProxyPolicy getProxyPolicy() {
139150
return proxyPolicy;
@@ -143,13 +154,13 @@ public void setProxyPolicy(ProxyPolicy proxyPolicy) {
143154
this.proxyPolicy = proxyPolicy;
144155
}
145156

146-
@JsonProperty("oss_cluster_api_preferred_ip_type")
147-
public IPType getOssClusterAPIPreferredIPType() {
148-
return ossClusterAPIPreferredIPType;
157+
@JsonProperty("redis_version")
158+
public String getRedisVersion() {
159+
return redisVersion;
149160
}
150161

151-
public void setOssClusterAPIPreferredIPType(IPType ossClusterAPIPreferredIPType) {
152-
this.ossClusterAPIPreferredIPType = ossClusterAPIPreferredIPType;
162+
public void setRedisVersion(String redisVersion) {
163+
this.redisVersion = redisVersion;
153164
}
154165

155166
@JsonProperty("shard_key_regex")
@@ -191,7 +202,7 @@ public void setModules(List<ModuleConfig> modules) {
191202
@Override
192203
public int hashCode() {
193204
return Objects.hash(memory, modules, name, ossCluster, ossClusterAPIPreferredIPType, port, proxyPolicy,
194-
replication, shardCount, shardKeyRegex, shardPlacement, sharding, type, uid);
205+
replication, redisVersion, shardCount, shardKeyRegex, shardPlacement, sharding, type, uid);
195206
}
196207

197208
@Override
@@ -206,9 +217,10 @@ public boolean equals(Object obj) {
206217
return memory == other.memory && Objects.equals(modules, other.modules) && Objects.equals(name, other.name)
207218
&& ossCluster == other.ossCluster && ossClusterAPIPreferredIPType == other.ossClusterAPIPreferredIPType
208219
&& Objects.equals(port, other.port) && proxyPolicy == other.proxyPolicy
209-
&& replication == other.replication && Objects.equals(shardCount, other.shardCount)
210-
&& Objects.equals(shardKeyRegex, other.shardKeyRegex) && shardPlacement == other.shardPlacement
211-
&& sharding == other.sharding && Objects.equals(type, other.type) && Objects.equals(uid, other.uid);
220+
&& Objects.equals(redisVersion, other.redisVersion) && replication == other.replication
221+
&& Objects.equals(shardCount, other.shardCount) && Objects.equals(shardKeyRegex, other.shardKeyRegex)
222+
&& shardPlacement == other.shardPlacement && sharding == other.sharding
223+
&& Objects.equals(type, other.type) && Objects.equals(uid, other.uid);
212224
}
213225

214226
public enum IPType {
@@ -240,9 +252,12 @@ public enum Type {
240252
@JsonInclude(JsonInclude.Include.NON_NULL)
241253
public static class ModuleConfig {
242254

255+
public static final String DEFAULT_ARGS = "";
256+
243257
private String name;
244258
private String id;
245-
private String args = "";
259+
private String args = DEFAULT_ARGS;
260+
private String version;
246261

247262
public ModuleConfig() {
248263
}
@@ -251,6 +266,13 @@ public ModuleConfig(String name) {
251266
this.name = name;
252267
}
253268

269+
private ModuleConfig(Builder builder) {
270+
this.name = builder.name;
271+
this.id = builder.id;
272+
this.args = builder.args;
273+
this.version = builder.version;
274+
}
275+
254276
@JsonProperty("module_name")
255277
public String getName() {
256278
return name;
@@ -278,6 +300,68 @@ public void setArgs(String args) {
278300
this.args = args;
279301
}
280302

303+
@JsonProperty("semantic_version")
304+
public String getVersion() {
305+
return version;
306+
}
307+
308+
public void setVersion(String version) {
309+
this.version = version;
310+
}
311+
312+
public static Builder search() {
313+
return new Builder().name(RedisModule.SEARCH.getModuleName());
314+
}
315+
316+
public static Builder json() {
317+
return new Builder().name(RedisModule.JSON.getModuleName());
318+
}
319+
320+
public static Builder probabilistic() {
321+
return new Builder().name(RedisModule.PROBABILISTIC.getModuleName());
322+
}
323+
324+
public static Builder timeseries() {
325+
return new Builder().name(RedisModule.TIMESERIES.getModuleName());
326+
}
327+
328+
public static Builder builder() {
329+
return new Builder();
330+
}
331+
332+
public static class Builder {
333+
334+
private String name;
335+
private String id;
336+
private String args = DEFAULT_ARGS;
337+
private String version;
338+
339+
public Builder name(String name) {
340+
this.name = name;
341+
return this;
342+
}
343+
344+
public Builder id(String id) {
345+
this.id = id;
346+
return this;
347+
}
348+
349+
public Builder args(String args) {
350+
this.args = args;
351+
return this;
352+
}
353+
354+
public Builder version(String version) {
355+
this.version = version;
356+
return this;
357+
}
358+
359+
public ModuleConfig build() {
360+
return new ModuleConfig(this);
361+
}
362+
363+
}
364+
281365
}
282366

283367
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -318,6 +402,7 @@ public static final class Builder {
318402
private boolean ossCluster;
319403
private ProxyPolicy proxyPolicy;
320404
private IPType ossClusterAPIPreferredIPType;
405+
private String redisVersion;
321406
private List<String> shardKeyRegexes = new ArrayList<>();
322407
private Integer shardCount;
323408
private ShardPlacement shardPlacement;
@@ -336,6 +421,11 @@ public Builder name(String name) {
336421
return this;
337422
}
338423

424+
public Builder redisVersion(String version) {
425+
this.redisVersion = version;
426+
return this;
427+
}
428+
339429
public Builder replication(boolean replication) {
340430
this.replication = replication;
341431
return this;
@@ -427,6 +517,11 @@ public Builder shardPlacement(ShardPlacement shardPlacement) {
427517
return this;
428518
}
429519

520+
public Builder module(ModuleConfig module) {
521+
this.moduleConfigs.add(module);
522+
return this;
523+
}
524+
430525
public Builder module(RedisModule module) {
431526
this.moduleConfigs.add(new ModuleConfig(module.getModuleName()));
432527
return this;

core/redis-enterprise-admin/src/main/java/com/redis/enterprise/RedisModule.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
public enum RedisModule {
44

5-
BLOOM("bf"), GRAPH("graph"), JSON("ReJSON"), SEARCH("search"), TIMESERIES("timeseries");
5+
PROBABILISTIC("bf"), JSON("ReJSON"), SEARCH("search"), TIMESERIES("timeseries");
66

77
private final String moduleName;
88

9-
RedisModule(String moduleName) {
10-
this.moduleName = moduleName;
9+
RedisModule(String name) {
10+
this.moduleName = name;
1111
}
1212

1313
public String getModuleName() {

core/redis-enterprise-admin/src/main/java/com/redis/enterprise/rest/InstalledModule.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public class InstalledModule {
88

99
private String name;
1010
private String id;
11+
private int version;
1112

1213
public String getName() {
1314
return name;
@@ -27,4 +28,12 @@ public void setId(String id) {
2728
this.id = id;
2829
}
2930

31+
public int getVersion() {
32+
return version;
33+
}
34+
35+
public void setVersion(int version) {
36+
this.version = version;
37+
}
38+
3039
}

core/redis-enterprise-admin/src/test/java/com/redis/enterprise/ServerAdminTests.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,28 @@
22

33
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
44

5-
import com.redis.testcontainers.RedisEnterpriseServer;
5+
import com.redis.enterprise.testcontainers.RedisEnterpriseServer;
66

77
@EnabledIfEnvironmentVariable(named = RedisEnterpriseServer.ENV_HOST, matches = ".*")
88
class ServerAdminTests extends AbstractAdminTests {
99

1010
@Override
1111
protected Admin admin() {
1212
Admin admin = new Admin();
13+
String user = System.getenv(RedisEnterpriseServer.ENV_USER);
14+
if (hasLength(user)) {
15+
admin.withUserName(user);
16+
}
17+
String password = System.getenv(RedisEnterpriseServer.ENV_PASSWORD);
18+
if (hasLength(password)) {
19+
admin.withPassword(password);
20+
}
1321
admin.withHost(System.getenv(RedisEnterpriseServer.ENV_HOST));
1422
return admin;
1523
}
1624

25+
private static boolean hasLength(String string) {
26+
return string != null && string.length() > 0;
27+
}
28+
1729
}

core/redis-enterprise-admin/src/test/java/com/redis/enterprise/TestRedisEnterpriseContainer.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22

33
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
5+
import org.testcontainers.containers.ContainerLaunchException;
56
import org.testcontainers.utility.DockerImageName;
67

7-
import com.redis.testcontainers.AbstractRedisEnterpriseContainer;
8+
import com.redis.enterprise.testcontainers.AbstractRedisEnterpriseContainer;
89

910
public class TestRedisEnterpriseContainer extends AbstractRedisEnterpriseContainer<TestRedisEnterpriseContainer> {
1011

1112
private final Admin admin = new Admin();
1213
private Database database = Database.builder().shardCount(2).port(12000).ossCluster(true)
13-
.modules(RedisModule.SEARCH, RedisModule.JSON, RedisModule.TIMESERIES, RedisModule.BLOOM).build();
14+
.modules(RedisModule.SEARCH, RedisModule.JSON, RedisModule.TIMESERIES, RedisModule.PROBABILISTIC).build();
1415

1516
private final Logger log = LoggerFactory.getLogger(TestRedisEnterpriseContainer.class);
1617

@@ -51,11 +52,16 @@ protected void doStart() {
5152
}
5253

5354
@Override
54-
protected void createCluster() throws Exception {
55+
protected void createCluster() {
5556
log.info("Waiting for cluster bootstrap");
5657
admin.waitForBoostrap();
5758
super.createCluster();
58-
Database response = admin.createDatabase(database);
59+
Database response;
60+
try {
61+
response = admin.createDatabase(database);
62+
} catch (Exception e) {
63+
throw new ContainerLaunchException("Could not create Redis Enterprise database", e);
64+
}
5965
log.info("Created database {} with UID {}", response.getName(), response.getUid());
6066
}
6167

0 commit comments

Comments
 (0)