Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Option to set reactor.netty.resources.ConnectionProvider #292

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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