Skip to content

Commit 594765e

Browse files
committed
Add nullability annotations to module/spring-boot-data-redis
See gh-46587
1 parent b036947 commit 594765e

File tree

12 files changed

+180
-120
lines changed

12 files changed

+180
-120
lines changed

module/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/JedisConnectionConfiguration.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration.JedisSslClientConfigurationBuilder;
4444
import org.springframework.data.redis.connection.jedis.JedisConnection;
4545
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
46+
import org.springframework.util.Assert;
4647
import org.springframework.util.StringUtils;
4748

4849
/**
@@ -92,8 +93,16 @@ private JedisConnectionFactory createJedisConnectionFactory(
9293
JedisClientConfiguration clientConfiguration = getJedisClientConfiguration(builderCustomizers);
9394
return switch (this.mode) {
9495
case STANDALONE -> new JedisConnectionFactory(getStandaloneConfig(), clientConfiguration);
95-
case CLUSTER -> new JedisConnectionFactory(getClusterConfiguration(), clientConfiguration);
96-
case SENTINEL -> new JedisConnectionFactory(getSentinelConfig(), clientConfiguration);
96+
case CLUSTER -> {
97+
RedisClusterConfiguration clusterConfiguration = getClusterConfiguration();
98+
Assert.state(clusterConfiguration != null, "'clusterConfiguration' must not be null");
99+
yield new JedisConnectionFactory(clusterConfiguration, clientConfiguration);
100+
}
101+
case SENTINEL -> {
102+
RedisSentinelConfiguration sentinelConfig = getSentinelConfig();
103+
Assert.state(sentinelConfig != null, "'sentinelConfig' must not be null");
104+
yield new JedisConnectionFactory(sentinelConfig, clientConfiguration);
105+
}
97106
};
98107
}
99108

@@ -105,8 +114,9 @@ private JedisClientConfiguration getJedisClientConfiguration(
105114
if (isPoolEnabled(pool)) {
106115
applyPooling(pool, builder);
107116
}
108-
if (StringUtils.hasText(getProperties().getUrl())) {
109-
customizeConfigurationFromUrl(builder);
117+
String url = getProperties().getUrl();
118+
if (StringUtils.hasText(url)) {
119+
customizeConfigurationFromUrl(builder, url);
110120
}
111121
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
112122
return builder.build();
@@ -154,8 +164,9 @@ private JedisPoolConfig jedisPoolConfig(RedisProperties.Pool pool) {
154164
return config;
155165
}
156166

157-
private void customizeConfigurationFromUrl(JedisClientConfiguration.JedisClientConfigurationBuilder builder) {
158-
if (urlUsesSsl()) {
167+
private void customizeConfigurationFromUrl(JedisClientConfiguration.JedisClientConfigurationBuilder builder,
168+
String url) {
169+
if (urlUsesSsl(url)) {
159170
builder.useSsl();
160171
}
161172
}

module/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/LettuceConnectionConfiguration.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import io.lettuce.core.resource.ClientResources;
3131
import io.lettuce.core.resource.DefaultClientResources;
3232
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
33+
import org.jspecify.annotations.Nullable;
3334

3435
import org.springframework.beans.factory.ObjectProvider;
3536
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -52,6 +53,7 @@
5253
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration.LettuceClientConfigurationBuilder;
5354
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
5455
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
56+
import org.springframework.util.Assert;
5557
import org.springframework.util.StringUtils;
5658

5759
/**
@@ -120,8 +122,16 @@ private LettuceConnectionFactory createConnectionFactory(
120122
getProperties().getLettuce().getPool());
121123
return switch (this.mode) {
122124
case STANDALONE -> new LettuceConnectionFactory(getStandaloneConfig(), clientConfiguration);
123-
case CLUSTER -> new LettuceConnectionFactory(getClusterConfiguration(), clientConfiguration);
124-
case SENTINEL -> new LettuceConnectionFactory(getSentinelConfig(), clientConfiguration);
125+
case CLUSTER -> {
126+
RedisClusterConfiguration clusterConfiguration = getClusterConfiguration();
127+
Assert.state(clusterConfiguration != null, "'clusterConfiguration' must not be null");
128+
yield new LettuceConnectionFactory(clusterConfiguration, clientConfiguration);
129+
}
130+
case SENTINEL -> {
131+
RedisSentinelConfiguration sentinelConfig = getSentinelConfig();
132+
Assert.state(sentinelConfig != null, "'sentinelConfig' must not be null");
133+
yield new LettuceConnectionFactory(sentinelConfig, clientConfiguration);
134+
}
125135
};
126136
}
127137

@@ -132,8 +142,9 @@ private LettuceClientConfiguration getLettuceClientConfiguration(
132142
LettuceClientConfigurationBuilder builder = createBuilder(pool);
133143
SslBundle sslBundle = getSslBundle();
134144
applyProperties(builder, sslBundle);
135-
if (StringUtils.hasText(getProperties().getUrl())) {
136-
customizeConfigurationFromUrl(builder);
145+
String url = getProperties().getUrl();
146+
if (StringUtils.hasText(url)) {
147+
customizeConfigurationFromUrl(builder, url);
137148
}
138149
builder.clientOptions(createClientOptions(clientOptionsBuilderCustomizers, sslBundle));
139150
builder.clientResources(clientResources);
@@ -148,7 +159,7 @@ private LettuceClientConfigurationBuilder createBuilder(Pool pool) {
148159
return LettuceClientConfiguration.builder();
149160
}
150161

151-
private void applyProperties(LettuceClientConfigurationBuilder builder, SslBundle sslBundle) {
162+
private void applyProperties(LettuceClientConfigurationBuilder builder, @Nullable SslBundle sslBundle) {
152163
if (sslBundle != null) {
153164
builder.useSsl();
154165
}
@@ -191,7 +202,7 @@ private String getCanonicalReadFromName(String name) {
191202

192203
private ClientOptions createClientOptions(
193204
ObjectProvider<LettuceClientOptionsBuilderCustomizer> clientConfigurationBuilderCustomizers,
194-
SslBundle sslBundle) {
205+
@Nullable SslBundle sslBundle) {
195206
ClientOptions.Builder builder = initializeClientOptionsBuilder();
196207
Duration connectTimeout = getProperties().getConnectTimeout();
197208
if (connectTimeout != null) {
@@ -232,8 +243,9 @@ private ClientOptions.Builder initializeClientOptionsBuilder() {
232243
return ClientOptions.builder();
233244
}
234245

235-
private void customizeConfigurationFromUrl(LettuceClientConfiguration.LettuceClientConfigurationBuilder builder) {
236-
if (urlUsesSsl()) {
246+
private void customizeConfigurationFromUrl(LettuceClientConfiguration.LettuceClientConfigurationBuilder builder,
247+
String url) {
248+
if (urlUsesSsl(url)) {
237249
builder.useSsl();
238250
}
239251
}

module/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/PropertiesRedisConnectionDetails.java

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616

1717
package org.springframework.boot.data.redis.autoconfigure;
1818

19+
import java.util.Collections;
1920
import java.util.List;
2021

22+
import org.jspecify.annotations.Nullable;
23+
2124
import org.springframework.boot.ssl.SslBundle;
2225
import org.springframework.boot.ssl.SslBundles;
2326
import org.springframework.util.Assert;
@@ -37,21 +40,21 @@ class PropertiesRedisConnectionDetails implements RedisConnectionDetails {
3740

3841
private final RedisProperties properties;
3942

40-
private final SslBundles sslBundles;
43+
private final @Nullable SslBundles sslBundles;
4144

42-
PropertiesRedisConnectionDetails(RedisProperties properties, SslBundles sslBundles) {
45+
PropertiesRedisConnectionDetails(RedisProperties properties, @Nullable SslBundles sslBundles) {
4346
this.properties = properties;
4447
this.sslBundles = sslBundles;
4548
}
4649

4750
@Override
48-
public String getUsername() {
51+
public @Nullable String getUsername() {
4952
RedisUrl redisUrl = getRedisUrl();
5053
return (redisUrl != null) ? redisUrl.credentials().username() : this.properties.getUsername();
5154
}
5255

5356
@Override
54-
public String getPassword() {
57+
public @Nullable String getPassword() {
5558
RedisUrl redisUrl = getRedisUrl();
5659
return (redisUrl != null) ? redisUrl.credentials().password() : this.properties.getPassword();
5760
}
@@ -65,7 +68,7 @@ public Standalone getStandalone() {
6568
getSslBundle());
6669
}
6770

68-
private SslBundle getSslBundle() {
71+
private @Nullable SslBundle getSslBundle() {
6972
if (!this.properties.getSsl().isEnabled()) {
7073
return null;
7174
}
@@ -78,22 +81,25 @@ private SslBundle getSslBundle() {
7881
}
7982

8083
@Override
81-
public Sentinel getSentinel() {
84+
public @Nullable Sentinel getSentinel() {
8285
RedisProperties.Sentinel sentinel = this.properties.getSentinel();
8386
return (sentinel != null) ? new PropertiesSentinel(getStandalone().getDatabase(), sentinel) : null;
8487
}
8588

8689
@Override
87-
public Cluster getCluster() {
90+
public @Nullable Cluster getCluster() {
8891
RedisProperties.Cluster cluster = this.properties.getCluster();
8992
return (cluster != null) ? new PropertiesCluster(cluster) : null;
9093
}
9194

92-
private RedisUrl getRedisUrl() {
95+
private @Nullable RedisUrl getRedisUrl() {
9396
return RedisUrl.of(this.properties.getUrl());
9497
}
9598

96-
private List<Node> asNodes(List<String> nodes) {
99+
private List<Node> asNodes(@Nullable List<String> nodes) {
100+
if (nodes == null) {
101+
return Collections.emptyList();
102+
}
97103
return nodes.stream().map(this::asNode).toList();
98104
}
99105

@@ -121,7 +127,7 @@ public List<Node> getNodes() {
121127
}
122128

123129
@Override
124-
public SslBundle getSslBundle() {
130+
public @Nullable SslBundle getSslBundle() {
125131
return PropertiesRedisConnectionDetails.this.getSslBundle();
126132
}
127133

@@ -148,7 +154,9 @@ public int getDatabase() {
148154

149155
@Override
150156
public String getMaster() {
151-
return this.properties.getMaster();
157+
String master = this.properties.getMaster();
158+
Assert.state(master != null, "'master' must not be null");
159+
return master;
152160
}
153161

154162
@Override
@@ -157,17 +165,17 @@ public List<Node> getNodes() {
157165
}
158166

159167
@Override
160-
public String getUsername() {
168+
public @Nullable String getUsername() {
161169
return this.properties.getUsername();
162170
}
163171

164172
@Override
165-
public String getPassword() {
173+
public @Nullable String getPassword() {
166174
return this.properties.getPassword();
167175
}
168176

169177
@Override
170-
public SslBundle getSslBundle() {
178+
public @Nullable SslBundle getSslBundle() {
171179
return PropertiesRedisConnectionDetails.this.getSslBundle();
172180
}
173181

module/spring-boot-data-redis/src/main/java/org/springframework/boot/data/redis/autoconfigure/RedisConnectionConfiguration.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,21 @@
1919
import java.util.ArrayList;
2020
import java.util.List;
2121

22+
import org.jspecify.annotations.Nullable;
23+
2224
import org.springframework.beans.factory.ObjectProvider;
2325
import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails.Cluster;
2426
import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails.Node;
2527
import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails.Sentinel;
28+
import org.springframework.boot.data.redis.autoconfigure.RedisConnectionDetails.Standalone;
2629
import org.springframework.boot.data.redis.autoconfigure.RedisProperties.Pool;
2730
import org.springframework.boot.ssl.SslBundle;
2831
import org.springframework.data.redis.connection.RedisClusterConfiguration;
2932
import org.springframework.data.redis.connection.RedisNode;
3033
import org.springframework.data.redis.connection.RedisPassword;
3134
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
3235
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
36+
import org.springframework.util.Assert;
3337
import org.springframework.util.ClassUtils;
3438

3539
/**
@@ -52,11 +56,11 @@ abstract class RedisConnectionConfiguration {
5256

5357
private final RedisProperties properties;
5458

55-
private final RedisStandaloneConfiguration standaloneConfiguration;
59+
private final @Nullable RedisStandaloneConfiguration standaloneConfiguration;
5660

57-
private final RedisSentinelConfiguration sentinelConfiguration;
61+
private final @Nullable RedisSentinelConfiguration sentinelConfiguration;
5862

59-
private final RedisClusterConfiguration clusterConfiguration;
63+
private final @Nullable RedisClusterConfiguration clusterConfiguration;
6064

6165
private final RedisConnectionDetails connectionDetails;
6266

@@ -79,15 +83,17 @@ protected final RedisStandaloneConfiguration getStandaloneConfig() {
7983
return this.standaloneConfiguration;
8084
}
8185
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
82-
config.setHostName(this.connectionDetails.getStandalone().getHost());
83-
config.setPort(this.connectionDetails.getStandalone().getPort());
86+
Standalone standalone = this.connectionDetails.getStandalone();
87+
Assert.state(standalone != null, "'standalone' must not be null");
88+
config.setHostName(standalone.getHost());
89+
config.setPort(standalone.getPort());
8490
config.setUsername(this.connectionDetails.getUsername());
8591
config.setPassword(RedisPassword.of(this.connectionDetails.getPassword()));
86-
config.setDatabase(this.connectionDetails.getStandalone().getDatabase());
92+
config.setDatabase(standalone.getDatabase());
8793
return config;
8894
}
8995

90-
protected final RedisSentinelConfiguration getSentinelConfig() {
96+
protected final @Nullable RedisSentinelConfiguration getSentinelConfig() {
9197
if (this.sentinelConfiguration != null) {
9298
return this.sentinelConfiguration;
9399
}
@@ -115,7 +121,7 @@ protected final RedisSentinelConfiguration getSentinelConfig() {
115121
* Create a {@link RedisClusterConfiguration} if necessary.
116122
* @return {@literal null} if no cluster settings are set.
117123
*/
118-
protected final RedisClusterConfiguration getClusterConfiguration() {
124+
protected final @Nullable RedisClusterConfiguration getClusterConfiguration() {
119125
if (this.clusterConfiguration != null) {
120126
return this.clusterConfiguration;
121127
}
@@ -148,7 +154,7 @@ protected final RedisProperties getProperties() {
148154
return this.properties;
149155
}
150156

151-
protected SslBundle getSslBundle() {
157+
protected @Nullable SslBundle getSslBundle() {
152158
return switch (this.mode) {
153159
case STANDALONE -> (this.connectionDetails.getStandalone() != null)
154160
? this.connectionDetails.getStandalone().getSslBundle() : null;
@@ -163,8 +169,8 @@ protected final boolean isSslEnabled() {
163169
return getProperties().getSsl().isEnabled();
164170
}
165171

166-
protected final boolean urlUsesSsl() {
167-
return RedisUrl.of(this.properties.getUrl()).useSsl();
172+
protected final boolean urlUsesSsl(String url) {
173+
return RedisUrl.of(url).useSsl();
168174
}
169175

170176
protected boolean isPoolEnabled(Pool pool) {

0 commit comments

Comments
 (0)