Skip to content

Commit

Permalink
Added Option to set reactor.netty.resources.ConnectionProvider
Browse files Browse the repository at this point in the history
Signed-off-by: Paul Johe <[email protected]>
  • Loading branch information
paul-kraftlauget committed Jan 31, 2025
1 parent 3449c84 commit 0e43966
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ Mono<Connection> connectionMono = Mono.from(connectionFactory.create());
| `trustStoreType` | Type of the TrustStore. Defaults to `KeyStore.getDefaultType()`. _(Optional)_
| `trustStore` | Path to the certificate TrustStore file. _(Optional)_
| `trustStorePassword` | Password used to check the integrity of the TrustStore data. _(Optional)_
| `connectionProvider` | Set the `reactor.netty.resources.ConnectionProvider` to be used when creating the connection. Defaults to `ConnectionProvider.newConnection()`. _(Optional)_ |


**Programmatic Configuration**
Expand Down
39 changes: 33 additions & 6 deletions src/main/java/io/r2dbc/mssql/MssqlConnectionConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,16 @@ public final class MssqlConnectionConfiguration {

private final String username;

@Nullable
private final ConnectionProvider connectionProvider;

private MssqlConnectionConfiguration(@Nullable String applicationName, @Nullable UUID connectionId, Duration connectTimeout, @Nullable String database, String host, String hostNameInCertificate,
@Nullable Duration lockWaitTimeout, CharSequence password, Predicate<String> preferCursoredExecution, int port, boolean sendStringParametersAsUnicode,
boolean ssl,
Function<SslContextBuilder, SslContextBuilder> sslContextBuilderCustomizer,
@Nullable Function<SslContextBuilder, SslContextBuilder> sslTunnelSslContextBuilderCustomizer, boolean tcpKeepAlive, boolean tcpNoDelay,
boolean trustServerCertificate, @Nullable File trustStore, @Nullable String trustStoreType,
@Nullable char[] trustStorePassword, String username) {
@Nullable char[] trustStorePassword, String username, @Nullable ConnectionProvider connectionProvider) {

this.applicationName = applicationName;
this.connectionId = connectionId;
Expand All @@ -148,6 +151,7 @@ private MssqlConnectionConfiguration(@Nullable String applicationName, @Nullable
this.trustStoreType = trustStoreType;
this.trustStorePassword = trustStorePassword;
this.username = Assert.requireNonNull(username, "username must not be null");
this.connectionProvider = connectionProvider;
}

/**
Expand Down Expand Up @@ -185,12 +189,14 @@ MssqlConnectionConfiguration withRedirect(Redirect redirect) {
return new MssqlConnectionConfiguration(this.applicationName, this.connectionId, this.connectTimeout, this.database, redirectServerName, hostNameInCertificate, this.lockWaitTimeout,
this.password,
this.preferCursoredExecution, redirect.getPort(), this.sendStringParametersAsUnicode, this.ssl, this.sslContextBuilderCustomizer,
this.sslTunnelSslContextBuilderCustomizer, this.tcpKeepAlive, this.tcpNoDelay, this.trustServerCertificate, this.trustStore, this.trustStoreType, this.trustStorePassword, this.username);
this.sslTunnelSslContextBuilderCustomizer, this.tcpKeepAlive, this.tcpNoDelay, this.trustServerCertificate, this.trustStore, this.trustStoreType, this.trustStorePassword, this.username,
this.connectionProvider);
}

ClientConfiguration toClientConfiguration() {
return new DefaultClientConfiguration(this.connectTimeout, this.host, this.hostNameInCertificate, this.port, this.ssl, this.sslContextBuilderCustomizer,
this.sslTunnelSslContextBuilderCustomizer, this.tcpKeepAlive, this.tcpNoDelay, this.trustServerCertificate, this.trustStore, this.trustStoreType, this.trustStorePassword);
this.sslTunnelSslContextBuilderCustomizer, this.tcpKeepAlive, this.tcpNoDelay, this.trustServerCertificate, this.trustStore, this.trustStoreType, this.trustStorePassword,
this.connectionProvider);
}

ConnectionOptions toConnectionOptions() {
Expand Down Expand Up @@ -387,6 +393,9 @@ public static final class Builder {
@Nullable
private char[] trustStorePassword;

@Nullable
private ConnectionProvider connectionProvider;

private Builder() {
}

Expand Down Expand Up @@ -703,6 +712,18 @@ public Builder username(String username) {
return this;
}

/**
* Configure the {@link ConnectionProvider} to be used with Netty
*
* @param connectionProvider the connection provider
* @return this {@link Builder}
* @since 1.1.0
*/
public Builder connectionProvider(ConnectionProvider connectionProvider) {
this.connectionProvider = connectionProvider;
return this;
}

/**
* Returns a configured {@link MssqlConnectionConfiguration}.
*
Expand All @@ -719,7 +740,7 @@ public MssqlConnectionConfiguration build() {
this.preferCursoredExecution, this.port, this.sendStringParametersAsUnicode, this.ssl, this.sslContextBuilderCustomizer,
this.sslTunnelSslContextBuilderCustomizer, this.tcpKeepAlive,
this.tcpNoDelay, this.trustServerCertificate, this.trustStore,
this.trustStoreType, this.trustStorePassword, this.username);
this.trustStoreType, this.trustStorePassword, this.username, this.connectionProvider);
}

}
Expand Down Expand Up @@ -756,10 +777,14 @@ static class DefaultClientConfiguration implements ClientConfiguration {
@Nullable
private final char[] trustStorePassword;

@Nullable
private final ConnectionProvider connectionProvider;

DefaultClientConfiguration(Duration connectTimeout, String host, String hostNameInCertificate, int port, boolean ssl,
Function<SslContextBuilder, SslContextBuilder> sslContextBuilderCustomizer,
@Nullable Function<SslContextBuilder, SslContextBuilder> sslTunnelSslContextBuilderCustomizer, boolean tcpKeepAlive, boolean tcpNoDelay,
boolean trustServerCertificate, @Nullable File trustStore, @Nullable String trustStoreType, @Nullable char[] trustStorePassword) {
boolean trustServerCertificate, @Nullable File trustStore, @Nullable String trustStoreType, @Nullable char[] trustStorePassword,
ConnectionProvider connectionProvider) {

this.connectTimeout = connectTimeout;
this.host = host;
Expand All @@ -774,6 +799,7 @@ static class DefaultClientConfiguration implements ClientConfiguration {
this.trustStore = trustStore;
this.trustStoreType = trustStoreType;
this.trustStorePassword = trustStorePassword;
this.connectionProvider = connectionProvider;
}

@Override
Expand Down Expand Up @@ -803,7 +829,8 @@ public boolean isTcpNoDelay() {

@Override
public ConnectionProvider getConnectionProvider() {
return ConnectionProvider.newConnection();
return Optional.ofNullable(connectionProvider)
.orElseGet(ConnectionProvider::newConnection);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.r2dbc.spi.ConnectionFactoryOptions;
import io.r2dbc.spi.ConnectionFactoryProvider;
import io.r2dbc.spi.Option;
import reactor.netty.resources.ConnectionProvider;
import reactor.util.Logger;
import reactor.util.Loggers;

Expand Down Expand Up @@ -134,6 +135,13 @@ public final class MssqlConnectionFactoryProvider implements ConnectionFactoryPr
*/
public static final Option<char[]> TRUST_STORE_PASSWORD = Option.valueOf("trustStorePassword");

/**
* Optional {@link reactor.netty.resources.ConnectionProvider} to control Netty configuration directly
*
* @since 1.1.0
*/
public static final Option<ConnectionProvider> CONNECTION_PROVIDER = Option.valueOf("connectionProvider");

/**
* Driver option value.
*/
Expand Down Expand Up @@ -194,6 +202,7 @@ public MssqlConnectionFactory create(ConnectionFactoryOptions connectionFactoryO
mapper.from(TRUST_STORE).map(OptionMapper::toFile).to(builder::trustStore);
mapper.fromTyped(TRUST_STORE_TYPE).to(builder::trustStoreType);
mapper.from(TRUST_STORE_PASSWORD).map(it -> it instanceof String ? ((String) it).toCharArray() : (char[]) it).to(builder::trustStorePassword);
mapper.fromTyped(CONNECTION_PROVIDER).to(builder::connectionProvider);

builder.host(connectionFactoryOptions.getRequiredValue(HOST).toString());
builder.password((CharSequence) connectionFactoryOptions.getRequiredValue(PASSWORD));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.testcontainers.shaded.org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.testcontainers.shaded.org.bouncycastle.operator.ContentSigner;
import org.testcontainers.shaded.org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import reactor.netty.resources.ConnectionProvider;

import java.io.File;
import java.io.FileOutputStream;
Expand Down Expand Up @@ -86,6 +87,7 @@ void builderNoUsername() {
void configuration() {
UUID connectionId = UUID.randomUUID();
Predicate<String> TRUE = s -> true;
ConnectionProvider connectionProvider = ConnectionProvider.create("test");
MssqlConnectionConfiguration configuration = MssqlConnectionConfiguration.builder()
.connectionId(connectionId)
.database("test-database")
Expand All @@ -95,6 +97,7 @@ void configuration() {
.port(100)
.username("test-username")
.sendStringParametersAsUnicode(false)
.connectionProvider(connectionProvider)
.build();

assertThat(configuration)
Expand All @@ -105,7 +108,8 @@ void configuration() {
.hasFieldOrPropertyWithValue("preferCursoredExecution", TRUE)
.hasFieldOrPropertyWithValue("port", 100)
.hasFieldOrPropertyWithValue("username", "test-username")
.hasFieldOrPropertyWithValue("sendStringParametersAsUnicode", false);
.hasFieldOrPropertyWithValue("sendStringParametersAsUnicode", false)
.hasFieldOrPropertyWithValue("connectionProvider", connectionProvider);
}

@Test
Expand Down

0 comments on commit 0e43966

Please sign in to comment.