Skip to content

Commit 6c288c9

Browse files
committed
Improve null-safety of module/spring-boot-r2dbc
See gh-46926
1 parent 1157a30 commit 6c288c9

File tree

6 files changed

+65
-19
lines changed

6 files changed

+65
-19
lines changed

module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcAutoConfiguration.java

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.boot.r2dbc.autoconfigure;
1818

19-
import java.util.function.Predicate;
2019
import java.util.function.Supplier;
2120

2221
import io.r2dbc.spi.ConnectionFactory;
@@ -34,6 +33,7 @@
3433
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3534
import org.springframework.context.annotation.Bean;
3635
import org.springframework.context.annotation.Import;
36+
import org.springframework.util.Assert;
3737
import org.springframework.util.StringUtils;
3838

3939
/**
@@ -72,26 +72,43 @@ static class PropertiesR2dbcConnectionDetails implements R2dbcConnectionDetails
7272

7373
@Override
7474
public ConnectionFactoryOptions getConnectionFactoryOptions() {
75-
ConnectionFactoryOptions urlOptions = ConnectionFactoryOptions.parse(this.properties.getUrl());
75+
String url = this.properties.getUrl();
76+
Assert.state(url != null, "'url' must not be null");
77+
ConnectionFactoryOptions urlOptions = ConnectionFactoryOptions.parse(url);
7678
Builder optionsBuilder = urlOptions.mutate();
77-
configureIf(optionsBuilder, urlOptions, ConnectionFactoryOptions.USER, this.properties::getUsername,
78-
StringUtils::hasText);
79-
configureIf(optionsBuilder, urlOptions, ConnectionFactoryOptions.PASSWORD, this.properties::getPassword,
80-
StringUtils::hasText);
81-
configureIf(optionsBuilder, urlOptions, ConnectionFactoryOptions.DATABASE,
82-
() -> determineDatabaseName(this.properties), StringUtils::hasText);
79+
configureUser(optionsBuilder, urlOptions);
80+
configurePassword(optionsBuilder, urlOptions);
81+
configureDatabase(optionsBuilder, urlOptions);
8382
this.properties.getProperties().forEach((key, value) -> optionsBuilder.option(Option.valueOf(key), value));
8483
return optionsBuilder.build();
8584
}
8685

86+
// Lambda isn't detected with the correct nullability
87+
@SuppressWarnings("NullAway")
88+
private void configureDatabase(Builder optionsBuilder, ConnectionFactoryOptions urlOptions) {
89+
configureIf(optionsBuilder, urlOptions, ConnectionFactoryOptions.DATABASE,
90+
() -> determineDatabaseName(this.properties));
91+
}
92+
93+
// Lambda isn't detected with the correct nullability
94+
@SuppressWarnings("NullAway")
95+
private void configurePassword(Builder optionsBuilder, ConnectionFactoryOptions urlOptions) {
96+
configureIf(optionsBuilder, urlOptions, ConnectionFactoryOptions.PASSWORD, this.properties::getPassword);
97+
}
98+
99+
// Lambda isn't detected with the correct nullability
100+
@SuppressWarnings("NullAway")
101+
private void configureUser(Builder optionsBuilder, ConnectionFactoryOptions urlOptions) {
102+
configureIf(optionsBuilder, urlOptions, ConnectionFactoryOptions.USER, this.properties::getUsername);
103+
}
104+
87105
private <T extends CharSequence> void configureIf(Builder optionsBuilder,
88-
ConnectionFactoryOptions originalOptions, Option<T> option, Supplier<T> valueSupplier,
89-
Predicate<T> setIf) {
106+
ConnectionFactoryOptions originalOptions, Option<T> option, Supplier<@Nullable T> valueSupplier) {
90107
if (originalOptions.hasOption(option)) {
91108
return;
92109
}
93110
T value = valueSupplier.get();
94-
if (setIf.test(value)) {
111+
if (StringUtils.hasText(value)) {
95112
optionsBuilder.option(option, value);
96113
}
97114
}

module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseEnvironment.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,19 @@ class ClickHouseEnvironment {
3737
private final String database;
3838

3939
ClickHouseEnvironment(Map<String, @Nullable String> env) {
40-
this.username = env.getOrDefault("CLICKHOUSE_USER", "default");
40+
this.username = extractUsername(env);
4141
this.password = extractPassword(env);
42-
this.database = env.getOrDefault("CLICKHOUSE_DB", "default");
42+
this.database = extractDatabase(env);
43+
}
44+
45+
private static String extractDatabase(Map<String, @Nullable String> env) {
46+
String result = env.get("CLICKHOUSE_DB");
47+
return (result != null) ? result : "default";
48+
}
49+
50+
private static String extractUsername(Map<String, @Nullable String> env) {
51+
String result = env.get("CLICKHOUSE_USER");
52+
return (result != null) ? result : "default";
4353
}
4454

4555
private String extractPassword(Map<String, @Nullable String> env) {

module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironment.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ class MariaDbEnvironment {
4747

4848
private String extractUsername(Map<String, @Nullable String> env) {
4949
String user = env.get("MARIADB_USER");
50-
return (user != null) ? user : env.getOrDefault("MYSQL_USER", "root");
50+
if (user == null) {
51+
user = env.get("MYSQL_USER");
52+
}
53+
return (user != null) ? user : "root";
5154
}
5255

5356
private String extractPassword(Map<String, @Nullable String> env) {

module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MySqlEnvironment.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,16 @@ class MySqlEnvironment {
4040
private final String database;
4141

4242
MySqlEnvironment(Map<String, @Nullable String> env) {
43-
this.username = env.getOrDefault("MYSQL_USER", "root");
43+
this.username = extractUsername(env);
4444
this.password = extractPassword(env);
4545
this.database = extractDatabase(env);
4646
}
4747

48+
private static String extractUsername(Map<String, @Nullable String> env) {
49+
String result = env.get("MYSQL_USER");
50+
return (result != null) ? result : "root";
51+
}
52+
4853
private String extractPassword(Map<String, @Nullable String> env) {
4954
Assert.state(!env.containsKey("MYSQL_RANDOM_ROOT_PASSWORD"), "MYSQL_RANDOM_ROOT_PASSWORD is not supported");
5055
boolean allowEmpty = env.containsKey("MYSQL_ALLOW_EMPTY_PASSWORD") || env.containsKey("ALLOW_EMPTY_PASSWORD");

module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleEnvironment.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,19 @@ class OracleEnvironment {
3737
private final String database;
3838

3939
OracleEnvironment(Map<String, @Nullable String> env, String defaultDatabase) {
40-
this.username = env.getOrDefault("APP_USER", "system");
40+
this.username = extractUsername(env);
4141
this.password = extractPassword(env);
42-
this.database = env.getOrDefault("ORACLE_DATABASE", defaultDatabase);
42+
this.database = extractDatabase(env, defaultDatabase);
43+
}
44+
45+
private static String extractDatabase(Map<String, @Nullable String> env, String defaultDatabase) {
46+
String result = env.get("ORACLE_DATABASE");
47+
return (result != null) ? result : defaultDatabase;
48+
}
49+
50+
private static String extractUsername(Map<String, @Nullable String> env) {
51+
String result = env.get("APP_USER");
52+
return (result != null) ? result : "system";
4353
}
4454

4555
private String extractPassword(Map<String, @Nullable String> env) {

module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/PostgresEnvironment.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ class PostgresEnvironment {
5757

5858
private String extract(Map<String, @Nullable String> env, String[] keys, String defaultValue) {
5959
for (String key : keys) {
60-
if (env.containsKey(key)) {
61-
return env.get(key);
60+
String value = env.get(key);
61+
if (value != null) {
62+
return value;
6263
}
6364
}
6465
return defaultValue;

0 commit comments

Comments
 (0)