diff --git a/vertx-db2-client/src/main/generated/io/vertx/db2client/DB2ConnectOptionsConverter.java b/vertx-db2-client/src/main/generated/io/vertx/db2client/DB2ConnectOptionsConverter.java index 0c6b237ff..29fa7c041 100644 --- a/vertx-db2-client/src/main/generated/io/vertx/db2client/DB2ConnectOptionsConverter.java +++ b/vertx-db2-client/src/main/generated/io/vertx/db2client/DB2ConnectOptionsConverter.java @@ -20,6 +20,11 @@ public class DB2ConnectOptionsConverter { public static void fromJson(Iterable> json, DB2ConnectOptions obj) { for (java.util.Map.Entry member : json) { switch (member.getKey()) { + case "ssl": + if (member.getValue() instanceof Boolean) { + obj.setSsl((Boolean)member.getValue()); + } + break; case "pipeliningLimit": break; } @@ -31,6 +36,7 @@ public static void toJson(DB2ConnectOptions obj, JsonObject json) { } public static void toJson(DB2ConnectOptions obj, java.util.Map json) { + json.put("ssl", obj.isSsl()); json.put("pipeliningLimit", obj.getPipeliningLimit()); } } diff --git a/vertx-db2-client/src/main/java/examples/DB2ClientExamples.java b/vertx-db2-client/src/main/java/examples/DB2ClientExamples.java index 10b70dd7f..62c94a971 100644 --- a/vertx-db2-client/src/main/java/examples/DB2ClientExamples.java +++ b/vertx-db2-client/src/main/java/examples/DB2ClientExamples.java @@ -21,6 +21,7 @@ import io.vertx.core.Future; import io.vertx.core.Vertx; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.JksOptions; import io.vertx.db2client.DB2ConnectOptions; import io.vertx.db2client.DB2Connection; @@ -258,9 +259,9 @@ public void connectSsl(Vertx vertx) { .setUser("user") .setPassword("secret") .setSsl(true) - .setTrustStoreOptions(new JksOptions() - .setPath("/path/to/keystore.p12") - .setPassword("keystoreSecret")); + .setSslOptions(new ClientSSLOptions().setTrustOptions(new JksOptions() + .setPath("/path/to/keystore.p12") + .setPassword("keystoreSecret"))); DB2Connection.connect(vertx, options) .onComplete(res -> { @@ -396,5 +397,4 @@ public void enumIntValues(SqlClient client) { } }); } - } diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/DB2ConnectOptions.java b/vertx-db2-client/src/main/java/io/vertx/db2client/DB2ConnectOptions.java index 1b8544cc7..fde8993f4 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/DB2ConnectOptions.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/DB2ConnectOptions.java @@ -25,16 +25,7 @@ import io.vertx.codegen.annotations.DataObject; import io.vertx.codegen.annotations.GenIgnore; import io.vertx.core.json.JsonObject; -import io.vertx.core.net.ClientOptionsBase; -import io.vertx.core.net.JdkSSLEngineOptions; -import io.vertx.core.net.JksOptions; -import io.vertx.core.net.KeyCertOptions; -import io.vertx.core.net.NetClientOptions; -import io.vertx.core.net.OpenSSLEngineOptions; -import io.vertx.core.net.PemKeyCertOptions; -import io.vertx.core.net.PemTrustOptions; -import io.vertx.core.net.SSLEngineOptions; -import io.vertx.core.net.TrustOptions; +import io.vertx.core.net.*; import io.vertx.core.tracing.TracingPolicy; import io.vertx.db2client.impl.DB2ConnectionUriParser; import io.vertx.db2client.impl.drda.SQLState; @@ -77,6 +68,7 @@ public static DB2ConnectOptions fromUri(String connectionUri) throws IllegalArgu public static final boolean DEFAULT_USE_AFFECTED_ROWS = false; public static final int DEFAULT_PIPELINING_LIMIT = 1; // 256; // TODO default to 256 once implemented properly public static final Map DEFAULT_CONNECTION_ATTRIBUTES; + public static final boolean DEFAULT_SSL = false; static { Map defaultAttributes = new HashMap<>(); @@ -84,6 +76,7 @@ public static DB2ConnectOptions fromUri(String connectionUri) throws IllegalArgu DEFAULT_CONNECTION_ATTRIBUTES = Collections.unmodifiableMap(defaultAttributes); } + private boolean ssl = DEFAULT_SSL; private int pipeliningLimit = DEFAULT_PIPELINING_LIMIT; public DB2ConnectOptions() { @@ -100,12 +93,14 @@ public DB2ConnectOptions(SqlConnectOptions other) { if (other instanceof DB2ConnectOptions) { DB2ConnectOptions opts = (DB2ConnectOptions) other; this.pipeliningLimit = opts.pipeliningLimit; + this.ssl = opts.ssl; } } public DB2ConnectOptions(DB2ConnectOptions other) { super(other); this.pipeliningLimit = other.pipeliningLimit; + this.ssl = other.ssl; } @Override @@ -169,69 +164,23 @@ public DB2ConnectOptions setPreparedStatementCacheSqlLimit(int preparedStatement return (DB2ConnectOptions) super.setPreparedStatementCacheSqlLimit(preparedStatementCacheSqlLimit); } - @Override - public DB2ConnectOptions setSsl(boolean ssl) { - return (DB2ConnectOptions) super.setSsl(ssl); - } - - @Override - public DB2ConnectOptions setSslHandshakeTimeout(long sslHandshakeTimeout) { - return (DB2ConnectOptions) super.setSslHandshakeTimeout(sslHandshakeTimeout); - } - - @Override - public DB2ConnectOptions setSslHandshakeTimeoutUnit(TimeUnit sslHandshakeTimeoutUnit) { - return (DB2ConnectOptions) super.setSslHandshakeTimeoutUnit(sslHandshakeTimeoutUnit); - } - - @Override - public DB2ConnectOptions setSslEngineOptions(SSLEngineOptions sslEngineOptions) { - return (DB2ConnectOptions) super.setSslEngineOptions(sslEngineOptions); - } - - @Override - public DB2ConnectOptions setJdkSslEngineOptions(JdkSSLEngineOptions sslEngineOptions) { - return (DB2ConnectOptions) super.setJdkSslEngineOptions(sslEngineOptions); - } - - @Override - public DB2ConnectOptions setKeyCertOptions(KeyCertOptions options) { - return (DB2ConnectOptions) super.setKeyCertOptions(options); - } - - @Override - public DB2ConnectOptions setKeyStoreOptions(JksOptions options) { - return (DB2ConnectOptions) super.setKeyStoreOptions(options); - } - - @Override - public DB2ConnectOptions setOpenSslEngineOptions(OpenSSLEngineOptions sslEngineOptions) { - return (DB2ConnectOptions) super.setOpenSslEngineOptions(sslEngineOptions); - } - - @Override - public DB2ConnectOptions setPemKeyCertOptions(PemKeyCertOptions options) { - return (DB2ConnectOptions) super.setPemKeyCertOptions(options); - } - - @Override - public DB2ConnectOptions setPemTrustOptions(PemTrustOptions options) { - return (DB2ConnectOptions) super.setPemTrustOptions(options); - } - - @Override - public DB2ConnectOptions setTrustAll(boolean trustAll) { - return (DB2ConnectOptions) super.setTrustAll(trustAll); - } - - @Override - public DB2ConnectOptions setTrustOptions(TrustOptions options) { - return (DB2ConnectOptions) super.setTrustOptions(options); + /** + * + * @return is SSL/TLS enabled? + */ + public boolean isSsl() { + return ssl; } - @Override - public DB2ConnectOptions setTrustStoreOptions(JksOptions options) { - return (DB2ConnectOptions) super.setTrustStoreOptions(options); + /** + * Set whether SSL/TLS is enabled + * + * @param ssl true if enabled + * @return a reference to this, so the API can be used fluently + */ + public DB2ConnectOptions setSsl(boolean ssl) { + this.ssl = ssl; + return this; } public int getPipeliningLimit() { @@ -271,6 +220,11 @@ public DB2ConnectOptions addProperty(String key, String value) { return (DB2ConnectOptions) super.addProperty(key, value); } + @Override + public DB2ConnectOptions setSslOptions(ClientSSLOptions sslOptions) { + return (DB2ConnectOptions) super.setSslOptions(sslOptions); + } + /** * Initialize with the default options. */ diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionFactory.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionFactory.java index 47163934d..d90c4dbbf 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionFactory.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionFactory.java @@ -50,10 +50,9 @@ protected Future doConnectInternal(DB2ConnectOptions options, Contex String database = options.getDatabase(); Map properties = options.getProperties(); int pipeliningLimit = options.getPipeliningLimit(); - NetClient netClient = netClient(options); - return netClient.connect(server).flatMap(so -> { + return client.connect(server).flatMap(so -> { VertxMetrics vertxMetrics = vertx.metricsSPI(); - ClientMetrics metrics = vertxMetrics != null ? vertxMetrics.createClientMetrics(options.getSocketAddress(), "sql", options.getMetricsName()) : null; + ClientMetrics metrics = vertxMetrics != null ? vertxMetrics.createClientMetrics(options.getSocketAddress(), "sql", tcpOptions.getMetricsName()) : null; DB2SocketConnection conn = new DB2SocketConnection((NetSocketInternal) so, metrics, options, cachePreparedStatements, preparedStatementCacheSize, preparedStatementCacheSqlFilter, pipeliningLimit, context); conn.init(); diff --git a/vertx-db2-client/src/test/java/io/vertx/db2client/junit/DB2Resource.java b/vertx-db2-client/src/test/java/io/vertx/db2client/junit/DB2Resource.java index 84bacba92..4efd195c8 100644 --- a/vertx-db2-client/src/test/java/io/vertx/db2client/junit/DB2Resource.java +++ b/vertx-db2-client/src/test/java/io/vertx/db2client/junit/DB2Resource.java @@ -15,6 +15,7 @@ */ package io.vertx.db2client.junit; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.JksOptions; import io.vertx.db2client.DB2ConnectOptions; import org.junit.rules.ExternalResource; @@ -101,9 +102,9 @@ public DB2ConnectOptions secureOptions() { return new DB2ConnectOptions(options()) .setPort(securePort) .setSsl(true) - .setTrustStoreOptions(new JksOptions() - .setPath("src/test/resources/tls/db2-keystore.p12") - .setPassword("db2test")); + .setSslOptions(new ClientSSLOptions().setTrustOptions(new JksOptions() + .setPath("src/test/resources/tls/db2-keystore.p12") + .setPassword("db2test"))); } public boolean isZOS() { diff --git a/vertx-mssql-client/src/main/generated/io/vertx/mssqlclient/MSSQLConnectOptionsConverter.java b/vertx-mssql-client/src/main/generated/io/vertx/mssqlclient/MSSQLConnectOptionsConverter.java index 36bf40464..2049da0db 100644 --- a/vertx-mssql-client/src/main/generated/io/vertx/mssqlclient/MSSQLConnectOptionsConverter.java +++ b/vertx-mssql-client/src/main/generated/io/vertx/mssqlclient/MSSQLConnectOptionsConverter.java @@ -25,6 +25,11 @@ public static void fromJson(Iterable> json, obj.setPacketSize(((Number)member.getValue()).intValue()); } break; + case "ssl": + if (member.getValue() instanceof Boolean) { + obj.setSsl((Boolean)member.getValue()); + } + break; } } } @@ -35,5 +40,6 @@ public static void toJson(MSSQLConnectOptions obj, JsonObject json) { public static void toJson(MSSQLConnectOptions obj, java.util.Map json) { json.put("packetSize", obj.getPacketSize()); + json.put("ssl", obj.isSsl()); } } diff --git a/vertx-mssql-client/src/main/java/examples/MSSQLClientExamples.java b/vertx-mssql-client/src/main/java/examples/MSSQLClientExamples.java index 9b65d1606..78962d2b6 100644 --- a/vertx-mssql-client/src/main/java/examples/MSSQLClientExamples.java +++ b/vertx-mssql-client/src/main/java/examples/MSSQLClientExamples.java @@ -12,6 +12,7 @@ package examples; import io.vertx.core.Vertx; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.PemTrustOptions; import io.vertx.docgen.Source; import io.vertx.mssqlclient.MSSQLConnectOptions; @@ -307,13 +308,13 @@ public void setSsl() { public void disableHostnameValidation() { MSSQLConnectOptions connectOptions = new MSSQLConnectOptions() .setSsl(true) - .setTrustAll(true); + .setSslOptions(new ClientSSLOptions().setTrustAll(true)); } public void usingTrustOptions() { MSSQLConnectOptions connectOptions = new MSSQLConnectOptions() .setSsl(true) - .setPemTrustOptions(new PemTrustOptions().addCertPath("/path/to/server-cert.pem")); + .setSslOptions(new ClientSSLOptions().setTrustOptions(new PemTrustOptions().addCertPath("/path/to/server-cert.pem"))); } public void infoHandler(MSSQLConnection connection) { diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/MSSQLConnectOptions.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/MSSQLConnectOptions.java index 982ce428f..4be50010a 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/MSSQLConnectOptions.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/MSSQLConnectOptions.java @@ -12,18 +12,14 @@ package io.vertx.mssqlclient; import io.vertx.codegen.annotations.DataObject; -import io.vertx.core.buffer.Buffer; import io.vertx.core.json.JsonObject; import io.vertx.core.net.*; -import io.vertx.core.tracing.TracingPolicy; import io.vertx.mssqlclient.impl.MSSQLConnectionUriParser; import io.vertx.sqlclient.SqlConnectOptions; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; /** * Connect options for configuring {@link MSSQLConnection}. @@ -65,6 +61,7 @@ public static MSSQLConnectOptions fromUri(String connectionUri) throws IllegalAr public static final int MIN_PACKET_SIZE = 512; public static final int MAX_PACKET_SIZE = 32767; public static final int DEFAULT_PACKET_SIZE = 4096; + public static final boolean DEFAULT_SSL = false; static { Map defaultProperties = new HashMap<>(); @@ -73,6 +70,7 @@ public static MSSQLConnectOptions fromUri(String connectionUri) throws IllegalAr DEFAULT_PROPERTIES = defaultProperties; } + private boolean ssl; private int packetSize; public MSSQLConnectOptions() { @@ -99,6 +97,7 @@ public MSSQLConnectOptions(MSSQLConnectOptions other) { private void copyFields(MSSQLConnectOptions other) { packetSize = other.packetSize; + ssl = other.ssl; } @Override @@ -163,169 +162,23 @@ public MSSQLConnectOptions setPacketSize(int packetSize) { return this; } - @Override - public MSSQLConnectOptions setSendBufferSize(int sendBufferSize) { - return (MSSQLConnectOptions) super.setSendBufferSize(sendBufferSize); - } - - @Override - public MSSQLConnectOptions setReceiveBufferSize(int receiveBufferSize) { - return (MSSQLConnectOptions) super.setReceiveBufferSize(receiveBufferSize); - } - - @Override - public MSSQLConnectOptions setReuseAddress(boolean reuseAddress) { - return (MSSQLConnectOptions) super.setReuseAddress(reuseAddress); - } - - @Override - public MSSQLConnectOptions setReusePort(boolean reusePort) { - return (MSSQLConnectOptions) super.setReusePort(reusePort); - } - - @Override - public MSSQLConnectOptions setTrafficClass(int trafficClass) { - return (MSSQLConnectOptions) super.setTrafficClass(trafficClass); - } - - @Override - public MSSQLConnectOptions setTcpNoDelay(boolean tcpNoDelay) { - return (MSSQLConnectOptions) super.setTcpNoDelay(tcpNoDelay); - } - - @Override - public MSSQLConnectOptions setTcpKeepAlive(boolean tcpKeepAlive) { - return (MSSQLConnectOptions) super.setTcpKeepAlive(tcpKeepAlive); - } - - @Override - public MSSQLConnectOptions setSoLinger(int soLinger) { - return (MSSQLConnectOptions) super.setSoLinger(soLinger); - } - - @Override - public MSSQLConnectOptions setIdleTimeout(int idleTimeout) { - return (MSSQLConnectOptions) super.setIdleTimeout(idleTimeout); - } - - @Override - public MSSQLConnectOptions setIdleTimeoutUnit(TimeUnit idleTimeoutUnit) { - return (MSSQLConnectOptions) super.setIdleTimeoutUnit(idleTimeoutUnit); - } - - @Override - public MSSQLConnectOptions setKeyCertOptions(KeyCertOptions options) { - return (MSSQLConnectOptions) super.setKeyCertOptions(options); - } - - @Override - public MSSQLConnectOptions setKeyStoreOptions(JksOptions options) { - return (MSSQLConnectOptions) super.setKeyStoreOptions(options); - } - - @Override - public MSSQLConnectOptions setPfxKeyCertOptions(PfxOptions options) { - return (MSSQLConnectOptions) super.setPfxKeyCertOptions(options); - } - - @Override - public MSSQLConnectOptions setPemKeyCertOptions(PemKeyCertOptions options) { - return (MSSQLConnectOptions) super.setPemKeyCertOptions(options); - } - - @Override - public MSSQLConnectOptions setTrustOptions(TrustOptions options) { - return (MSSQLConnectOptions) super.setTrustOptions(options); - } - - @Override - public MSSQLConnectOptions setTrustStoreOptions(JksOptions options) { - return (MSSQLConnectOptions) super.setTrustStoreOptions(options); - } - - @Override - public MSSQLConnectOptions setPemTrustOptions(PemTrustOptions options) { - return (MSSQLConnectOptions) super.setPemTrustOptions(options); - } - - @Override - public MSSQLConnectOptions setPfxTrustOptions(PfxOptions options) { - return (MSSQLConnectOptions) super.setPfxTrustOptions(options); - } - - @Override - public MSSQLConnectOptions addEnabledCipherSuite(String suite) { - return (MSSQLConnectOptions) super.addEnabledCipherSuite(suite); - } - - @Override - public MSSQLConnectOptions addEnabledSecureTransportProtocol(String protocol) { - return (MSSQLConnectOptions) super.addEnabledSecureTransportProtocol(protocol); - } - - @Override - public MSSQLConnectOptions removeEnabledSecureTransportProtocol(String protocol) { - return (MSSQLConnectOptions) super.removeEnabledSecureTransportProtocol(protocol); - } - - @Override - public MSSQLConnectOptions setUseAlpn(boolean useAlpn) { - return (MSSQLConnectOptions) super.setUseAlpn(useAlpn); - } - - @Override - public MSSQLConnectOptions setSslEngineOptions(SSLEngineOptions sslEngineOptions) { - return (MSSQLConnectOptions) super.setSslEngineOptions(sslEngineOptions); - } - - @Override - public MSSQLConnectOptions setJdkSslEngineOptions(JdkSSLEngineOptions sslEngineOptions) { - return (MSSQLConnectOptions) super.setJdkSslEngineOptions(sslEngineOptions); - } - - @Override - public MSSQLConnectOptions setTcpFastOpen(boolean tcpFastOpen) { - return (MSSQLConnectOptions) super.setTcpFastOpen(tcpFastOpen); - } - - @Override - public MSSQLConnectOptions setTcpCork(boolean tcpCork) { - return (MSSQLConnectOptions) super.setTcpCork(tcpCork); - } - - @Override - public MSSQLConnectOptions setTcpQuickAck(boolean tcpQuickAck) { - return (MSSQLConnectOptions) super.setTcpQuickAck(tcpQuickAck); - } - - @Override - public MSSQLConnectOptions setOpenSslEngineOptions(OpenSSLEngineOptions sslEngineOptions) { - return (MSSQLConnectOptions) super.setOpenSslEngineOptions(sslEngineOptions); - } - - @Override - public MSSQLConnectOptions addCrlPath(String crlPath) throws NullPointerException { - return (MSSQLConnectOptions) super.addCrlPath(crlPath); - } - - @Override - public MSSQLConnectOptions addCrlValue(Buffer crlValue) throws NullPointerException { - return (MSSQLConnectOptions) super.addCrlValue(crlValue); - } - - @Override - public MSSQLConnectOptions setTrustAll(boolean trustAll) { - return (MSSQLConnectOptions) super.setTrustAll(trustAll); - } - - @Override - public MSSQLConnectOptions setConnectTimeout(int connectTimeout) { - return (MSSQLConnectOptions) super.setConnectTimeout(connectTimeout); + /** + * + * @return is SSL/TLS enabled? + */ + public boolean isSsl() { + return ssl; } - @Override - public MSSQLConnectOptions setMetricsName(String metricsName) { - return (MSSQLConnectOptions) super.setMetricsName(metricsName); + /** + * Set whether SSL/TLS is enabled + * + * @param ssl true if enabled + * @return a reference to this, so the API can be used fluently + */ + public MSSQLConnectOptions setSsl(boolean ssl) { + this.ssl = ssl; + return this; } @Override @@ -339,53 +192,28 @@ public MSSQLConnectOptions setReconnectInterval(long interval) { } @Override - public MSSQLConnectOptions setHostnameVerificationAlgorithm(String hostnameVerificationAlgorithm) { - return (MSSQLConnectOptions) super.setHostnameVerificationAlgorithm(hostnameVerificationAlgorithm); - } - - @Override - public MSSQLConnectOptions setLogActivity(boolean logEnabled) { - return (MSSQLConnectOptions) super.setLogActivity(logEnabled); - } - - @Override - public MSSQLConnectOptions setProxyOptions(ProxyOptions proxyOptions) { - return (MSSQLConnectOptions) super.setProxyOptions(proxyOptions); - } - - @Override - public MSSQLConnectOptions setLocalAddress(String localAddress) { - return (MSSQLConnectOptions) super.setLocalAddress(localAddress); + public MSSQLConnectOptions setCachePreparedStatements(boolean cachePreparedStatements) { + return (MSSQLConnectOptions) super.setCachePreparedStatements(cachePreparedStatements); } @Override - public MSSQLConnectOptions setEnabledSecureTransportProtocols(Set enabledSecureTransportProtocols) { - return (MSSQLConnectOptions) super.setEnabledSecureTransportProtocols(enabledSecureTransportProtocols); + public MSSQLConnectOptions setPreparedStatementCacheMaxSize(int preparedStatementCacheMaxSize) { + return (MSSQLConnectOptions) super.setPreparedStatementCacheMaxSize(preparedStatementCacheMaxSize); } @Override - public MSSQLConnectOptions setSslHandshakeTimeout(long sslHandshakeTimeout) { - return (MSSQLConnectOptions) super.setSslHandshakeTimeout(sslHandshakeTimeout); + public MSSQLConnectOptions setPreparedStatementCacheSqlFilter(Predicate predicate) { + return (MSSQLConnectOptions) super.setPreparedStatementCacheSqlFilter(predicate); } @Override - public MSSQLConnectOptions setSslHandshakeTimeoutUnit(TimeUnit sslHandshakeTimeoutUnit) { - return (MSSQLConnectOptions) super.setSslHandshakeTimeoutUnit(sslHandshakeTimeoutUnit); - } - - @Override - public MSSQLConnectOptions setTracingPolicy(TracingPolicy tracingPolicy) { - return (MSSQLConnectOptions) super.setTracingPolicy(tracingPolicy); - } - - @Override - public MSSQLConnectOptions setSsl(boolean ssl) { - return (MSSQLConnectOptions) super.setSsl(ssl); + public MSSQLConnectOptions setPreparedStatementCacheSqlLimit(int preparedStatementCacheSqlLimit) { + return (MSSQLConnectOptions) super.setPreparedStatementCacheSqlLimit(preparedStatementCacheSqlLimit); } @Override - public MSSQLConnectOptions setNonProxyHosts(List nonProxyHosts) { - return (MSSQLConnectOptions) super.setNonProxyHosts(nonProxyHosts); + public MSSQLConnectOptions setSslOptions(ClientSSLOptions sslOptions) { + return (MSSQLConnectOptions) super.setSslOptions(sslOptions); } /** @@ -399,6 +227,7 @@ protected void init() { this.setDatabase(DEFAULT_DATABASE); this.setProperties(new HashMap<>(DEFAULT_PROPERTIES)); packetSize = DEFAULT_PACKET_SIZE; + ssl = DEFAULT_SSL; } @Override diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionFactory.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionFactory.java index 3a2a16726..3a0e37200 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionFactory.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionFactory.java @@ -16,11 +16,10 @@ import io.vertx.core.Promise; import io.vertx.core.impl.ContextInternal; import io.vertx.core.impl.VertxInternal; -import io.vertx.core.net.NetClient; -import io.vertx.core.net.NetClientOptions; import io.vertx.core.net.NetSocket; import io.vertx.core.net.SocketAddress; import io.vertx.core.net.impl.NetSocketInternal; +import io.vertx.core.net.impl.SSLHelper; import io.vertx.core.spi.metrics.ClientMetrics; import io.vertx.core.spi.metrics.VertxMetrics; import io.vertx.mssqlclient.MSSQLConnectOptions; @@ -29,14 +28,16 @@ import io.vertx.sqlclient.impl.ConnectionFactoryBase; import java.util.Map; -import java.util.function.Supplier; import static io.vertx.mssqlclient.impl.codec.EncryptionLevel.*; public class MSSQLConnectionFactory extends ConnectionFactoryBase { + private final SSLHelper sslHelper; + public MSSQLConnectionFactory(VertxInternal vertx) { super(vertx); + sslHelper = new SSLHelper(SSLHelper.resolveEngineOptions(tcpOptions.getSslEngineOptions(), tcpOptions.isUseAlpn())); } @Override @@ -52,8 +53,7 @@ private Future connectOrRedirect(MSSQLConnectOptions options, Contex boolean clientSslConfig = options.isSsl(); int desiredPacketSize = options.getPacketSize(); // Always start unencrypted, the connection will be upgraded if client and server agree - NetClient netClient = netClient(new NetClientOptions(options).setSsl(false)); - return netClient.connect(server) + return client.connect(server) .map(so -> createSocketConnection(so, options, desiredPacketSize, context)) .compose(conn -> conn.sendPreLoginMessage(clientSslConfig) .compose(encryptionLevel -> login(conn, options, encryptionLevel, context)) @@ -72,8 +72,8 @@ private Future connectOrRedirect(MSSQLConnectOptions options, Contex private MSSQLSocketConnection createSocketConnection(NetSocket so, MSSQLConnectOptions options, int desiredPacketSize, ContextInternal context) { VertxMetrics vertxMetrics = vertx.metricsSPI(); - ClientMetrics metrics = vertxMetrics != null ? vertxMetrics.createClientMetrics(options.getSocketAddress(), "sql", options.getMetricsName()) : null; - MSSQLSocketConnection conn = new MSSQLSocketConnection((NetSocketInternal) so, metrics, options, desiredPacketSize, false, 0, sql -> true, 1, context); + ClientMetrics metrics = vertxMetrics != null ? vertxMetrics.createClientMetrics(options.getSocketAddress(), "sql", tcpOptions.getMetricsName()) : null; + MSSQLSocketConnection conn = new MSSQLSocketConnection((NetSocketInternal) so, sslHelper, metrics, options, desiredPacketSize, false, 0, sql -> true, 1, context); conn.init(); return conn; } diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLSocketConnection.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLSocketConnection.java index 640c3276a..0d34832fb 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLSocketConnection.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLSocketConnection.java @@ -17,7 +17,6 @@ import io.vertx.core.AsyncResult; import io.vertx.core.Future; import io.vertx.core.Handler; -import io.vertx.core.http.ClientAuth; import io.vertx.core.impl.ContextInternal; import io.vertx.core.impl.future.PromiseInternal; import io.vertx.core.net.ClientSSLOptions; @@ -50,11 +49,13 @@ public class MSSQLSocketConnection extends SocketConnectionBase { private final MSSQLConnectOptions connectOptions; private final int packetSize; + private final SSLHelper sslHelper; private MSSQLDatabaseMetadata databaseMetadata; private SocketAddress alternateServer; MSSQLSocketConnection(NetSocketInternal socket, + SSLHelper sslHelper, ClientMetrics clientMetrics, MSSQLConnectOptions connectOptions, int packetSize, @@ -66,6 +67,7 @@ public class MSSQLSocketConnection extends SocketConnectionBase { super(socket, clientMetrics, cachePreparedStatements, preparedStatementCacheSize, preparedStatementCacheSqlFilter, pipeliningLimit, context); this.connectOptions = connectOptions; this.packetSize = packetSize; + this.sslHelper = sslHelper; } @Override @@ -102,21 +104,18 @@ Future enableSsl(boolean clientConfigSsl, byte encryptionLevel, MSSQLConne } }); + ClientSSLOptions sslOptions = options.getSslOptions() == null ? new ClientSSLOptions() : options.getSslOptions().copy(); + // Do not perform hostname validation if the client did not require encryption if (!clientConfigSsl) { - options.setTrustAll(true); + sslOptions.setTrustAll(true); } // 2. Create and set up an SSLHelper and SSLHandler // options.getApplicationLayerProtocols() - SSLHelper helper = new SSLHelper(SSLHelper.resolveEngineOptions(options.getSslEngineOptions(), options.isUseAlpn())); - ClientSSLOptions sslOptions = options.getSslOptions(); - if (sslOptions == null) { - sslOptions = new ClientSSLOptions(); - } - Future f = helper.resolveSslChannelProvider(sslOptions, "", false, null, null, context); + Future f = sslHelper.resolveSslChannelProvider(sslOptions, "", false, null, null, context); return f.compose(provider -> { - SslHandler sslHandler = provider.createClientSslHandler(socket.remoteAddress(), null, options.isUseAlpn(), options.isTrustAll(), options.getSslHandshakeTimeout(), options.getSslHandshakeTimeoutUnit()); + SslHandler sslHandler = provider.createClientSslHandler(socket.remoteAddress(), null, sslOptions.isUseAlpn(), sslOptions.isTrustAll(), sslOptions.getSslHandshakeTimeout(), sslOptions.getSslHandshakeTimeoutUnit()); // 3. TdsSslHandshakeCodec manages SSL payload encapsulated in TDS packets TdsSslHandshakeCodec tdsSslHandshakeCodec = new TdsSslHandshakeCodec(); diff --git a/vertx-mssql-client/src/test/java/io/vertx/mssqlclient/MSSQLEncryptionTestBase.java b/vertx-mssql-client/src/test/java/io/vertx/mssqlclient/MSSQLEncryptionTestBase.java index cc1e060b9..05e074e72 100644 --- a/vertx-mssql-client/src/test/java/io/vertx/mssqlclient/MSSQLEncryptionTestBase.java +++ b/vertx-mssql-client/src/test/java/io/vertx/mssqlclient/MSSQLEncryptionTestBase.java @@ -15,6 +15,7 @@ import io.vertx.core.Handler; import io.vertx.core.Vertx; import io.vertx.core.buffer.Buffer; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.PemTrustOptions; import io.vertx.ext.unit.TestContext; import io.vertx.mssqlclient.junit.MSSQLRule; @@ -93,7 +94,7 @@ public void testHostnameValidationFails(TestContext ctx) { public void testTrustAll(TestContext ctx) { setOptions(rule().options() .setSsl(true) - .setTrustAll(true)); + .setSslOptions(new ClientSSLOptions().setTrustAll(true))); asyncAssertConnectionEncrypted(ctx); } @@ -102,7 +103,7 @@ public void testTrustOptions(TestContext ctx) { Buffer certValue = vertx.fileSystem().readFileBlocking("mssql.pem"); setOptions(rule().options() .setSsl(true) - .setPemTrustOptions(new PemTrustOptions().addCertValue(certValue))); + .setSslOptions(new ClientSSLOptions().setTrustOptions(new PemTrustOptions().addCertValue(certValue)))); asyncAssertConnectionEncrypted(ctx); } } diff --git a/vertx-mysql-client/src/main/java/examples/MySQLClientExamples.java b/vertx-mysql-client/src/main/java/examples/MySQLClientExamples.java index b61d8ebe6..66a06c621 100644 --- a/vertx-mysql-client/src/main/java/examples/MySQLClientExamples.java +++ b/vertx-mysql-client/src/main/java/examples/MySQLClientExamples.java @@ -15,7 +15,9 @@ import io.vertx.core.Vertx; import io.vertx.core.buffer.Buffer; import io.vertx.core.json.JsonObject; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.PemTrustOptions; +import io.vertx.core.net.SSLOptions; import io.vertx.docgen.Source; import io.vertx.mysqlclient.*; import io.vertx.mysqlclient.data.spatial.Point; @@ -580,7 +582,7 @@ public void tlsExample(Vertx vertx) { .setUser("user") .setPassword("secret") .setSslMode(SslMode.VERIFY_CA) - .setPemTrustOptions(new PemTrustOptions().addCertPath("/path/to/cert.pem")); + .setSslOptions(new ClientSSLOptions().setTrustOptions(new PemTrustOptions().addCertPath("/path/to/cert.pem"))); MySQLConnection.connect(vertx, options) .onComplete(res -> { diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/MySQLConnectOptions.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/MySQLConnectOptions.java index d0bef295c..9af09ddc3 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/MySQLConnectOptions.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/MySQLConnectOptions.java @@ -255,16 +255,6 @@ public MySQLConnectOptions setAuthenticationPlugin(MySQLAuthenticationPlugin aut return this; } - @Override - public MySQLConnectOptions setSsl(boolean ssl) { - if (ssl) { - setSslMode(SslMode.VERIFY_CA); - } else { - setSslMode(SslMode.DISABLED); - } - return this; - } - /** * Set the path of server RSA public key which is mostly used for encrypting password under insecure connections when performing authentication. * @@ -385,171 +375,6 @@ public MySQLConnectOptions addProperty(String key, String value) { return (MySQLConnectOptions) super.addProperty(key, value); } - @Override - public MySQLConnectOptions setSendBufferSize(int sendBufferSize) { - return (MySQLConnectOptions) super.setSendBufferSize(sendBufferSize); - } - - @Override - public MySQLConnectOptions setReceiveBufferSize(int receiveBufferSize) { - return (MySQLConnectOptions) super.setReceiveBufferSize(receiveBufferSize); - } - - @Override - public MySQLConnectOptions setReuseAddress(boolean reuseAddress) { - return (MySQLConnectOptions) super.setReuseAddress(reuseAddress); - } - - @Override - public MySQLConnectOptions setReusePort(boolean reusePort) { - return (MySQLConnectOptions) super.setReusePort(reusePort); - } - - @Override - public MySQLConnectOptions setTrafficClass(int trafficClass) { - return (MySQLConnectOptions) super.setTrafficClass(trafficClass); - } - - @Override - public MySQLConnectOptions setTcpNoDelay(boolean tcpNoDelay) { - return (MySQLConnectOptions) super.setTcpNoDelay(tcpNoDelay); - } - - @Override - public MySQLConnectOptions setTcpKeepAlive(boolean tcpKeepAlive) { - return (MySQLConnectOptions) super.setTcpKeepAlive(tcpKeepAlive); - } - - @Override - public MySQLConnectOptions setSoLinger(int soLinger) { - return (MySQLConnectOptions) super.setSoLinger(soLinger); - } - - @Override - public MySQLConnectOptions setIdleTimeout(int idleTimeout) { - return (MySQLConnectOptions) super.setIdleTimeout(idleTimeout); - } - - @Override - public MySQLConnectOptions setIdleTimeoutUnit(TimeUnit idleTimeoutUnit) { - return (MySQLConnectOptions) super.setIdleTimeoutUnit(idleTimeoutUnit); - } - - @Override - public MySQLConnectOptions setKeyCertOptions(KeyCertOptions options) { - return (MySQLConnectOptions) super.setKeyCertOptions(options); - } - - @Override - public MySQLConnectOptions setKeyStoreOptions(JksOptions options) { - return (MySQLConnectOptions) super.setKeyStoreOptions(options); - } - - @Override - public MySQLConnectOptions setPfxKeyCertOptions(PfxOptions options) { - return (MySQLConnectOptions) super.setPfxKeyCertOptions(options); - } - - @Override - public MySQLConnectOptions setPemKeyCertOptions(PemKeyCertOptions options) { - return (MySQLConnectOptions) super.setPemKeyCertOptions(options); - } - - @Override - public MySQLConnectOptions setTrustOptions(TrustOptions options) { - return (MySQLConnectOptions) super.setTrustOptions(options); - } - - @Override - public MySQLConnectOptions setTrustStoreOptions(JksOptions options) { - return (MySQLConnectOptions) super.setTrustStoreOptions(options); - } - - @Override - public MySQLConnectOptions setPemTrustOptions(PemTrustOptions options) { - return (MySQLConnectOptions) super.setPemTrustOptions(options); - } - - @Override - public MySQLConnectOptions setPfxTrustOptions(PfxOptions options) { - return (MySQLConnectOptions) super.setPfxTrustOptions(options); - } - - @Override - public MySQLConnectOptions addEnabledCipherSuite(String suite) { - return (MySQLConnectOptions) super.addEnabledCipherSuite(suite); - } - - @Override - public MySQLConnectOptions addEnabledSecureTransportProtocol(String protocol) { - return (MySQLConnectOptions) super.addEnabledSecureTransportProtocol(protocol); - } - - @Override - public MySQLConnectOptions removeEnabledSecureTransportProtocol(String protocol) { - return (MySQLConnectOptions) super.removeEnabledSecureTransportProtocol(protocol); - } - - @Override - public MySQLConnectOptions setUseAlpn(boolean useAlpn) { - return (MySQLConnectOptions) super.setUseAlpn(useAlpn); - } - - @Override - public MySQLConnectOptions setSslEngineOptions(SSLEngineOptions sslEngineOptions) { - return (MySQLConnectOptions) super.setSslEngineOptions(sslEngineOptions); - } - - @Override - public MySQLConnectOptions setJdkSslEngineOptions(JdkSSLEngineOptions sslEngineOptions) { - return (MySQLConnectOptions) super.setJdkSslEngineOptions(sslEngineOptions); - } - - @Override - public MySQLConnectOptions setTcpFastOpen(boolean tcpFastOpen) { - return (MySQLConnectOptions) super.setTcpFastOpen(tcpFastOpen); - } - - @Override - public MySQLConnectOptions setTcpCork(boolean tcpCork) { - return (MySQLConnectOptions) super.setTcpCork(tcpCork); - } - - @Override - public MySQLConnectOptions setTcpQuickAck(boolean tcpQuickAck) { - return (MySQLConnectOptions) super.setTcpQuickAck(tcpQuickAck); - } - - @Override - public ClientOptionsBase setOpenSslEngineOptions(OpenSSLEngineOptions sslEngineOptions) { - return super.setOpenSslEngineOptions(sslEngineOptions); - } - - @Override - public MySQLConnectOptions addCrlPath(String crlPath) throws NullPointerException { - return (MySQLConnectOptions) super.addCrlPath(crlPath); - } - - @Override - public MySQLConnectOptions addCrlValue(Buffer crlValue) throws NullPointerException { - return (MySQLConnectOptions) super.addCrlValue(crlValue); - } - - @Override - public MySQLConnectOptions setTrustAll(boolean trustAll) { - return (MySQLConnectOptions) super.setTrustAll(trustAll); - } - - @Override - public MySQLConnectOptions setConnectTimeout(int connectTimeout) { - return (MySQLConnectOptions) super.setConnectTimeout(connectTimeout); - } - - @Override - public MySQLConnectOptions setMetricsName(String metricsName) { - return (MySQLConnectOptions) super.setMetricsName(metricsName); - } - @Override public MySQLConnectOptions setReconnectAttempts(int attempts) { return (MySQLConnectOptions) super.setReconnectAttempts(attempts); @@ -561,43 +386,13 @@ public MySQLConnectOptions setReconnectInterval(long interval) { } @Override - public MySQLConnectOptions setHostnameVerificationAlgorithm(String hostnameVerificationAlgorithm) { - return (MySQLConnectOptions) super.setHostnameVerificationAlgorithm(hostnameVerificationAlgorithm); - } - - @Override - public MySQLConnectOptions setLogActivity(boolean logEnabled) { - return (MySQLConnectOptions) super.setLogActivity(logEnabled); - } - - @Override - public MySQLConnectOptions setProxyOptions(ProxyOptions proxyOptions) { - return (MySQLConnectOptions) super.setProxyOptions(proxyOptions); - } - - @Override - public MySQLConnectOptions setLocalAddress(String localAddress) { - return (MySQLConnectOptions) super.setLocalAddress(localAddress); - } - - @Override - public MySQLConnectOptions setEnabledSecureTransportProtocols(Set enabledSecureTransportProtocols) { - return (MySQLConnectOptions) super.setEnabledSecureTransportProtocols(enabledSecureTransportProtocols); - } - - @Override - public MySQLConnectOptions setSslHandshakeTimeout(long sslHandshakeTimeout) { - return (MySQLConnectOptions) super.setSslHandshakeTimeout(sslHandshakeTimeout); - } - - @Override - public MySQLConnectOptions setSslHandshakeTimeoutUnit(TimeUnit sslHandshakeTimeoutUnit) { - return (MySQLConnectOptions) super.setSslHandshakeTimeoutUnit(sslHandshakeTimeoutUnit); + public MySQLConnectOptions setTracingPolicy(TracingPolicy tracingPolicy) { + return (MySQLConnectOptions) super.setTracingPolicy(tracingPolicy); } @Override - public MySQLConnectOptions setTracingPolicy(TracingPolicy tracingPolicy) { - return (MySQLConnectOptions) super.setTracingPolicy(tracingPolicy); + public MySQLConnectOptions setSslOptions(ClientSSLOptions sslOptions) { + return (MySQLConnectOptions) super.setSslOptions(sslOptions); } /** diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionFactory.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionFactory.java index f71cf10b4..1a4b03e00 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionFactory.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionFactory.java @@ -17,7 +17,8 @@ import io.vertx.core.buffer.Buffer; import io.vertx.core.impl.ContextInternal; import io.vertx.core.impl.VertxInternal; -import io.vertx.core.net.NetClientOptions; +import io.vertx.core.net.ConnectOptions; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.NetSocket; import io.vertx.core.net.SocketAddress; import io.vertx.core.net.TrustOptions; @@ -46,25 +47,29 @@ public MySQLConnectionFactory(VertxInternal vertx) { @Override protected Future doConnectInternal(MySQLConnectOptions options, ContextInternal context) { SslMode sslMode = options.isUsingDomainSocket() ? SslMode.DISABLED : options.getSslMode(); + ClientSSLOptions sslOptions = options.getSslOptions(); switch (sslMode) { case VERIFY_IDENTITY: - String hostnameVerificationAlgorithm = options.getHostnameVerificationAlgorithm(); + String hostnameVerificationAlgorithm = sslOptions.getHostnameVerificationAlgorithm(); if (hostnameVerificationAlgorithm == null || hostnameVerificationAlgorithm.isEmpty()) { return context.failedFuture(new IllegalArgumentException("Host verification algorithm must be specified under VERIFY_IDENTITY ssl-mode.")); } break; case VERIFY_CA: - TrustOptions trustOptions = options.getTrustOptions(); + TrustOptions trustOptions = sslOptions.getTrustOptions(); if (trustOptions == null) { return context.failedFuture(new IllegalArgumentException("Trust options must be specified under " + sslMode.name() + " ssl-mode.")); } break; + case DISABLED: + sslOptions = null; + break; } int capabilitiesFlag = capabilitiesFlags(options); if (sslMode == SslMode.PREFERRED) { - return doConnect(options, sslMode, capabilitiesFlag, context).recover(err -> doConnect(options, SslMode.DISABLED, capabilitiesFlag, context)); + return doConnect(options, sslMode, sslOptions, capabilitiesFlag, context).recover(err -> doConnect(options, SslMode.DISABLED, null, capabilitiesFlag, context)); } else { - return doConnect(options, sslMode, capabilitiesFlag, context); + return doConnect(options, sslMode, sslOptions, capabilitiesFlag, context); } } @@ -82,7 +87,7 @@ private int capabilitiesFlags(MySQLConnectOptions options) { return capabilitiesFlags; } - private Future doConnect(MySQLConnectOptions options, SslMode sslMode, int initialCapabilitiesFlags, ContextInternal context) { + private Future doConnect(MySQLConnectOptions options, SslMode sslMode, ClientSSLOptions sslOptions, int initialCapabilitiesFlags, ContextInternal context) { String username = options.getUser(); String password = options.getPassword(); String database = options.getDatabase(); @@ -122,13 +127,14 @@ private Future doConnect(MySQLConnectOptions options, SslMode sslMod } int pipeliningLimit = options.getPipeliningLimit(); MySQLAuthenticationPlugin authenticationPlugin = options.getAuthenticationPlugin(); - Future fut = netClient(new NetClientOptions(options).setSsl(false)).connect(server); + ConnectOptions connectOptions = new ConnectOptions().setRemoteAddress(server); + Future fut = client.connect(connectOptions); return fut.flatMap(so -> { VertxMetrics vertxMetrics = vertx.metricsSPI(); - ClientMetrics metrics = vertxMetrics != null ? vertxMetrics.createClientMetrics(options.getSocketAddress(), "sql", options.getMetricsName()) : null; + ClientMetrics metrics = vertxMetrics != null ? vertxMetrics.createClientMetrics(options.getSocketAddress(), "sql", tcpOptions.getMetricsName()) : null; MySQLSocketConnection conn = new MySQLSocketConnection((NetSocketInternal) so, metrics, options, cachePreparedStatements, preparedStatementCacheMaxSize, preparedStatementCacheSqlFilter, pipeliningLimit, context); conn.init(); - return Future.future(promise -> conn.sendStartupMessage(username, password, database, collation, serverRsaPublicKey, properties, sslMode, initialCapabilitiesFlags, charsetEncoding, authenticationPlugin, promise)); + return Future.future(promise -> conn.sendStartupMessage(username, password, database, collation, serverRsaPublicKey, properties, sslMode, sslOptions, initialCapabilitiesFlags, charsetEncoding, authenticationPlugin, promise)); }); } diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLSocketConnection.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLSocketConnection.java index 5394bbff5..1541d7dc5 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLSocketConnection.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLSocketConnection.java @@ -24,6 +24,7 @@ import io.vertx.core.Promise; import io.vertx.core.buffer.Buffer; import io.vertx.core.impl.ContextInternal; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.impl.NetSocketInternal; import io.vertx.core.spi.metrics.ClientMetrics; import io.vertx.mysqlclient.MySQLAuthenticationPlugin; @@ -74,11 +75,12 @@ void sendStartupMessage(String username, Buffer serverRsaPublicKey, Map properties, SslMode sslMode, + ClientSSLOptions sslOptions, int initialCapabilitiesFlags, Charset charsetEncoding, MySQLAuthenticationPlugin authenticationPlugin, Promise completionHandler) { - InitialHandshakeCommand cmd = new InitialHandshakeCommand(this, username, password, database, collation, serverRsaPublicKey, properties, sslMode, initialCapabilitiesFlags, charsetEncoding, authenticationPlugin); + InitialHandshakeCommand cmd = new InitialHandshakeCommand(this, username, password, database, collation, serverRsaPublicKey, properties, sslMode, sslOptions, initialCapabilitiesFlags, charsetEncoding, authenticationPlugin); schedule(context, cmd).onComplete(completionHandler); } @@ -112,8 +114,8 @@ protected void doSchedule(CommandBase cmd, Handler> handle } } - public Future upgradeToSsl() { - return socket.upgradeToSsl(); + public Future upgradeToSsl(ClientSSLOptions sslOptions) { + return socket.upgradeToSsl(sslOptions); } @Override diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/InitialHandshakeCommandCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/InitialHandshakeCommandCodec.java index 0973fce36..379de4020 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/InitialHandshakeCommandCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/InitialHandshakeCommandCodec.java @@ -143,7 +143,7 @@ private void handleInitialHandshake(ByteBuf payload) { encoder.clientCapabilitiesFlag |= CLIENT_SSL; sendSslRequest(); - encoder.socketConnection.upgradeToSsl().onComplete(upgrade -> { + encoder.socketConnection.upgradeToSsl(cmd.sslOptions()).onComplete(upgrade -> { if (upgrade.succeeded()) { doSendHandshakeResponseMessage(serverAuthPluginName, cmd.authenticationPlugin(), authPluginData, serverCapabilitiesFlags); } else { diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/InitialHandshakeCommand.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/InitialHandshakeCommand.java index 252e5b6d4..fe03c0b99 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/InitialHandshakeCommand.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/InitialHandshakeCommand.java @@ -12,6 +12,7 @@ package io.vertx.mysqlclient.impl.command; import io.vertx.core.buffer.Buffer; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.mysqlclient.MySQLAuthenticationPlugin; import io.vertx.mysqlclient.SslMode; import io.vertx.mysqlclient.impl.MySQLCollation; @@ -24,6 +25,7 @@ public class InitialHandshakeCommand extends AuthenticationCommandBase { private final SocketConnectionBase conn; private final SslMode sslMode; + private final ClientSSLOptions sslOptions; private final int initialCapabilitiesFlags; private final Charset charsetEncoding; private final MySQLAuthenticationPlugin authenticationPlugin; @@ -36,12 +38,14 @@ public InitialHandshakeCommand(SocketConnectionBase conn, Buffer serverRsaPublicKey, Map connectionAttributes, SslMode sslMode, + ClientSSLOptions sslOptions, int initialCapabilitiesFlags, Charset charsetEncoding, MySQLAuthenticationPlugin authenticationPlugin) { super(username, password, database, collation, serverRsaPublicKey, connectionAttributes); this.conn = conn; this.sslMode = sslMode; + this.sslOptions = sslOptions; this.initialCapabilitiesFlags = initialCapabilitiesFlags; this.charsetEncoding = charsetEncoding; this.authenticationPlugin = authenticationPlugin; @@ -55,6 +59,10 @@ public SslMode sslMode() { return sslMode; } + public ClientSSLOptions sslOptions() { + return sslOptions; + } + public int initialCapabilitiesFlags() { return initialCapabilitiesFlags; } diff --git a/vertx-mysql-client/src/test/java/io/vertx/mysqlclient/MySQLTLSTest.java b/vertx-mysql-client/src/test/java/io/vertx/mysqlclient/MySQLTLSTest.java index 02de2e5c4..680cac4ec 100644 --- a/vertx-mysql-client/src/test/java/io/vertx/mysqlclient/MySQLTLSTest.java +++ b/vertx-mysql-client/src/test/java/io/vertx/mysqlclient/MySQLTLSTest.java @@ -13,6 +13,7 @@ import io.vertx.core.Future; import io.vertx.core.Vertx; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.PemKeyCertOptions; import io.vertx.core.net.PemTrustOptions; import io.vertx.ext.unit.TestContext; @@ -42,7 +43,7 @@ public class MySQLTLSTest { @Before public void setup() { vertx = Vertx.vertx(); - options = new MySQLConnectOptions(rule.options()); + options = new MySQLConnectOptions(rule.options()).setSslOptions(new ClientSSLOptions()); nonTlsOptions = new MySQLConnectOptions(nonTlsRule.options()); /* * For testing we have to drop using the TLSv1.2. @@ -53,7 +54,7 @@ public void setup() { * and https://dev.mysql.com/doc/refman/5.7/en/encrypted-connection-protocols-ciphers.html for more details. */ if (rule.isUsingMySQL5_6()) { - options.removeEnabledSecureTransportProtocol("TLSv1.2"); + options.getSslOptions().removeEnabledSecureTransportProtocol("TLSv1.2"); } } @@ -89,10 +90,11 @@ public void testSuccessWithDisabledSslMode(TestContext ctx) { @Test public void testTlsSuccessWithPreferredSslMode(TestContext ctx) { options.setSslMode(SslMode.PREFERRED); - options.setPemTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")); - options.setPemKeyCertOptions(new PemKeyCertOptions() - .setCertPath("tls/files/client-cert.pem") - .setKeyPath("tls/files/client-key.pem")); + options.getSslOptions() + .setTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")) + .setKeyCertOptions(new PemKeyCertOptions() + .setCertPath("tls/files/client-cert.pem") + .setKeyPath("tls/files/client-key.pem")); MySQLConnection.connect(vertx, options).onComplete(ctx.asyncAssertSuccess(conn -> { ctx.assertTrue(conn.isSSL()); @@ -109,10 +111,11 @@ public void testTlsSuccessWithPreferredSslMode(TestContext ctx) { @Test public void testTlsHandshakeFailWithPreferredSslMode(TestContext ctx) { options.setSslMode(SslMode.PREFERRED); - options.setPemTrustOptions(new PemTrustOptions().addCertPath("tls/files/client-cert.pem")); // wrong file - options.setPemKeyCertOptions(new PemKeyCertOptions() - .setCertPath("tls/files/client-cert.pem") - .setKeyPath("tls/files/client-key.pem")); + options.getSslOptions() + .setTrustOptions(new PemTrustOptions().addCertPath("tls/files/client-cert.pem")) + .setKeyCertOptions(new PemKeyCertOptions() + .setCertPath("tls/files/client-cert.pem") + .setKeyPath("tls/files/client-key.pem")); MySQLConnection.connect(vertx, options).onComplete(ctx.asyncAssertSuccess(conn -> { ctx.assertFalse(conn.isSSL()); @@ -129,10 +132,11 @@ public void testTlsHandshakeFailWithPreferredSslMode(TestContext ctx) { @Test public void testNonTlsConnWithPreferredSslMode(TestContext ctx) { nonTlsOptions.setSslMode(SslMode.PREFERRED); - nonTlsOptions.setPemTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")); - nonTlsOptions.setPemKeyCertOptions(new PemKeyCertOptions() - .setCertPath("tls/files/client-cert.pem") - .setKeyPath("tls/files/client-key.pem")); + options.getSslOptions() + .setTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")) + .setKeyCertOptions(new PemKeyCertOptions() + .setCertPath("tls/files/client-cert.pem") + .setKeyPath("tls/files/client-key.pem")); MySQLConnection.connect(vertx, nonTlsOptions).onComplete( ctx.asyncAssertSuccess(conn -> { ctx.assertFalse(conn.isSSL()); @@ -149,10 +153,11 @@ public void testNonTlsConnWithPreferredSslMode(TestContext ctx) { @Test public void testSuccessWithRequiredSslMode(TestContext ctx) { options.setSslMode(SslMode.REQUIRED); - options.setPemTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")); - options.setPemKeyCertOptions(new PemKeyCertOptions() - .setCertPath("tls/files/client-cert.pem") - .setKeyPath("tls/files/client-key.pem")); + options.getSslOptions() + .setTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")) + .setKeyCertOptions(new PemKeyCertOptions() + .setCertPath("tls/files/client-cert.pem") + .setKeyPath("tls/files/client-key.pem")); MySQLConnection.connect(vertx, options).onComplete( ctx.asyncAssertSuccess(conn -> { ctx.assertTrue(conn.isSSL()); @@ -169,10 +174,11 @@ public void testSuccessWithRequiredSslMode(TestContext ctx) { @Test public void testPoolSuccessWithRequiredSslMode(TestContext ctx) { options.setSslMode(SslMode.REQUIRED); - options.setPemTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")); - options.setPemKeyCertOptions(new PemKeyCertOptions() - .setCertPath("tls/files/client-cert.pem") - .setKeyPath("tls/files/client-key.pem")); + options.getSslOptions() + .setTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")) + .setKeyCertOptions(new PemKeyCertOptions() + .setCertPath("tls/files/client-cert.pem") + .setKeyPath("tls/files/client-key.pem")); MySQLPool pool = MySQLPool.pool(vertx, options, new PoolOptions().setMaxSize(5)); @@ -191,7 +197,8 @@ public void testPoolSuccessWithRequiredSslMode(TestContext ctx) { @Test public void testSuccessWithOnlyCertificate(TestContext ctx) { options.setSslMode(SslMode.REQUIRED); - options.setPemTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")); + options.getSslOptions() + .setTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")); MySQLConnection.connect(vertx, options).onComplete(ctx.asyncAssertSuccess(conn -> { ctx.assertTrue(conn.isSSL()); @@ -208,7 +215,7 @@ public void testSuccessWithOnlyCertificate(TestContext ctx) { @Test public void testSuccessWithoutCertificate(TestContext ctx) { options.setSslMode(SslMode.REQUIRED); - options.setTrustAll(true); + options.getSslOptions().setTrustAll(true); MySQLConnection.connect(vertx, options).onComplete( ctx.asyncAssertSuccess(conn -> { ctx.assertTrue(conn.isSSL()); @@ -225,10 +232,11 @@ public void testSuccessWithoutCertificate(TestContext ctx) { @Test public void testSuccessWithVerifyCaSslMode(TestContext ctx) { options.setSslMode(SslMode.VERIFY_CA); - options.setPemTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")); - options.setPemKeyCertOptions(new PemKeyCertOptions() - .setCertPath("tls/files/client-cert.pem") - .setKeyPath("tls/files/client-key.pem")); + options.getSslOptions() + .setTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")) + .setKeyCertOptions(new PemKeyCertOptions() + .setCertPath("tls/files/client-cert.pem") + .setKeyPath("tls/files/client-key.pem")); MySQLConnection.connect(vertx, options).onComplete( ctx.asyncAssertSuccess(conn -> { ctx.assertTrue(conn.isSSL()); @@ -245,10 +253,11 @@ public void testSuccessWithVerifyCaSslMode(TestContext ctx) { @Test public void testConnFailWithVerifyCaSslMode(TestContext ctx) { options.setSslMode(SslMode.VERIFY_CA); - options.setTrustAll(true); - options.setPemKeyCertOptions(new PemKeyCertOptions() - .setCertPath("tls/files/client-cert.pem") - .setKeyPath("tls/files/client-key.pem")); + options.getSslOptions() + .setTrustAll(true) + .setKeyCertOptions(new PemKeyCertOptions() + .setCertPath("tls/files/client-cert.pem") + .setKeyPath("tls/files/client-key.pem")); MySQLConnection.connect(vertx, options).onComplete( ctx.asyncAssertFailure(error -> { ctx.assertEquals("Trust options must be specified under VERIFY_CA ssl-mode.", error.getMessage()); @@ -258,10 +267,11 @@ public void testConnFailWithVerifyCaSslMode(TestContext ctx) { @Test public void testPoolFailWithVerifyCaSslMode(TestContext ctx) { options.setSslMode(SslMode.VERIFY_CA); - options.setTrustAll(true); - options.setPemKeyCertOptions(new PemKeyCertOptions() - .setCertPath("tls/files/client-cert.pem") - .setKeyPath("tls/files/client-key.pem")); + options.getSslOptions() + .setTrustAll(true) + .setKeyCertOptions(new PemKeyCertOptions() + .setCertPath("tls/files/client-cert.pem") + .setKeyPath("tls/files/client-key.pem")); try { MySQLPool.pool(vertx, options, new PoolOptions()); @@ -273,10 +283,11 @@ public void testPoolFailWithVerifyCaSslMode(TestContext ctx) { @Test public void testConnFailWithVerifyIdentitySslMode(TestContext ctx) { options.setSslMode(SslMode.VERIFY_IDENTITY); - options.setPemTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")); - options.setPemKeyCertOptions(new PemKeyCertOptions() - .setCertPath("tls/files/client-cert.pem") - .setKeyPath("tls/files/client-key.pem")); + options.getSslOptions() + .setTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")) + .setKeyCertOptions(new PemKeyCertOptions() + .setCertPath("tls/files/client-cert.pem") + .setKeyPath("tls/files/client-key.pem")); MySQLConnection.connect(vertx, options).onComplete( ctx.asyncAssertFailure(error -> { ctx.assertEquals("Host verification algorithm must be specified under VERIFY_IDENTITY ssl-mode.", error.getMessage()); @@ -294,7 +305,8 @@ public void testConnFail(TestContext ctx) { @Test public void testChangeUser(TestContext ctx) { options.setSslMode(SslMode.REQUIRED); - options.setPemTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")); + options.getSslOptions() + .setTrustOptions(new PemTrustOptions().addCertPath("tls/files/ca.pem")); MySQLConnection.connect(vertx, options).onComplete( ctx.asyncAssertSuccess(conn -> { conn diff --git a/vertx-mysql-client/src/test/java/io/vertx/mysqlclient/MySQLUnixDomainSocketTest.java b/vertx-mysql-client/src/test/java/io/vertx/mysqlclient/MySQLUnixDomainSocketTest.java index ec010f502..340a00970 100644 --- a/vertx-mysql-client/src/test/java/io/vertx/mysqlclient/MySQLUnixDomainSocketTest.java +++ b/vertx-mysql-client/src/test/java/io/vertx/mysqlclient/MySQLUnixDomainSocketTest.java @@ -35,6 +35,7 @@ public class MySQLUnixDomainSocketTest extends MySQLTestBase { private MySQLPool client; private MySQLConnectOptions options; + private Vertx vertx; @Before public void setUp() { @@ -47,12 +48,16 @@ public void setUp() { options.setHost(rule.domainSocketPath()); } assumeTrue(options.isUsingDomainSocket()); + vertx = Vertx.vertx(new VertxOptions().setPreferNativeTransport(true)); } @After - public void after() { + public void after(TestContext ctx) { + if (vertx != null) { + vertx.close().onComplete(ctx.asyncAssertSuccess()); + } if (client != null) { - client.close(); + client.close().onComplete(ctx.asyncAssertSuccess()); } } @@ -69,7 +74,7 @@ public void uriSocketAttributeTest(TestContext context) throws UnsupportedEncodi } private void uriTest(TestContext context, String uri) throws UnsupportedEncodingException { - client = MySQLPool.pool(uri); + client = MySQLPool.pool(vertx, uri); client .getConnection() .onComplete(context.asyncAssertSuccess(SqlClient::close)); @@ -77,7 +82,7 @@ private void uriTest(TestContext context, String uri) throws UnsupportedEncoding @Test public void simpleConnect(TestContext context) { - client = MySQLPool.pool(new MySQLConnectOptions(options), new PoolOptions()); + client = MySQLPool.pool(vertx, new MySQLConnectOptions(options), new PoolOptions()); client .getConnection() .onComplete(context.asyncAssertSuccess(SqlClient::close)); @@ -103,7 +108,7 @@ public void connectWithVertxInstance(TestContext context) { @Test public void testIgnoreSslMode(TestContext context) { - client = MySQLPool.pool(new MySQLConnectOptions(options).setSslMode(SslMode.REQUIRED), new PoolOptions()); + client = MySQLPool.pool(vertx, new MySQLConnectOptions(options).setSslMode(SslMode.REQUIRED), new PoolOptions()); client .getConnection() .onComplete(context.asyncAssertSuccess(conn -> { diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/OracleConnectOptions.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/OracleConnectOptions.java index d843bb3c4..cd659f8eb 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/OracleConnectOptions.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/OracleConnectOptions.java @@ -40,6 +40,7 @@ public static OracleConnectOptions wrap(SqlConnectOptions options) { public static final String DEFAULT_USER = ""; public static final String DEFAULT_PASSWORD = ""; public static final String DEFAULT_DATABASE = ""; + public static final boolean DEFAULT_SSL = false; private String serviceId; private String serviceName; @@ -47,6 +48,7 @@ public static OracleConnectOptions wrap(SqlConnectOptions options) { private String instanceName; private String tnsAlias; private String tnsAdmin; + private boolean ssl; public OracleConnectOptions() { super(); @@ -64,6 +66,7 @@ private void copyFields(OracleConnectOptions other) { this.instanceName = other.instanceName; this.tnsAlias = other.tnsAlias; this.tnsAdmin = other.tnsAdmin; + this.ssl = other.ssl; } public OracleConnectOptions(SqlConnectOptions options) { @@ -329,9 +332,23 @@ public OracleConnectOptions setTracingPolicy(TracingPolicy tracingPolicy) { return (OracleConnectOptions) super.setTracingPolicy(tracingPolicy); } - @Override + /** + * + * @return is SSL/TLS enabled? + */ + public boolean isSsl() { + return ssl; + } + + /** + * Set whether SSL/TLS is enabled + * + * @param ssl true if enabled + * @return a reference to this, so the API can be used fluently + */ public OracleConnectOptions setSsl(boolean ssl) { - return (OracleConnectOptions) super.setSsl(ssl); + this.ssl = ssl; + return this; } @Override diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleConnectionFactory.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleConnectionFactory.java index fe2611d0d..86829bf6e 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleConnectionFactory.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleConnectionFactory.java @@ -61,7 +61,7 @@ private OracleDataSource getDatasource(SqlConnectOptions options) { public Future connect(Context context, OracleConnectOptions options) { OracleDataSource datasource = getDatasource(options); VertxMetrics vertxMetrics = ((VertxInternal)context.owner()).metricsSPI(); - ClientMetrics metrics = vertxMetrics != null ? vertxMetrics.createClientMetrics(options.getSocketAddress(), "sql", options.getMetricsName()) : null; + ClientMetrics metrics = vertxMetrics != null ? vertxMetrics.createClientMetrics(options.getSocketAddress(), "sql", null) : null; ContextInternal ctx = (ContextInternal) context; return executeBlocking(context, () -> { OracleConnection orac = datasource.createConnectionBuilder().build(); diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleDatabaseHelper.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleDatabaseHelper.java index b41eeca30..516f0d7d2 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleDatabaseHelper.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleDatabaseHelper.java @@ -106,10 +106,10 @@ private static void configureStandardOptions(OracleDataSource oracleDataSource, runOrHandleSQLException(() -> oracleDataSource.setPassword(password.toString())); } - int connectTimeout = options.getConnectTimeout(); - if (connectTimeout > 0) { - runOrHandleSQLException(() -> oracleDataSource.setLoginTimeout(connectTimeout)); - } +// int connectTimeout = options.getConnectTimeout(); +// if (connectTimeout > 0) { +// runOrHandleSQLException(() -> oracleDataSource.setLoginTimeout(connectTimeout)); +// } } private static void configureExtendedOptions(OracleDataSource oracleDataSource, OracleConnectOptions options) { diff --git a/vertx-pg-client/src/main/java/examples/PgClientExamples.java b/vertx-pg-client/src/main/java/examples/PgClientExamples.java index a16fe2cc1..9745dc550 100644 --- a/vertx-pg-client/src/main/java/examples/PgClientExamples.java +++ b/vertx-pg-client/src/main/java/examples/PgClientExamples.java @@ -20,6 +20,7 @@ import io.vertx.core.Future; import io.vertx.core.Vertx; import io.vertx.core.json.JsonObject; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.PemTrustOptions; import io.vertx.docgen.Source; import io.vertx.pgclient.PgConnectOptions; @@ -465,7 +466,7 @@ public void ex10(Vertx vertx) { .setUser("user") .setPassword("secret") .setSslMode(SslMode.VERIFY_CA) - .setPemTrustOptions(new PemTrustOptions().addCertPath("/path/to/cert.pem")); + .setSslOptions(new ClientSSLOptions().setTrustOptions(new PemTrustOptions().addCertPath("/path/to/cert.pem"))); PgConnection .connect(vertx, options) diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/PgConnectOptions.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/PgConnectOptions.java index 3d7f0c649..3b4fc1ab6 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/PgConnectOptions.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/PgConnectOptions.java @@ -22,7 +22,6 @@ import io.vertx.core.tracing.TracingPolicy; import io.vertx.pgclient.impl.PgConnectionUriParser; import io.vertx.codegen.annotations.DataObject; -import io.vertx.core.buffer.Buffer; import io.vertx.core.json.JsonObject; import io.vertx.core.net.*; import io.vertx.sqlclient.SqlConnectOptions; @@ -30,8 +29,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import static java.lang.Integer.parseInt; @@ -259,224 +256,24 @@ public PgConnectOptions setUseLayer7Proxy(boolean useLayer7Proxy) { return this; } - @Override - public PgConnectOptions setSendBufferSize(int sendBufferSize) { - return (PgConnectOptions)super.setSendBufferSize(sendBufferSize); - } - - @Override - public PgConnectOptions setReceiveBufferSize(int receiveBufferSize) { - return (PgConnectOptions)super.setReceiveBufferSize(receiveBufferSize); - } - - @Override - public PgConnectOptions setReuseAddress(boolean reuseAddress) { - return (PgConnectOptions)super.setReuseAddress(reuseAddress); - } - - @Override - public PgConnectOptions setTrafficClass(int trafficClass) { - return (PgConnectOptions)super.setTrafficClass(trafficClass); - } - - @Override - public PgConnectOptions setTcpNoDelay(boolean tcpNoDelay) { - return (PgConnectOptions)super.setTcpNoDelay(tcpNoDelay); - } - - @Override - public PgConnectOptions setTcpKeepAlive(boolean tcpKeepAlive) { - return (PgConnectOptions)super.setTcpKeepAlive(tcpKeepAlive); - } - - @Override - public PgConnectOptions setSoLinger(int soLinger) { - return (PgConnectOptions)super.setSoLinger(soLinger); - } - - @Override - public PgConnectOptions setIdleTimeout(int idleTimeout) { - return (PgConnectOptions)super.setIdleTimeout(idleTimeout); - } - - @Override - public PgConnectOptions setIdleTimeoutUnit(TimeUnit idleTimeoutUnit) { - return (PgConnectOptions) super.setIdleTimeoutUnit(idleTimeoutUnit); - } - - @Override - public PgConnectOptions setSsl(boolean ssl) { - if (ssl) { - setSslMode(SslMode.VERIFY_CA); - } else { - setSslMode(SslMode.DISABLE); - } - return this; - } - - @Override - public PgConnectOptions setKeyCertOptions(KeyCertOptions options) { - return (PgConnectOptions)super.setKeyCertOptions(options); - } - - @Override - public PgConnectOptions setKeyStoreOptions(JksOptions options) { - return (PgConnectOptions)super.setKeyStoreOptions(options); - } - - @Override - public PgConnectOptions setPfxKeyCertOptions(PfxOptions options) { - return (PgConnectOptions)super.setPfxKeyCertOptions(options); - } - - @Override - public PgConnectOptions setPemKeyCertOptions(PemKeyCertOptions options) { - return (PgConnectOptions)super.setPemKeyCertOptions(options); - } - - @Override - public PgConnectOptions setTrustOptions(TrustOptions options) { - return (PgConnectOptions)super.setTrustOptions(options); - } - - @Override - public PgConnectOptions setTrustStoreOptions(JksOptions options) { - return (PgConnectOptions)super.setTrustStoreOptions(options); - } - - @Override - public PgConnectOptions setPemTrustOptions(PemTrustOptions options) { - return (PgConnectOptions)super.setPemTrustOptions(options); - } - - @Override - public PgConnectOptions setPfxTrustOptions(PfxOptions options) { - return (PgConnectOptions)super.setPfxTrustOptions(options); - } - - @Override - public PgConnectOptions addEnabledCipherSuite(String suite) { - return (PgConnectOptions)super.addEnabledCipherSuite(suite); - } - - @Override - public PgConnectOptions addEnabledSecureTransportProtocol(String protocol) { - return (PgConnectOptions)super.addEnabledSecureTransportProtocol(protocol); - } - - @Override - public PgConnectOptions addCrlPath(String crlPath) throws NullPointerException { - return (PgConnectOptions)super.addCrlPath(crlPath); - } - - @Override - public PgConnectOptions addCrlValue(Buffer crlValue) throws NullPointerException { - return (PgConnectOptions)super.addCrlValue(crlValue); - } - - @Override - public PgConnectOptions setTrustAll(boolean trustAll) { - return (PgConnectOptions)super.setTrustAll(trustAll); - } - - @Override - public PgConnectOptions setConnectTimeout(int connectTimeout) { - return (PgConnectOptions)super.setConnectTimeout(connectTimeout); - } - - @Override - public PgConnectOptions setMetricsName(String metricsName) { - return (PgConnectOptions)super.setMetricsName(metricsName); - } - @Override public PgConnectOptions setReconnectAttempts(int attempts) { return (PgConnectOptions)super.setReconnectAttempts(attempts); } - @Override - public PgConnectOptions setHostnameVerificationAlgorithm(String hostnameVerificationAlgorithm) { - return (PgConnectOptions)super.setHostnameVerificationAlgorithm(hostnameVerificationAlgorithm); - } - - @Override - public PgConnectOptions setLogActivity(boolean logEnabled) { - return (PgConnectOptions)super.setLogActivity(logEnabled); - } - @Override public PgConnectOptions setReconnectInterval(long interval) { return (PgConnectOptions)super.setReconnectInterval(interval); } @Override - public PgConnectOptions setProxyOptions(ProxyOptions proxyOptions) { - return (PgConnectOptions)super.setProxyOptions(proxyOptions); - } - - @Override - public PgConnectOptions setLocalAddress(String localAddress) { - return (PgConnectOptions)super.setLocalAddress(localAddress); - } - - @Override - public PgConnectOptions setUseAlpn(boolean useAlpn) { - return (PgConnectOptions)super.setUseAlpn(useAlpn); - } - - @Override - public PgConnectOptions setSslEngineOptions(SSLEngineOptions sslEngineOptions) { - return (PgConnectOptions)super.setSslEngineOptions(sslEngineOptions); - } - - @Override - public PgConnectOptions setJdkSslEngineOptions(JdkSSLEngineOptions sslEngineOptions) { - return (PgConnectOptions)super.setJdkSslEngineOptions(sslEngineOptions); - } - - @Override - public PgConnectOptions setOpenSslEngineOptions(OpenSSLEngineOptions sslEngineOptions) { - return (PgConnectOptions)super.setOpenSslEngineOptions(sslEngineOptions); - } - - @Override - public PgConnectOptions setReusePort(boolean reusePort) { - return (PgConnectOptions) super.setReusePort(reusePort); - } - - @Override - public PgConnectOptions setTcpFastOpen(boolean tcpFastOpen) { - return (PgConnectOptions) super.setTcpFastOpen(tcpFastOpen); - } - - @Override - public PgConnectOptions setTcpCork(boolean tcpCork) { - return (PgConnectOptions) super.setTcpCork(tcpCork); - } - - @Override - public PgConnectOptions setTcpQuickAck(boolean tcpQuickAck) { - return (PgConnectOptions) super.setTcpQuickAck(tcpQuickAck); - } - - @Override - public PgConnectOptions setEnabledSecureTransportProtocols(Set enabledSecureTransportProtocols) { - return (PgConnectOptions) super.setEnabledSecureTransportProtocols(enabledSecureTransportProtocols); - } - - @Override - public PgConnectOptions setSslHandshakeTimeout(long sslHandshakeTimeout) { - return (PgConnectOptions) super.setSslHandshakeTimeout(sslHandshakeTimeout); - } - - @Override - public PgConnectOptions setSslHandshakeTimeoutUnit(TimeUnit sslHandshakeTimeoutUnit) { - return (PgConnectOptions) super.setSslHandshakeTimeoutUnit(sslHandshakeTimeoutUnit); + public PgConnectOptions setTracingPolicy(TracingPolicy tracingPolicy) { + return (PgConnectOptions) super.setTracingPolicy(tracingPolicy); } @Override - public PgConnectOptions setTracingPolicy(TracingPolicy tracingPolicy) { - return (PgConnectOptions) super.setTracingPolicy(tracingPolicy); + public PgConnectOptions setSslOptions(ClientSSLOptions sslOptions) { + return (PgConnectOptions) super.setSslOptions(sslOptions); } /** diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/InitiateSslHandler.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/InitiateSslHandler.java index b4819dc0a..1f6795339 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/InitiateSslHandler.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/InitiateSslHandler.java @@ -22,9 +22,8 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.codec.DecoderException; -import io.vertx.core.AsyncResult; -import io.vertx.core.Handler; import io.vertx.core.Promise; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.pgclient.impl.codec.PgProtocolConstants; import io.vertx.sqlclient.impl.SocketConnectionBase; import io.vertx.core.VertxException; @@ -33,10 +32,12 @@ public class InitiateSslHandler extends ChannelInboundHandlerAdapter { private static final int code = 80877103; private final SocketConnectionBase conn; + private final ClientSSLOptions sslOptions; private final Promise upgradePromise; - public InitiateSslHandler(SocketConnectionBase conn, Promise upgradePromise) { + public InitiateSslHandler(SocketConnectionBase conn, ClientSSLOptions sslOptions, Promise upgradePromise) { this.conn = conn; + this.sslOptions = sslOptions; this.upgradePromise = upgradePromise; } @@ -61,7 +62,7 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception case PgProtocolConstants.MESSAGE_TYPE_SSL_YES: { conn .socket() - .upgradeToSsl() + .upgradeToSsl(sslOptions) .onComplete(ar -> { if (ar.succeeded()) { ctx.pipeline().remove(this); diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgConnectionFactory.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgConnectionFactory.java index 53ff12295..82d0b2e25 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgConnectionFactory.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgConnectionFactory.java @@ -24,6 +24,7 @@ import io.vertx.core.impl.ContextInternal; import io.vertx.core.impl.VertxInternal; import io.vertx.core.impl.future.PromiseInternal; +import io.vertx.core.net.ConnectOptions; import io.vertx.core.net.NetSocket; import io.vertx.core.net.SocketAddress; import io.vertx.core.net.TrustOptions; @@ -52,12 +53,12 @@ public PgConnectionFactory(VertxInternal context) { private void checkSslMode(PgConnectOptions options) { switch (options.getSslMode()) { case VERIFY_FULL: - String hostnameVerificationAlgorithm = options.getHostnameVerificationAlgorithm(); + String hostnameVerificationAlgorithm = options.getSslOptions().getHostnameVerificationAlgorithm(); if (hostnameVerificationAlgorithm == null || hostnameVerificationAlgorithm.isEmpty()) { throw new IllegalArgumentException("Host verification algorithm must be specified under verify-full sslmode"); } case VERIFY_CA: - TrustOptions trustOptions = options.getTrustOptions(); + TrustOptions trustOptions = options.getSslOptions().getTrustOptions(); if (trustOptions == null) { throw new IllegalArgumentException("Trust options must be specified under verify-full or verify-ca sslmode"); } @@ -77,7 +78,7 @@ protected Future doConnectInternal(PgConnectOptions options, Context String database = options.getDatabase(); SocketAddress server = options.getSocketAddress(); Map properties = options.getProperties() != null ? Collections.unmodifiableMap(options.getProperties()) : null; - return doConnect(server, context, (PgConnectOptions) options).flatMap(conn -> { + return doConnect(server, context, options).flatMap(conn -> { PgSocketConnection socket = (PgSocketConnection) conn; socket.init(); return Future.future(p -> socket.sendStartupMessage(username, password, database, properties, p)) @@ -98,21 +99,23 @@ public void cancelRequest(PgConnectOptions options, int processId, int secretKey private Future doConnect(SocketAddress server, ContextInternal context, PgConnectOptions options) { SslMode sslMode = options.isUsingDomainSocket() ? SslMode.DISABLE : options.getSslMode(); + ConnectOptions connectOptions = new ConnectOptions() + .setRemoteAddress(server); Future connFuture; switch (sslMode) { case DISABLE: - connFuture = doConnect(server, context, false, options); + connFuture = doConnect(connectOptions, context, false, options); break; case ALLOW: - connFuture = doConnect(server, context,false, options).recover(err -> doConnect(server, context,true, options)); + connFuture = doConnect(connectOptions, context, false, options).recover(err -> doConnect(connectOptions, context, true, options)); break; case PREFER: - connFuture = doConnect(server, context,true, options).recover(err -> doConnect(server, context,false, options)); + connFuture = doConnect(connectOptions, context, true, options).recover(err -> doConnect(connectOptions, context, false, options)); break; case REQUIRE: case VERIFY_CA: case VERIFY_FULL: - connFuture = doConnect(server, context, true, options); + connFuture = doConnect(connectOptions, context, true, options); break; default: return context.failedFuture(new IllegalArgumentException("Unsupported SSL mode")); @@ -120,20 +123,20 @@ private Future doConnect(SocketAddress server, ContextInternal conte return connFuture; } - private Future doConnect(SocketAddress server, ContextInternal context, boolean ssl, PgConnectOptions options) { + private Future doConnect(ConnectOptions connectOptions, ContextInternal context, boolean ssl, PgConnectOptions options) { Future soFut; try { - soFut = netClient(options).connect(server, (String) null); + soFut = client.connect(connectOptions); } catch (Exception e) { // Client is closed return context.failedFuture(e); } Future connFut = soFut.map(so -> newSocketConnection(context, (NetSocketInternal) so, options)); - if (ssl && !server.isDomainSocket()) { + if (ssl && !connectOptions.getRemoteAddress().isDomainSocket()) { // upgrade connection to SSL if needed connFut = connFut.flatMap(conn -> Future.future(p -> { PgSocketConnection socket = (PgSocketConnection) conn; - socket.upgradeToSSLConnection(ar2 -> { + socket.upgradeToSSLConnection(options.getSslOptions(), ar2 -> { if (ar2.succeeded()) { p.complete(conn); } else { @@ -169,7 +172,7 @@ private PgSocketConnection newSocketConnection(ContextInternal context, NetSocke int pipeliningLimit = options.getPipeliningLimit(); boolean useLayer7Proxy = options.getUseLayer7Proxy(); VertxMetrics vertxMetrics = vertx.metricsSPI(); - ClientMetrics metrics = vertxMetrics != null ? vertxMetrics.createClientMetrics(options.getSocketAddress(), "sql", options.getMetricsName()) : null; + ClientMetrics metrics = vertxMetrics != null ? vertxMetrics.createClientMetrics(options.getSocketAddress(), "sql", tcpOptions.getMetricsName()) : null; PgSocketConnection conn = new PgSocketConnection(socket, metrics, options, cachePreparedStatements, preparedStatementCacheMaxSize, preparedStatementCacheSqlFilter, pipeliningLimit, useLayer7Proxy, context); return conn; } diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgSocketConnection.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgSocketConnection.java index ac5bff03a..378c96789 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgSocketConnection.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgSocketConnection.java @@ -25,6 +25,7 @@ import io.vertx.core.Promise; import io.vertx.core.buffer.Buffer; import io.vertx.core.impl.ContextInternal; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.impl.NetSocketInternal; import io.vertx.core.spi.metrics.ClientMetrics; import io.vertx.pgclient.PgConnectOptions; @@ -145,7 +146,7 @@ public DatabaseMetadata getDatabaseMetaData() { return dbMetaData; } - void upgradeToSSLConnection(Handler> completionHandler) { + void upgradeToSSLConnection(ClientSSLOptions sslOptions, Handler> completionHandler) { ChannelPipeline pipeline = socket.channelHandlerContext().pipeline(); Promise upgradePromise = Promise.promise(); upgradePromise.future().onComplete(ar->{ @@ -160,7 +161,7 @@ void upgradeToSSLConnection(Handler> completionHandler) { completionHandler.handle(Future.failedFuture(cause)); } }); - pipeline.addBefore("handler", "initiate-ssl-handler", new InitiateSslHandler(this, upgradePromise)); + pipeline.addBefore("handler", "initiate-ssl-handler", new InitiateSslHandler(this, sslOptions, upgradePromise)); } @Override diff --git a/vertx-pg-client/src/test/java/io/vertx/pgclient/PgClientTestBase.java b/vertx-pg-client/src/test/java/io/vertx/pgclient/PgClientTestBase.java index 90160aa82..a983df71d 100644 --- a/vertx-pg-client/src/test/java/io/vertx/pgclient/PgClientTestBase.java +++ b/vertx-pg-client/src/test/java/io/vertx/pgclient/PgClientTestBase.java @@ -20,6 +20,7 @@ import io.vertx.core.AsyncResult; import io.vertx.core.Handler; import io.vertx.core.Vertx; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.NetSocket; import io.vertx.ext.unit.Async; import io.vertx.ext.unit.TestContext; @@ -64,7 +65,7 @@ public void tearDown(TestContext ctx) { @Test public void testConnectNonSSLServer(TestContext ctx) { Async async = ctx.async(); - options.setSslMode(SslMode.REQUIRE).setTrustAll(true); + options.setSslMode(SslMode.REQUIRE).setSslOptions(new ClientSSLOptions().setTrustAll(true)); connector.accept(ctx.asyncAssertFailure(err -> { ctx.assertEquals("Postgres Server does not handle SSL connection", err.getMessage()); async.complete(); diff --git a/vertx-pg-client/src/test/java/io/vertx/pgclient/TLSTest.java b/vertx-pg-client/src/test/java/io/vertx/pgclient/TLSTest.java index 9f7d34cfe..bc455c428 100644 --- a/vertx-pg-client/src/test/java/io/vertx/pgclient/TLSTest.java +++ b/vertx-pg-client/src/test/java/io/vertx/pgclient/TLSTest.java @@ -18,6 +18,7 @@ package io.vertx.pgclient; import io.vertx.core.Vertx; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.PemTrustOptions; import io.vertx.ext.unit.Async; import io.vertx.ext.unit.TestContext; @@ -54,7 +55,7 @@ public void testTLS(TestContext ctx) { PgConnectOptions options = new PgConnectOptions(rule.options()) .setSslMode(SslMode.REQUIRE) - .setPemTrustOptions(new PemTrustOptions().addCertPath("tls/server.crt")); + .setSslOptions(new ClientSSLOptions().setTrustOptions(new PemTrustOptions().addCertPath("tls/server.crt"))); PgConnection.connect(vertx, options.setSslMode(SslMode.REQUIRE)).onComplete(ctx.asyncAssertSuccess(conn -> { ctx.assertTrue(conn.isSSL()); conn @@ -73,7 +74,7 @@ public void testTLS(TestContext ctx) { @Test public void testTLSTrustAll(TestContext ctx) { Async async = ctx.async(); - PgConnection.connect(vertx, rule.options().setSslMode(SslMode.REQUIRE).setTrustAll(true)).onComplete(ctx.asyncAssertSuccess(conn -> { + PgConnection.connect(vertx, rule.options().setSslMode(SslMode.REQUIRE).setSslOptions(new ClientSSLOptions().setTrustAll(true))).onComplete(ctx.asyncAssertSuccess(conn -> { ctx.assertTrue(conn.isSSL()); async.complete(); })); @@ -82,7 +83,7 @@ public void testTLSTrustAll(TestContext ctx) { @Test public void testTLSInvalidCertificate(TestContext ctx) { Async async = ctx.async(); - PgConnection.connect(vertx, rule.options().setSslMode(SslMode.REQUIRE)).onComplete(ctx.asyncAssertFailure(err -> { + PgConnection.connect(vertx, rule.options().setSslMode(SslMode.REQUIRE).setSslOptions(new ClientSSLOptions().setTrustOptions(new PemTrustOptions().addCertPath("tls/another.crt")))).onComplete(ctx.asyncAssertFailure(err -> { // ctx.assertEquals(err.getClass(), VertxException.class); ctx.assertEquals(err.getMessage(), "SSL handshake failed"); async.complete(); @@ -116,7 +117,7 @@ public void testSslModePrefer(TestContext ctx) { Async async = ctx.async(); PgConnectOptions options = rule.options() .setSslMode(SslMode.PREFER) - .setTrustAll(true); + .setSslOptions(new ClientSSLOptions().setTrustAll(true)); PgConnection.connect(vertx, new PgConnectOptions(options)).onComplete(ctx.asyncAssertSuccess(conn -> { ctx.assertTrue(conn.isSSL()); async.complete(); @@ -127,7 +128,7 @@ public void testSslModePrefer(TestContext ctx) { public void testSslModeVerifyCaConf(TestContext ctx) { PgConnectOptions options = rule.options() .setSslMode(SslMode.VERIFY_CA) - .setTrustAll(true); + .setSslOptions(new ClientSSLOptions().setTrustAll(true)); PgConnection.connect(vertx, new PgConnectOptions(options)).onComplete(ctx.asyncAssertFailure(error -> { ctx.assertEquals("Trust options must be specified under verify-full or verify-ca sslmode", error.getMessage()); })); @@ -136,6 +137,7 @@ public void testSslModeVerifyCaConf(TestContext ctx) { @Test public void testSslModeVerifyFullConf(TestContext ctx) { PgConnectOptions options = rule.options() + .setSslOptions(new ClientSSLOptions().setTrustOptions(new PemTrustOptions().addCertPath("tls/another.crt"))) .setSslMode(SslMode.VERIFY_FULL); PgConnection.connect(vertx, new PgConnectOptions(options)).onComplete(ctx.asyncAssertFailure(error -> { ctx.assertEquals("Host verification algorithm must be specified under verify-full sslmode", error.getMessage()); diff --git a/vertx-pg-client/src/test/java/io/vertx/pgclient/UnixDomainSocketTest.java b/vertx-pg-client/src/test/java/io/vertx/pgclient/UnixDomainSocketTest.java index 05aaf0697..1e7b978b8 100644 --- a/vertx-pg-client/src/test/java/io/vertx/pgclient/UnixDomainSocketTest.java +++ b/vertx-pg-client/src/test/java/io/vertx/pgclient/UnixDomainSocketTest.java @@ -19,7 +19,6 @@ import io.vertx.pgclient.junit.PgRule; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; -import io.vertx.ext.unit.Async; import io.vertx.ext.unit.TestContext; import io.vertx.ext.unit.junit.VertxUnitRunner; import io.vertx.sqlclient.PoolOptions; @@ -30,7 +29,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; @RunWith(VertxUnitRunner.class) @@ -50,9 +48,11 @@ public class UnixDomainSocketTest { public static PgRule rule = new PgRule().domainSockets(nativeTransportEnabled); private PgPool client; private PgConnectOptions options; + private Vertx vertx; @Before public void before() { + vertx = Vertx.vertx(new VertxOptions().setPreferNativeTransport(true)); options = rule.options(); if (unixSocketDirectory != null && !unixSocketDirectory.isEmpty()) { options.setHost(unixSocketDirectory); @@ -64,6 +64,9 @@ public void before() { @After public void after(TestContext ctx) { + if (vertx != null) { + vertx.close().onComplete(ctx.asyncAssertSuccess()); + } if (client != null) { client.close().onComplete(ctx.asyncAssertSuccess()); } @@ -73,7 +76,7 @@ public void after(TestContext ctx) { public void uriTest(TestContext context) { assumeTrue(options.isUsingDomainSocket()); String uri = "postgresql://postgres:postgres@/postgres?host=" + options.getHost() + "&port=" + options.getPort(); - client = PgPool.pool(uri); + client = PgPool.pool(vertx, uri); client .getConnection() .onComplete(context.asyncAssertSuccess(SqlClient::close)); @@ -82,7 +85,7 @@ public void uriTest(TestContext context) { @Test public void simpleConnect(TestContext context) { assumeTrue(options.isUsingDomainSocket()); - client = PgPool.pool(new PgConnectOptions(options), new PoolOptions()); + client = PgPool.pool(vertx, new PgConnectOptions(options), new PoolOptions()); client .getConnection() .onComplete(context.asyncAssertSuccess(pgConnection -> pgConnection.close().onComplete(context.asyncAssertSuccess()))); @@ -91,26 +94,19 @@ public void simpleConnect(TestContext context) { @Test public void connectWithVertxInstance(TestContext context) { assumeTrue(options.isUsingDomainSocket()); - Vertx vertx = Vertx.vertx(new VertxOptions().setPreferNativeTransport(true)); - try { - client = PgPool.pool(vertx, new PgConnectOptions(options), new PoolOptions()); - Async async = context.async(); - client - .getConnection() - .onComplete(context.asyncAssertSuccess(pgConnection -> { - async.complete(); + client = PgPool.pool(vertx, new PgConnectOptions(options), new PoolOptions()); + client + .getConnection() + .onComplete(context.asyncAssertSuccess(pgConnection -> { pgConnection.close(); })); - async.await(); - } finally { - vertx.close(); - } } + @Ignore @Test public void testIgnoreSslMode(TestContext context) { assumeTrue(options.isUsingDomainSocket()); - client = PgPool.pool(new PgConnectOptions(options).setSslMode(SslMode.REQUIRE), new PoolOptions()); + client = PgPool.pool(vertx, new PgConnectOptions(options).setSslMode(SslMode.REQUIRE), new PoolOptions()); client .getConnection() .onComplete(context.asyncAssertSuccess(pgConnection -> { @@ -121,17 +117,9 @@ public void testIgnoreSslMode(TestContext context) { @Test public void testNativeTransportMustBeEnabled(TestContext ctx) { - Vertx vertx = Vertx.vertx(); - try { - PgPool pool = PgPool.pool(vertx, PgConnectOptions.fromUri("postgresql:///dbname?host=/var/lib/postgresql"), new PoolOptions()); - Async async = ctx.async(); - pool.getConnection().onComplete(ctx.asyncAssertFailure(err -> { - assertEquals(ConnectionFactoryBase.NATIVE_TRANSPORT_REQUIRED, err.getMessage()); - async.complete(); - })); - async.await(20_000); - } finally { - vertx.close(); - } + PgPool pool = PgPool.pool(PgConnectOptions.fromUri("postgresql:///dbname?host=/var/lib/postgresql"), new PoolOptions()); + pool.getConnection().onComplete(ctx.asyncAssertFailure(err -> { + assertEquals(ConnectionFactoryBase.NATIVE_TRANSPORT_REQUIRED, err.getMessage()); + })); } } diff --git a/vertx-pg-client/src/test/resources/tls/another.crt b/vertx-pg-client/src/test/resources/tls/another.crt new file mode 100644 index 000000000..241347df8 --- /dev/null +++ b/vertx-pg-client/src/test/resources/tls/another.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwTCCAamgAwIBAgIEBeVm4jANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZj +bGllbnQwHhcNMTgwNTI2MTEzNjUxWhcNMjEwNTI1MTEzNjUxWjARMQ8wDQYDVQQD +EwZjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVmCecLdUZ +U917hweVz4JqvZ9vZEi1rH+BG98HYfRR/h3QaobxPImZu3hzKHZ+MPbm94HunLPA +VA9yZhvZMToNfOuD4TUPBPloBuNzwBfZk2O4CaXeG4ailVWUfm5t/l+RD/55zYKu +hw1/Vl9lcOryF2XAmPQ2F1gwEKK7wt1Ak8zw8/yeYgBv1/F+ibCMvR6FVj9ABBEf +TM+oOs4oy51otUv0h63GqYgXMJyLX7q+AGWdC3srwwLQROtkzi7y00g/YryXUoIq +dXEI7CrNL35rZXcZ5LfGRwFX9evX11PpT3OShYlsJBcFE9KMatRoIWd6xUKlxTk0 +yLjoOUE2tsMJAgMBAAGjITAfMB0GA1UdDgQWBBQ6xJBQsJCJdj/u0iTLYYD2qQsB +DDANBgkqhkiG9w0BAQsFAAOCAQEAfoquV375+eAGmfnlLxB30v9VhsFckrxFVpYs +XXC6h2G8MtXLpIEpgJo+4SZ4YjNwf/8m9J5j/duU8RukYanyzJdgkFFqKDBYCX7U +SD1nQP7729KnQgxtbR/+i3zkNgo7FATdkLq+HOxklNOEE24Ldenya39bsG779B9n +Sskcbq++7rMM+onDYBv6PbUKCm6nfqPspq809CLxSaUJg9+9ykut6hiyke/i7GEP +XIZHrM+mEvG00ES/zBIdV6TE0AIBP7q2MN7ylT509Ko9sUBMOZdEzikYp5GaRdiv +zG9q6rqK5COK614BwJFOD1DKV1BoDFsgugvfvm/mrc3QfIUPDA== +-----END CERTIFICATE----- diff --git a/vertx-sql-client-templates/src/test/java/io/vertx/sqlclient/templates/TemplateBuilderTest.java b/vertx-sql-client-templates/src/test/java/io/vertx/sqlclient/templates/TemplateBuilderTest.java index 55a144322..890ff0b1f 100644 --- a/vertx-sql-client-templates/src/test/java/io/vertx/sqlclient/templates/TemplateBuilderTest.java +++ b/vertx-sql-client-templates/src/test/java/io/vertx/sqlclient/templates/TemplateBuilderTest.java @@ -1,6 +1,5 @@ package io.vertx.sqlclient.templates; -import io.vertx.core.AsyncResult; import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.Vertx; @@ -23,7 +22,6 @@ import org.junit.Test; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.function.Supplier; diff --git a/vertx-sql-client/src/main/generated/io/vertx/sqlclient/SqlConnectOptionsConverter.java b/vertx-sql-client/src/main/generated/io/vertx/sqlclient/SqlConnectOptionsConverter.java index b8e98e332..4a38b086c 100644 --- a/vertx-sql-client/src/main/generated/io/vertx/sqlclient/SqlConnectOptionsConverter.java +++ b/vertx-sql-client/src/main/generated/io/vertx/sqlclient/SqlConnectOptionsConverter.java @@ -77,6 +77,21 @@ public static void fromJson(Iterable> json, break; case "usingDomainSocket": break; + case "reconnectAttempts": + if (member.getValue() instanceof Number) { + obj.setReconnectAttempts(((Number)member.getValue()).intValue()); + } + break; + case "reconnectInterval": + if (member.getValue() instanceof Number) { + obj.setReconnectInterval(((Number)member.getValue()).longValue()); + } + break; + case "sslOptions": + if (member.getValue() instanceof JsonObject) { + obj.setSslOptions(new io.vertx.core.net.ClientSSLOptions((io.vertx.core.json.JsonObject)member.getValue())); + } + break; } } } @@ -110,5 +125,10 @@ public static void toJson(SqlConnectOptions obj, java.util.Map j json.put("tracingPolicy", obj.getTracingPolicy().name()); } json.put("usingDomainSocket", obj.isUsingDomainSocket()); + json.put("reconnectAttempts", obj.getReconnectAttempts()); + json.put("reconnectInterval", obj.getReconnectInterval()); + if (obj.getSslOptions() != null) { + json.put("sslOptions", obj.getSslOptions().toJson()); + } } } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/SqlConnectOptions.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/SqlConnectOptions.java index 389c56c0d..e30cf54ac 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/SqlConnectOptions.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/SqlConnectOptions.java @@ -13,16 +13,13 @@ import io.vertx.codegen.annotations.DataObject; import io.vertx.codegen.annotations.GenIgnore; -import io.vertx.core.json.Json; import io.vertx.core.json.JsonObject; -import io.vertx.core.net.NetClientOptions; -import io.vertx.core.net.NetClientOptionsConverter; +import io.vertx.core.net.ClientSSLOptions; import io.vertx.core.net.SocketAddress; import io.vertx.core.tracing.TracingPolicy; import io.vertx.sqlclient.spi.Driver; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -35,7 +32,7 @@ * Connect options for configuring {@link SqlConnection} or {@link Pool}. */ @DataObject(generateConverter = true) -public class SqlConnectOptions extends NetClientOptions { +public class SqlConnectOptions { /** * Provide a {@link SqlConnectOptions} subclass configured from {@code connectionUri}. @@ -50,7 +47,7 @@ public class SqlConnectOptions extends NetClientOptions { */ public static SqlConnectOptions fromUri(String connectionUri) throws IllegalArgumentException, ServiceConfigurationError { List candidates = new ArrayList<>(1); - for (Driver d : ServiceLoader.load(Driver.class)) { + for (Driver d : ServiceLoader.load(Driver.class)) { SqlConnectOptions options = d.parseConnectionUri(connectionUri); if (options != null) { candidates.add(options); @@ -65,6 +62,8 @@ public static SqlConnectOptions fromUri(String connectionUri) throws IllegalArgu } } + public static final int DEFAULT_RECONNECT_ATTEMPTS = 0; + public static final long DEFAULT_RECONNECT_INTERVAL = 1000; public static final boolean DEFAULT_CACHE_PREPARED_STATEMENTS = false; public static final int DEFAULT_PREPARED_STATEMENT_CACHE_MAX_SIZE = 256; public static final int DEFAULT_PREPARED_STATEMENT_CACHE_SQL_LIMIT = 2048; @@ -80,20 +79,20 @@ public static SqlConnectOptions fromUri(String connectionUri) throws IllegalArgu private Predicate preparedStatementCacheSqlFilter = DEFAULT_PREPARED_STATEMENT_CACHE_FILTER; private Map properties = new HashMap<>(4); private TracingPolicy tracingPolicy; + private int reconnectAttempts; + private long reconnectInterval; + private ClientSSLOptions sslOptions; public SqlConnectOptions() { - super(); init(); } public SqlConnectOptions(JsonObject json) { - super(json); init(); SqlConnectOptionsConverter.fromJson(json, this); } public SqlConnectOptions(SqlConnectOptions other) { - super(other); this.host = other.host; this.port = other.port; this.user = other.user; @@ -105,6 +104,10 @@ public SqlConnectOptions(SqlConnectOptions other) { if (other.properties != null) { this.properties = new HashMap<>(other.properties); } + this.reconnectAttempts = other.reconnectAttempts; + this.reconnectInterval = other.reconnectInterval; + ClientSSLOptions sslOptions = other.sslOptions; + this.sslOptions = sslOptions != null ? sslOptions.copy() : null; } /** @@ -323,7 +326,6 @@ public SqlConnectOptions addProperty(String key, String value) { return this; } - @GenIgnore public SocketAddress getSocketAddress() { return SocketAddress.inetSocketAddress(getPort(), getHost()); @@ -351,9 +353,59 @@ public boolean isUsingDomainSocket() { return false; } - @Override + /** + * @return the value of reconnect attempts + */ + public int getReconnectAttempts() { + return reconnectAttempts; + } + + /** + * Set the value of reconnect attempts + * + * @param attempts the maximum number of reconnect attempts + * @return a reference to this, so the API can be used fluently + */ + public SqlConnectOptions setReconnectAttempts(int attempts) { + if (attempts < -1) { + throw new IllegalArgumentException("reconnect attempts must be >= -1"); + } + this.reconnectAttempts = attempts; + return this; + } + + /** + * @return the value of reconnect interval + */ + public long getReconnectInterval() { + return reconnectInterval; + } + + /** + * Set the reconnect interval + * + * @param interval the reconnect interval in ms + * @return a reference to this, so the API can be used fluently + */ + public SqlConnectOptions setReconnectInterval(long interval) { + if (interval < 1) { + throw new IllegalArgumentException("reconnect interval must be >= 1"); + } + this.reconnectInterval = interval; + return this; + } + + public ClientSSLOptions getSslOptions() { + return sslOptions; + } + + public SqlConnectOptions setSslOptions(ClientSSLOptions sslOptions) { + this.sslOptions = sslOptions; + return this; + } + public JsonObject toJson() { - JsonObject json = super.toJson(); + JsonObject json = new JsonObject(); SqlConnectOptionsConverter.toJson(this, json); return json; } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/ConnectionFactoryBase.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/ConnectionFactoryBase.java index 00ec34d70..995e7c9a2 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/ConnectionFactoryBase.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/ConnectionFactoryBase.java @@ -10,24 +10,15 @@ */ package io.vertx.sqlclient.impl; -import io.vertx.core.CompositeFuture; import io.vertx.core.Future; import io.vertx.core.Promise; import io.vertx.core.impl.*; import io.vertx.core.impl.future.PromiseInternal; -import io.vertx.core.json.JsonObject; -import io.vertx.core.net.NetClient; import io.vertx.core.net.NetClientOptions; -import io.vertx.core.net.impl.NetClientBuilder; import io.vertx.core.net.impl.NetClientInternal; import io.vertx.sqlclient.SqlConnectOptions; import io.vertx.sqlclient.spi.ConnectionFactory; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - /** * An base connection factory for creating database connections */ @@ -36,48 +27,24 @@ public abstract class ConnectionFactoryBase impleme public static final String NATIVE_TRANSPORT_REQUIRED = "The Vertx instance must use a native transport in order to connect to connect through domain sockets"; protected final VertxInternal vertx; - private final Map clients; + protected final NetClientInternal client; + protected final NetClientOptions tcpOptions; // close hook protected final CloseSequence clientCloseFuture = new CloseSequence(this::doClose); protected ConnectionFactoryBase(VertxInternal vertx) { - this.vertx = vertx; - this.clients = new HashMap<>(); - } - - private void doClose(Promise p) { - List> futures = clients.values().stream().map(client -> client.close()).collect(Collectors.toList()); - - CompositeFuture join = Future.join(futures); - - join.onComplete(ar -> p.complete()); + this(vertx, new NetClientOptions()); } - private NetClient createNetClient(NetClientOptions options) { - options.setReconnectAttempts(0); // auto-retry is handled on the protocol level instead of network level - - NetClientInternal netClient = new NetClientBuilder(vertx, options).build(); - - - // return new NetClientBuilder(vertx, options).closeFuture(clientCloseFuture).build(); - return netClient; + protected ConnectionFactoryBase(VertxInternal vertx, NetClientOptions tcpOptions) { + this.vertx = vertx; + this.client = (NetClientInternal) vertx.createNetClient(new NetClientOptions(tcpOptions).setReconnectAttempts(0)); // auto-retry is handled on the protocol level instead of network level + this.tcpOptions = tcpOptions; } - protected NetClient netClient(NetClientOptions options) { - if (options.getClass() != NetClientOptions.class) { - options = new NetClientOptions(options); - } - JsonObject key = options.toJson(); - NetClient client; - synchronized (this) { - client = clients.get(key); - if (client == null) { - client = createNetClient(options); - clients.put(key, client); - } - } - return client; + private void doClose(Promise p) { + client.close().onComplete(ar -> p.complete()); } public static ContextInternal asEventLoopContext(ContextInternal ctx) { diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/Driver.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/Driver.java index 6f19f333f..f89386e43 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/Driver.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/Driver.java @@ -42,7 +42,7 @@ public interface Driver { *

The returned pool will automatically closed when {@code vertx} is not {@code null} and is closed or when the creating * context is closed (e.g verticle undeployment). * - * @param vertx the Vertx instance to be used with the connection pool or {@code null} to create an auto closed Vertx instance + * @param vertx the Vertx instance to be used with the connection pool or {@code null} to create an auto closed Vertx instance * @param databases the list of databases * @param options the options for creating the pool * @return the connection pool @@ -53,12 +53,7 @@ default Pool createPool(Vertx vertx, Supplier> databases, PoolOptions if (Vertx.currentContext() != null) { throw new IllegalStateException("Running in a Vertx context => use Pool#pool(Vertx, SqlConnectOptions, PoolOptions) instead"); } - VertxOptions vertxOptions = new VertxOptions(); - if (databases instanceof SingletonSupplier) { - SqlConnectOptions connectOptions = ((SingletonSupplier) databases).unwrap(); - vertxOptions.setPreferNativeTransport(connectOptions.isUsingDomainSocket()); - } - vx = (VertxInternal) Vertx.vertx(vertxOptions); + vx = (VertxInternal) Vertx.vertx(new VertxOptions()); } else { vx = (VertxInternal) vertx; } @@ -131,7 +126,7 @@ default Pool newPool(Vertx vertx, List databases, PoolOptions options, CloseF /** * Create a connection factory to the given {@code database}. * - * @param vertx the Vertx instance t + * @param vertx the Vertx instance * @return the connection factory */ ConnectionFactory createConnectionFactory(Vertx vertx);