diff --git a/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionConfiguration.java b/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionConfiguration.java
index 294c45ff..cb9ec11d 100644
--- a/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionConfiguration.java
+++ b/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionConfiguration.java
@@ -16,7 +16,6 @@
package io.r2dbc.postgresql;
-
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.r2dbc.postgresql.client.DefaultHostnameVerifier;
@@ -26,6 +25,7 @@
import io.r2dbc.postgresql.extension.CodecRegistrar;
import io.r2dbc.postgresql.extension.Extension;
import io.r2dbc.postgresql.util.Assert;
+import io.r2dbc.spi.ConnectionFactoryOptions;
import reactor.netty.tcp.SslProvider;
import reactor.util.annotation.Nullable;
@@ -39,6 +39,26 @@
import java.util.function.Function;
import java.util.function.Supplier;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.APPLICATION_NAME;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.AUTODETECT_EXTENSIONS;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.FORCE_BINARY;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.OPTIONS;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.SCHEMA;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.SOCKET;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.SSL_CERT;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.SSL_CONTEXT_BUILDER_CUSTOMIZER;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.SSL_HOSTNAME_VERIFIER;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.SSL_KEY;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.SSL_MODE;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.SSL_PASSWORD;
+import static io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider.SSL_ROOT_CERT;
+import static io.r2dbc.spi.ConnectionFactoryOptions.CONNECT_TIMEOUT;
+import static io.r2dbc.spi.ConnectionFactoryOptions.DATABASE;
+import static io.r2dbc.spi.ConnectionFactoryOptions.HOST;
+import static io.r2dbc.spi.ConnectionFactoryOptions.PASSWORD;
+import static io.r2dbc.spi.ConnectionFactoryOptions.PORT;
+import static io.r2dbc.spi.ConnectionFactoryOptions.SSL;
+import static io.r2dbc.spi.ConnectionFactoryOptions.USER;
import static reactor.netty.tcp.SslProvider.DefaultConfigurationType.TCP;
/**
@@ -108,33 +128,31 @@ public static Builder builder() {
return new Builder();
}
- private static String repeat(int length, String character) {
-
- StringBuilder builder = new StringBuilder();
-
- for (int i = 0; i < length; i++) {
- builder.append(character);
- }
-
- return builder.toString();
+ /**
+ * Returns a new {@link Builder} configured with the given {@link ConnectionFactoryOptions}.
+ *
+ * @return a {@link Builder}
+ */
+ public static Builder builder(ConnectionFactoryOptions connectionFactoryOptions) {
+ return Builder.fromConnectionFactoryOptions(connectionFactoryOptions);
}
@Override
public String toString() {
return "PostgresqlConnectionConfiguration{" +
- "applicationName='" + this.applicationName + '\'' +
- ", autodetectExtensions='" + this.autodetectExtensions + '\'' +
- ", connectTimeout=" + this.connectTimeout +
- ", database='" + this.database + '\'' +
- ", extensions=" + this.extensions +
- ", forceBinary='" + this.forceBinary + '\'' +
- ", host='" + this.host + '\'' +
- ", options='" + this.options + '\'' +
- ", password='" + repeat(this.password != null ? this.password.length() : 0, "*") + '\'' +
- ", port=" + this.port +
- ", schema='" + this.schema + '\'' +
- ", username='" + this.username + '\'' +
- '}';
+ "applicationName='" + this.applicationName + '\'' +
+ ", autodetectExtensions='" + this.autodetectExtensions + '\'' +
+ ", connectTimeout=" + this.connectTimeout +
+ ", database='" + this.database + '\'' +
+ ", extensions=" + this.extensions +
+ ", forceBinary='" + this.forceBinary + '\'' +
+ ", host='" + this.host + '\'' +
+ ", options='" + this.options + '\'' +
+ ", password='" + obfuscate(this.password != null ? this.password.length() : 0) + '\'' +
+ ", port=" + this.port +
+ ", schema='" + this.schema + '\'' +
+ ", username='" + this.username + '\'' +
+ '}';
}
String getApplicationName() {
@@ -226,6 +244,17 @@ SSLConfig getSslConfig() {
return this.sslConfig;
}
+ private static String obfuscate(int length) {
+
+ StringBuilder builder = new StringBuilder();
+
+ for (int i = 0; i < length; i++) {
+ builder.append("*");
+ }
+
+ return builder.toString();
+ }
+
/**
* A builder for {@link PostgresqlConnectionConfiguration} instances.
*
@@ -287,6 +316,60 @@ public static final class Builder {
private Builder() {
}
+ /**
+ * Configure the builder with the given {@link ConnectionFactoryOptions}.
+ *
+ * @param connectionFactoryOptions {@link ConnectionFactoryOptions}
+ * @return this {@link Builder}
+ * @throws IllegalArgumentException if {@code connectionFactoryOptions} is {@code null}
+ */
+ private static Builder fromConnectionFactoryOptions(ConnectionFactoryOptions connectionFactoryOptions) {
+
+ Assert.requireNonNull(connectionFactoryOptions, "connectionFactoryOptions must not be null");
+
+ Builder builder = new Builder();
+
+ builder.connectTimeout(connectionFactoryOptions.getValue(CONNECT_TIMEOUT));
+ builder.database(connectionFactoryOptions.getValue(DATABASE));
+ builder.password(connectionFactoryOptions.getValue(PASSWORD));
+ builder.schema(connectionFactoryOptions.getValue(SCHEMA));
+ builder.username(connectionFactoryOptions.getRequiredValue(USER));
+
+ String applicationName = connectionFactoryOptions.getValue(APPLICATION_NAME);
+ if (applicationName != null) {
+ builder.applicationName(applicationName);
+ }
+
+ Object autodetectExtensions = connectionFactoryOptions.getValue(AUTODETECT_EXTENSIONS);
+ if (autodetectExtensions != null) {
+ builder.autodetectExtensions(convertToBoolean(autodetectExtensions));
+ }
+
+ Integer port = connectionFactoryOptions.getValue(PORT);
+ if (port != null) {
+ builder.port(port);
+ }
+
+ Object forceBinary = connectionFactoryOptions.getValue(FORCE_BINARY);
+ if (forceBinary != null) {
+ builder.forceBinary(convertToBoolean(forceBinary));
+ }
+
+ Map options = connectionFactoryOptions.getValue(OPTIONS);
+ if (options != null) {
+ builder.options(options);
+ }
+
+ if (isUsingTcp(connectionFactoryOptions)) {
+ builder.host(connectionFactoryOptions.getRequiredValue(HOST));
+ setupSsl(builder, connectionFactoryOptions);
+ } else {
+ builder.socket(connectionFactoryOptions.getRequiredValue(SOCKET));
+ }
+
+ return builder;
+ }
+
/**
* Configure the application name. Defaults to {@code postgresql-r2dbc}.
*
@@ -505,7 +588,7 @@ public Builder sslCert(String sslCert) {
/**
* Configure ssl HostnameVerifier.
*
- * @param sslHostnameVerifier {@link javax.net.ssl.HostnameVerifier}
+ * @param sslHostnameVerifier {@link HostnameVerifier}
* @return this {@link Builder}
*/
public Builder sslHostnameVerifier(HostnameVerifier sslHostnameVerifier) {
@@ -546,31 +629,6 @@ public Builder sslPassword(@Nullable CharSequence sslPassword) {
return this;
}
- @Override
- public String toString() {
- return "Builder{" +
- "applicationName='" + this.applicationName + '\'' +
- ", autodetectExtensions='" + this.autodetectExtensions + '\'' +
- ", connectTimeout='" + this.connectTimeout + '\'' +
- ", database='" + this.database + '\'' +
- ", extensions='" + this.extensions + '\'' +
- ", forceBinary='" + this.forceBinary + '\'' +
- ", host='" + this.host + '\'' +
- ", parameters='" + this.options + '\'' +
- ", password='" + repeat(this.password != null ? this.password.length() : 0, "*") + '\'' +
- ", port=" + this.port +
- ", schema='" + this.schema + '\'' +
- ", username='" + this.username + '\'' +
- ", socket='" + this.socket + '\'' +
- ", sslContextBuilderCustomizer='" + this.sslContextBuilderCustomizer + '\'' +
- ", sslMode='" + this.sslMode + '\'' +
- ", sslRootCert='" + this.sslRootCert + '\'' +
- ", sslCert='" + this.sslCert + '\'' +
- ", sslKey='" + this.sslKey + '\'' +
- ", sslHostnameVerifier='" + this.sslHostnameVerifier + '\'' +
- '}';
- }
-
/**
* Configure ssl root cert for server certificate validation.
*
@@ -594,6 +652,31 @@ public Builder username(String username) {
return this;
}
+ @Override
+ public String toString() {
+ return "Builder{" +
+ "applicationName='" + this.applicationName + '\'' +
+ ", autodetectExtensions='" + this.autodetectExtensions + '\'' +
+ ", connectTimeout='" + this.connectTimeout + '\'' +
+ ", database='" + this.database + '\'' +
+ ", extensions='" + this.extensions + '\'' +
+ ", forceBinary='" + this.forceBinary + '\'' +
+ ", host='" + this.host + '\'' +
+ ", parameters='" + this.options + '\'' +
+ ", password='" + obfuscate(this.password != null ? this.password.length() : 0) + '\'' +
+ ", port=" + this.port +
+ ", schema='" + this.schema + '\'' +
+ ", username='" + this.username + '\'' +
+ ", socket='" + this.socket + '\'' +
+ ", sslContextBuilderCustomizer='" + this.sslContextBuilderCustomizer + '\'' +
+ ", sslMode='" + this.sslMode + '\'' +
+ ", sslRootCert='" + this.sslRootCert + '\'' +
+ ", sslCert='" + this.sslCert + '\'' +
+ ", sslKey='" + this.sslKey + '\'' +
+ ", sslHostnameVerifier='" + this.sslHostnameVerifier + '\'' +
+ '}';
+ }
+
private SSLConfig createSslConfig() {
if (this.socket != null || this.sslMode == SSLMode.DISABLE) {
return SSLConfig.disabled();
@@ -618,23 +701,23 @@ private Supplier createSslProvider() {
// Emulate Libpq behavior
// Determining the default file location
- String pathsep = System.getProperty("file.separator");
- String defaultdir;
+ String pathSeparator = System.getProperty("file.separator");
+ String defaultDir;
if (System.getProperty("os.name").toLowerCase().contains("windows")) { // It is Windows
- defaultdir = System.getenv("APPDATA") + pathsep + "postgresql" + pathsep;
+ defaultDir = System.getenv("APPDATA") + pathSeparator + "postgresql" + pathSeparator;
} else {
- defaultdir = System.getProperty("user.home") + pathsep + ".postgresql" + pathsep;
+ defaultDir = System.getProperty("user.home") + pathSeparator + ".postgresql" + pathSeparator;
}
if (sslCert == null) {
- String pathname = defaultdir + "postgresql.crt";
+ String pathname = defaultDir + "postgresql.crt";
if (new File(pathname).exists()) {
sslCert = pathname;
}
}
if (sslKey == null) {
- String pathname = defaultdir + "postgresql.pk8";
+ String pathname = defaultDir + "postgresql.pk8";
if (new File(pathname).exists()) {
sslKey = pathname;
}
@@ -645,11 +728,80 @@ private Supplier createSslProvider() {
sslContextBuilder.keyManager(new File(sslCert), new File(sslKey), sslPassword);
}
-
return () -> SslProvider.builder()
.sslContext(this.sslContextBuilderCustomizer.apply(sslContextBuilder))
.defaultConfiguration(TCP)
.build();
}
+
+ private static void setupSsl(Builder builder, ConnectionFactoryOptions connectionFactoryOptions) {
+ Boolean ssl = connectionFactoryOptions.getValue(SSL);
+ if (ssl != null && ssl) {
+ builder.enableSsl();
+ }
+
+ Object sslMode = connectionFactoryOptions.getValue(SSL_MODE);
+ if (sslMode != null) {
+ if (sslMode instanceof String) {
+ builder.sslMode(SSLMode.fromValue(sslMode.toString()));
+ } else {
+ builder.sslMode((SSLMode) sslMode);
+ }
+ }
+
+ String sslRootCert = connectionFactoryOptions.getValue(SSL_ROOT_CERT);
+ if (sslRootCert != null) {
+ builder.sslRootCert(sslRootCert);
+ }
+
+ String sslCert = connectionFactoryOptions.getValue(SSL_CERT);
+ if (sslCert != null) {
+ builder.sslCert(sslCert);
+ }
+
+ String sslKey = connectionFactoryOptions.getValue(SSL_KEY);
+ if (sslKey != null) {
+ builder.sslKey(sslKey);
+ }
+
+ String sslPassword = connectionFactoryOptions.getValue(SSL_PASSWORD);
+ if (sslPassword != null) {
+ builder.sslPassword(sslPassword);
+ }
+
+ if (connectionFactoryOptions.hasOption(SSL_CONTEXT_BUILDER_CUSTOMIZER)) {
+ builder.sslContextBuilderCustomizer(connectionFactoryOptions.getRequiredValue(SSL_CONTEXT_BUILDER_CUSTOMIZER));
+ }
+
+ setSslHostnameVerifier(builder, connectionFactoryOptions);
+ }
+
+ private static void setSslHostnameVerifier(Builder builder, ConnectionFactoryOptions connectionFactoryOptions) {
+ Object sslHostnameVerifier = connectionFactoryOptions.getValue(SSL_HOSTNAME_VERIFIER);
+ if (sslHostnameVerifier != null) {
+
+ if (sslHostnameVerifier instanceof String) {
+
+ try {
+ Class> verifierClass = Class.forName((String) sslHostnameVerifier);
+ Object verifier = verifierClass.getConstructor().newInstance();
+
+ builder.sslHostnameVerifier((HostnameVerifier) verifier);
+ } catch (ReflectiveOperationException e) {
+ throw new IllegalStateException("Cannot instantiate " + sslHostnameVerifier, e);
+ }
+ } else {
+ builder.sslHostnameVerifier((HostnameVerifier) sslHostnameVerifier);
+ }
+ }
+ }
+
+ private static boolean isUsingTcp(ConnectionFactoryOptions connectionFactoryOptions) {
+ return !connectionFactoryOptions.hasOption(SOCKET);
+ }
+
+ private static boolean convertToBoolean(Object value) {
+ return value instanceof Boolean ? (boolean) value : Boolean.parseBoolean(value.toString());
+ }
}
}
diff --git a/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryProvider.java b/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryProvider.java
index 72abb765..0515e746 100644
--- a/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryProvider.java
+++ b/src/main/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryProvider.java
@@ -27,14 +27,7 @@
import java.util.Map;
import java.util.function.Function;
-import static io.r2dbc.spi.ConnectionFactoryOptions.CONNECT_TIMEOUT;
-import static io.r2dbc.spi.ConnectionFactoryOptions.DATABASE;
import static io.r2dbc.spi.ConnectionFactoryOptions.DRIVER;
-import static io.r2dbc.spi.ConnectionFactoryOptions.HOST;
-import static io.r2dbc.spi.ConnectionFactoryOptions.PASSWORD;
-import static io.r2dbc.spi.ConnectionFactoryOptions.PORT;
-import static io.r2dbc.spi.ConnectionFactoryOptions.SSL;
-import static io.r2dbc.spi.ConnectionFactoryOptions.USER;
/**
* An implementation of {@link ConnectionFactoryProvider} for creating {@link PostgresqlConnectionFactory}s.
@@ -118,114 +111,12 @@ public final class PostgresqlConnectionFactoryProvider implements ConnectionFact
@Override
public PostgresqlConnectionFactory create(ConnectionFactoryOptions connectionFactoryOptions) {
- return new PostgresqlConnectionFactory(createConfiguration(connectionFactoryOptions));
- }
- private static PostgresqlConnectionConfiguration createConfiguration(ConnectionFactoryOptions connectionFactoryOptions) {
- Assert.requireNonNull(connectionFactoryOptions, "connectionFactoryOptions must not be null");
+ PostgresqlConnectionConfiguration configuration = PostgresqlConnectionConfiguration
+ .builder(connectionFactoryOptions)
+ .build();
- boolean tcp;
- PostgresqlConnectionConfiguration.Builder builder = PostgresqlConnectionConfiguration.builder();
-
- String applicationName = connectionFactoryOptions.getValue(APPLICATION_NAME);
- if (applicationName != null) {
- builder.applicationName(applicationName);
- }
-
- Object autodetectExtensions = connectionFactoryOptions.getValue(AUTODETECT_EXTENSIONS);
- if (autodetectExtensions != null) {
- builder.autodetectExtensions(convertToBoolean(autodetectExtensions));
- }
-
- builder.connectTimeout(connectionFactoryOptions.getValue(CONNECT_TIMEOUT));
- builder.database(connectionFactoryOptions.getValue(DATABASE));
-
- if (connectionFactoryOptions.hasOption(SOCKET)) {
- tcp = false;
- builder.socket(connectionFactoryOptions.getRequiredValue(SOCKET));
- } else {
- tcp = true;
- builder.host(connectionFactoryOptions.getRequiredValue(HOST));
- }
- builder.password(connectionFactoryOptions.getValue(PASSWORD));
- builder.schema(connectionFactoryOptions.getValue(SCHEMA));
- builder.username(connectionFactoryOptions.getRequiredValue(USER));
-
- Integer port = connectionFactoryOptions.getValue(PORT);
- if (port != null) {
- builder.port(port);
- }
-
- Object forceBinary = connectionFactoryOptions.getValue(FORCE_BINARY);
-
- if (forceBinary != null) {
- builder.forceBinary(convertToBoolean(forceBinary));
- }
-
- Map options = connectionFactoryOptions.getValue(OPTIONS);
- if (options != null) {
- builder.options(options);
- }
-
- if (tcp) {
- Boolean ssl = connectionFactoryOptions.getValue(SSL);
- if (ssl != null && ssl) {
- builder.enableSsl();
- }
-
- Object sslMode = connectionFactoryOptions.getValue(SSL_MODE);
- if (sslMode != null) {
- if (sslMode instanceof String) {
- builder.sslMode(SSLMode.fromValue(sslMode.toString()));
- } else {
- builder.sslMode((SSLMode) sslMode);
- }
- }
-
- String sslRootCert = connectionFactoryOptions.getValue(SSL_ROOT_CERT);
- if (sslRootCert != null) {
- builder.sslRootCert(sslRootCert);
- }
-
- String sslCert = connectionFactoryOptions.getValue(SSL_CERT);
- if (sslCert != null) {
- builder.sslCert(sslCert);
- }
-
- String sslKey = connectionFactoryOptions.getValue(SSL_KEY);
- if (sslKey != null) {
- builder.sslKey(sslKey);
- }
-
- String sslPassword = connectionFactoryOptions.getValue(SSL_PASSWORD);
- if (sslPassword != null) {
- builder.sslPassword(sslPassword);
- }
-
- Object sslHostnameVerifier = connectionFactoryOptions.getValue(SSL_HOSTNAME_VERIFIER);
- if (sslHostnameVerifier != null) {
-
- if (sslHostnameVerifier instanceof String) {
-
- try {
- Class> verifierClass = Class.forName((String) sslHostnameVerifier);
- Object verifier = verifierClass.getConstructor().newInstance();
-
- builder.sslHostnameVerifier((HostnameVerifier) verifier);
- } catch (ReflectiveOperationException e) {
- throw new IllegalStateException("Cannot instantiate " + sslHostnameVerifier, e);
- }
- } else {
- builder.sslHostnameVerifier((HostnameVerifier) sslHostnameVerifier);
- }
- }
-
- if (connectionFactoryOptions.hasOption(SSL_CONTEXT_BUILDER_CUSTOMIZER)) {
- builder.sslContextBuilderCustomizer(connectionFactoryOptions.getRequiredValue(SSL_CONTEXT_BUILDER_CUSTOMIZER));
- }
- }
-
- return builder.build();
+ return new PostgresqlConnectionFactory(configuration);
}
@Override
@@ -240,8 +131,4 @@ public boolean supports(ConnectionFactoryOptions connectionFactoryOptions) {
String driver = connectionFactoryOptions.getValue(DRIVER);
return driver != null && (driver.equals(POSTGRESQL_DRIVER) || driver.equals(LEGACY_POSTGRESQL_DRIVER));
}
-
- private static boolean convertToBoolean(Object value) {
- return value instanceof Boolean ? (boolean) value : Boolean.parseBoolean(value.toString());
- }
}