Browse Source

Improve null-safety of module/spring-boot-r2dbc

See gh-46926
pull/46973/head
Moritz Halbritter 4 months ago
parent
commit
6c288c9def
  1. 39
      module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/autoconfigure/R2dbcAutoConfiguration.java
  2. 14
      module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/ClickHouseEnvironment.java
  3. 5
      module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MariaDbEnvironment.java
  4. 7
      module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/MySqlEnvironment.java
  5. 14
      module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/OracleEnvironment.java
  6. 5
      module/spring-boot-r2dbc/src/main/java/org/springframework/boot/r2dbc/docker/compose/PostgresEnvironment.java

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

@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
package org.springframework.boot.r2dbc.autoconfigure;
import java.util.function.Predicate;
import java.util.function.Supplier;
import io.r2dbc.spi.ConnectionFactory;
@ -34,6 +33,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnResource; @@ -34,6 +33,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnResource;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@ -72,26 +72,43 @@ public final class R2dbcAutoConfiguration { @@ -72,26 +72,43 @@ public final class R2dbcAutoConfiguration {
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
ConnectionFactoryOptions urlOptions = ConnectionFactoryOptions.parse(this.properties.getUrl());
String url = this.properties.getUrl();
Assert.state(url != null, "'url' must not be null");
ConnectionFactoryOptions urlOptions = ConnectionFactoryOptions.parse(url);
Builder optionsBuilder = urlOptions.mutate();
configureIf(optionsBuilder, urlOptions, ConnectionFactoryOptions.USER, this.properties::getUsername,
StringUtils::hasText);
configureIf(optionsBuilder, urlOptions, ConnectionFactoryOptions.PASSWORD, this.properties::getPassword,
StringUtils::hasText);
configureIf(optionsBuilder, urlOptions, ConnectionFactoryOptions.DATABASE,
() -> determineDatabaseName(this.properties), StringUtils::hasText);
configureUser(optionsBuilder, urlOptions);
configurePassword(optionsBuilder, urlOptions);
configureDatabase(optionsBuilder, urlOptions);
this.properties.getProperties().forEach((key, value) -> optionsBuilder.option(Option.valueOf(key), value));
return optionsBuilder.build();
}
// Lambda isn't detected with the correct nullability
@SuppressWarnings("NullAway")
private void configureDatabase(Builder optionsBuilder, ConnectionFactoryOptions urlOptions) {
configureIf(optionsBuilder, urlOptions, ConnectionFactoryOptions.DATABASE,
() -> determineDatabaseName(this.properties));
}
// Lambda isn't detected with the correct nullability
@SuppressWarnings("NullAway")
private void configurePassword(Builder optionsBuilder, ConnectionFactoryOptions urlOptions) {
configureIf(optionsBuilder, urlOptions, ConnectionFactoryOptions.PASSWORD, this.properties::getPassword);
}
// Lambda isn't detected with the correct nullability
@SuppressWarnings("NullAway")
private void configureUser(Builder optionsBuilder, ConnectionFactoryOptions urlOptions) {
configureIf(optionsBuilder, urlOptions, ConnectionFactoryOptions.USER, this.properties::getUsername);
}
private <T extends CharSequence> void configureIf(Builder optionsBuilder,
ConnectionFactoryOptions originalOptions, Option<T> option, Supplier<T> valueSupplier,
Predicate<T> setIf) {
ConnectionFactoryOptions originalOptions, Option<T> option, Supplier<@Nullable T> valueSupplier) {
if (originalOptions.hasOption(option)) {
return;
}
T value = valueSupplier.get();
if (setIf.test(value)) {
if (StringUtils.hasText(value)) {
optionsBuilder.option(option, value);
}
}

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

@ -37,9 +37,19 @@ class ClickHouseEnvironment { @@ -37,9 +37,19 @@ class ClickHouseEnvironment {
private final String database;
ClickHouseEnvironment(Map<String, @Nullable String> env) {
this.username = env.getOrDefault("CLICKHOUSE_USER", "default");
this.username = extractUsername(env);
this.password = extractPassword(env);
this.database = env.getOrDefault("CLICKHOUSE_DB", "default");
this.database = extractDatabase(env);
}
private static String extractDatabase(Map<String, @Nullable String> env) {
String result = env.get("CLICKHOUSE_DB");
return (result != null) ? result : "default";
}
private static String extractUsername(Map<String, @Nullable String> env) {
String result = env.get("CLICKHOUSE_USER");
return (result != null) ? result : "default";
}
private String extractPassword(Map<String, @Nullable String> env) {

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

@ -47,7 +47,10 @@ class MariaDbEnvironment { @@ -47,7 +47,10 @@ class MariaDbEnvironment {
private String extractUsername(Map<String, @Nullable String> env) {
String user = env.get("MARIADB_USER");
return (user != null) ? user : env.getOrDefault("MYSQL_USER", "root");
if (user == null) {
user = env.get("MYSQL_USER");
}
return (user != null) ? user : "root";
}
private String extractPassword(Map<String, @Nullable String> env) {

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

@ -40,11 +40,16 @@ class MySqlEnvironment { @@ -40,11 +40,16 @@ class MySqlEnvironment {
private final String database;
MySqlEnvironment(Map<String, @Nullable String> env) {
this.username = env.getOrDefault("MYSQL_USER", "root");
this.username = extractUsername(env);
this.password = extractPassword(env);
this.database = extractDatabase(env);
}
private static String extractUsername(Map<String, @Nullable String> env) {
String result = env.get("MYSQL_USER");
return (result != null) ? result : "root";
}
private String extractPassword(Map<String, @Nullable String> env) {
Assert.state(!env.containsKey("MYSQL_RANDOM_ROOT_PASSWORD"), "MYSQL_RANDOM_ROOT_PASSWORD is not supported");
boolean allowEmpty = env.containsKey("MYSQL_ALLOW_EMPTY_PASSWORD") || env.containsKey("ALLOW_EMPTY_PASSWORD");

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

@ -37,9 +37,19 @@ class OracleEnvironment { @@ -37,9 +37,19 @@ class OracleEnvironment {
private final String database;
OracleEnvironment(Map<String, @Nullable String> env, String defaultDatabase) {
this.username = env.getOrDefault("APP_USER", "system");
this.username = extractUsername(env);
this.password = extractPassword(env);
this.database = env.getOrDefault("ORACLE_DATABASE", defaultDatabase);
this.database = extractDatabase(env, defaultDatabase);
}
private static String extractDatabase(Map<String, @Nullable String> env, String defaultDatabase) {
String result = env.get("ORACLE_DATABASE");
return (result != null) ? result : defaultDatabase;
}
private static String extractUsername(Map<String, @Nullable String> env) {
String result = env.get("APP_USER");
return (result != null) ? result : "system";
}
private String extractPassword(Map<String, @Nullable String> env) {

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

@ -57,8 +57,9 @@ class PostgresEnvironment { @@ -57,8 +57,9 @@ class PostgresEnvironment {
private String extract(Map<String, @Nullable String> env, String[] keys, String defaultValue) {
for (String key : keys) {
if (env.containsKey(key)) {
return env.get(key);
String value = env.get(key);
if (value != null) {
return value;
}
}
return defaultValue;

Loading…
Cancel
Save