Skip to content

Add SSL support (rebase + tests) #88

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Dec 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ env:
- secure: jGsaoOfcLzrHgsfIJBLTnhxO6C+4+qRYRMsLG1oJY4DfPZOqa78ShrL50kns15WDt9PkVq4ddPfINJrA5PmN3e0evupPRRDh1mcbvDjK9d4Mldyl5IJxRKL2lvPenC+EujOegVr9jp7Jv6QwI9mc4SJjzwA65uB96K5zvbEmUF0=
before_install:
- cp .travis.maven.settings.xml $HOME/.m2/settings.xml
- sudo /etc/init.d/mysql stop
- sudo /etc/init.d/mysql stop
- sudo /etc/init.d/postgresql stop
- docker run -e POSTGRES_USER=vertx -e POSTGRES_PASSWORD=password -e POSTGRES_DB=testdb -p 5432:5432 -d postgres
- docker run -e POSTGRES_USER=vertx -e POSTGRES_PASSWORD=password -e POSTGRES_DB=testdb -p 54321:5432 -d -v $(pwd)/src/test/resources/ssl-docker/server.crt:/docker-entrypoint-initdb.d/server.crt -v $(pwd)/src/test/resources/ssl-docker/server.key:/docker-entrypoint-initdb.d/server.key -v $(pwd)/src/test/resources/ssl-docker/init.sh:/docker-entrypoint-initdb.d/init.sh postgres
- docker run -e MYSQL_ROOT_PASSWORD=password -e MYSQL_USER=vertx -e MYSQL_PASSWORD=password -e MYSQL_DATABASE=testdb -p 3306:3306 -d mysql/mysql-server:5.6
install: true
script:
Expand Down
11 changes: 11 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ Setting up test databases with Docker:
docker run --rm --name vertx-postgres -e POSTGRES_USER=vertx -e POSTGRES_PASSWORD=password -e POSTGRES_DB=testdb -p 5432:5432 postgres
----

----
docker run --rm --name vertx-postgres-ssl -p 54321:5432 \
-e POSTGRES_USER=vertx \
-e POSTGRES_PASSWORD=password \
-e POSTGRES_DB=testdb \
-v $(pwd)/src/test/resources/ssl-docker/server.crt:/docker-entrypoint-initdb.d/server.crt \
-v $(pwd)/src/test/resources/ssl-docker/server.key:/docker-entrypoint-initdb.d/server.key \
-v $(pwd)/src/test/resources/ssl-docker/init.sh:/docker-entrypoint-initdb.d/init.sh \
postgres
----

----
docker run --rm --name vertx-mysql -e MYSQL_ROOT_PASSWORD=password -e MYSQL_USER=vertx -e MYSQL_PASSWORD=password -e MYSQL_DATABASE=testdb -p 3306:3306 mysql/mysql-server:5.6
----
18 changes: 16 additions & 2 deletions src/main/asciidoc/groovy/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ Both the PostgreSql and MySql clients take the same configuration:
"password" : <your-password>,
"database" : <name-of-your-database>,
"charset" : <name-of-the-character-set>,
"queryTimeout" : <timeout-in-milliseconds>
"queryTimeout" : <timeout-in-milliseconds>,
"sslMode" : <"disable"|"prefer"|"require"|"verify-ca"|"verify-full">,
"sslRootCert" : <path to file with certificate>
}
----

Expand All @@ -239,4 +241,16 @@ Both the PostgreSql and MySql clients take the same configuration:
`password`:: The password to connect to the database. Default is not set, i.e. it uses no password.
`database`:: The name of the database you want to connect to. Defaults to `testdb`.
`charset`:: The name of the character set you want to use for the connection. Defaults to `UTF-8`.
`queryTimeout`:: The timeout to wait for a query in milliseconds. Defaults to `10000` (= 10 seconds).
`queryTimeout`:: The timeout to wait for a query in milliseconds. Defaults to `10000` (= 10 seconds).
`sslMode` :: If you want to enable SSL support you should enable this parameter.
For example to connect Heroku you will need to use *prefer*.

"disable" ::: only try a non-SSL connection
"prefer" ::: first try an SSL connection; if that fails, try a non-SSL connection
"require" ::: only try an SSL connection, but don't verify Certificate Authority
"verify-ca" ::: only try an SSL connection, and verify that the server certificate is issued by a trusted
certificate authority (CA)
"verify-full" ::: only try an SSL connection, verify that the server certificate is issued by a trusted CA and
that the server host name matches that in the certificate
`sslRootCert` :: Path to SSL root certificate file. Is used if you want to verify privately issued certificate.
Refer to https://github.com/mauricio/postgresql-async[postgresql-async] documentation for more details.
18 changes: 16 additions & 2 deletions src/main/asciidoc/java/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,9 @@ Both the PostgreSql and MySql clients take the same configuration:
"password" : <your-password>,
"database" : <name-of-your-database>,
"charset" : <name-of-the-character-set>,
"queryTimeout" : <timeout-in-milliseconds>
"queryTimeout" : <timeout-in-milliseconds>,
"sslMode" : <"disable"|"prefer"|"require"|"verify-ca"|"verify-full">,
"sslRootCert" : <path to file with certificate>
}
----

Expand All @@ -207,4 +209,16 @@ Both the PostgreSql and MySql clients take the same configuration:
`password`:: The password to connect to the database. Default is not set, i.e. it uses no password.
`database`:: The name of the database you want to connect to. Defaults to `testdb`.
`charset`:: The name of the character set you want to use for the connection. Defaults to `UTF-8`.
`queryTimeout`:: The timeout to wait for a query in milliseconds. Defaults to `10000` (= 10 seconds).
`queryTimeout`:: The timeout to wait for a query in milliseconds. Defaults to `10000` (= 10 seconds).
`sslMode` :: If you want to enable SSL support you should enable this parameter.
For example to connect Heroku you will need to use *prefer*.

"disable" ::: only try a non-SSL connection
"prefer" ::: first try an SSL connection; if that fails, try a non-SSL connection
"require" ::: only try an SSL connection, but don't verify Certificate Authority
"verify-ca" ::: only try an SSL connection, and verify that the server certificate is issued by a trusted
certificate authority (CA)
"verify-full" ::: only try an SSL connection, verify that the server certificate is issued by a trusted CA and
that the server host name matches that in the certificate
`sslRootCert` :: Path to SSL root certificate file. Is used if you want to verify privately issued certificate.
Refer to https://github.com/mauricio/postgresql-async[postgresql-async] documentation for more details.
18 changes: 16 additions & 2 deletions src/main/asciidoc/js/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,9 @@ Both the PostgreSql and MySql clients take the same configuration:
"password" : <your-password>,
"database" : <name-of-your-database>,
"charset" : <name-of-the-character-set>,
"queryTimeout" : <timeout-in-milliseconds>
"queryTimeout" : <timeout-in-milliseconds>,
"sslMode" : <"disable"|"prefer"|"require"|"verify-ca"|"verify-full">,
"sslRootCert" : <path to file with certificate>
}
----

Expand All @@ -245,4 +247,16 @@ Both the PostgreSql and MySql clients take the same configuration:
`password`:: The password to connect to the database. Default is not set, i.e. it uses no password.
`database`:: The name of the database you want to connect to. Defaults to `testdb`.
`charset`:: The name of the character set you want to use for the connection. Defaults to `UTF-8`.
`queryTimeout`:: The timeout to wait for a query in milliseconds. Defaults to `10000` (= 10 seconds).
`queryTimeout`:: The timeout to wait for a query in milliseconds. Defaults to `10000` (= 10 seconds).
`sslMode` :: If you want to enable SSL support you should enable this parameter.
For example to connect Heroku you will need to use *prefer*.

"disable" ::: only try a non-SSL connection
"prefer" ::: first try an SSL connection; if that fails, try a non-SSL connection
"require" ::: only try an SSL connection, but don't verify Certificate Authority
"verify-ca" ::: only try an SSL connection, and verify that the server certificate is issued by a trusted
certificate authority (CA)
"verify-full" ::: only try an SSL connection, verify that the server certificate is issued by a trusted CA and
that the server host name matches that in the certificate
`sslRootCert` :: Path to SSL root certificate file. Is used if you want to verify privately issued certificate.
Refer to https://github.com/mauricio/postgresql-async[postgresql-async] documentation for more details.
18 changes: 16 additions & 2 deletions src/main/asciidoc/kotlin/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ Both the PostgreSql and MySql clients take the same configuration:
"password" : <your-password>,
"database" : <name-of-your-database>,
"charset" : <name-of-the-character-set>,
"queryTimeout" : <timeout-in-milliseconds>
"queryTimeout" : <timeout-in-milliseconds>,
"sslMode" : <"disable"|"prefer"|"require"|"verify-ca"|"verify-full">,
"sslRootCert" : <path to file with certificate>
}
----

Expand All @@ -239,4 +241,16 @@ Both the PostgreSql and MySql clients take the same configuration:
`password`:: The password to connect to the database. Default is not set, i.e. it uses no password.
`database`:: The name of the database you want to connect to. Defaults to `testdb`.
`charset`:: The name of the character set you want to use for the connection. Defaults to `UTF-8`.
`queryTimeout`:: The timeout to wait for a query in milliseconds. Defaults to `10000` (= 10 seconds).
`queryTimeout`:: The timeout to wait for a query in milliseconds. Defaults to `10000` (= 10 seconds).
`sslMode` :: If you want to enable SSL support you should enable this parameter.
For example to connect Heroku you will need to use *prefer*.

"disable" ::: only try a non-SSL connection
"prefer" ::: first try an SSL connection; if that fails, try a non-SSL connection
"require" ::: only try an SSL connection, but don't verify Certificate Authority
"verify-ca" ::: only try an SSL connection, and verify that the server certificate is issued by a trusted
certificate authority (CA)
"verify-full" ::: only try an SSL connection, verify that the server certificate is issued by a trusted CA and
that the server host name matches that in the certificate
`sslRootCert` :: Path to SSL root certificate file. Is used if you want to verify privately issued certificate.
Refer to https://github.com/mauricio/postgresql-async[postgresql-async] documentation for more details.
18 changes: 16 additions & 2 deletions src/main/asciidoc/ruby/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,9 @@ Both the PostgreSql and MySql clients take the same configuration:
"password" : <your-password>,
"database" : <name-of-your-database>,
"charset" : <name-of-the-character-set>,
"queryTimeout" : <timeout-in-milliseconds>
"queryTimeout" : <timeout-in-milliseconds>,
"sslMode" : <"disable"|"prefer"|"require"|"verify-ca"|"verify-full">,
"sslRootCert" : <path to file with certificate>
}
----

Expand All @@ -245,4 +247,16 @@ Both the PostgreSql and MySql clients take the same configuration:
`password`:: The password to connect to the database. Default is not set, i.e. it uses no password.
`database`:: The name of the database you want to connect to. Defaults to `testdb`.
`charset`:: The name of the character set you want to use for the connection. Defaults to `UTF-8`.
`queryTimeout`:: The timeout to wait for a query in milliseconds. Defaults to `10000` (= 10 seconds).
`queryTimeout`:: The timeout to wait for a query in milliseconds. Defaults to `10000` (= 10 seconds).
`sslMode` :: If you want to enable SSL support you should enable this parameter.
For example to connect Heroku you will need to use *prefer*.

"disable" ::: only try a non-SSL connection
"prefer" ::: first try an SSL connection; if that fails, try a non-SSL connection
"require" ::: only try an SSL connection, but don't verify Certificate Authority
"verify-ca" ::: only try an SSL connection, and verify that the server certificate is issued by a trusted
certificate authority (CA)
"verify-full" ::: only try an SSL connection, verify that the server certificate is issued by a trusted CA and
that the server host name matches that in the certificate
`sslRootCert` :: Path to SSL root certificate file. Is used if you want to verify privately issued certificate.
Refer to https://github.com/mauricio/postgresql-async[postgresql-async] documentation for more details.
16 changes: 15 additions & 1 deletion src/main/java/io/vertx/ext/asyncsql/impl/BaseSQLClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
import io.vertx.ext.asyncsql.impl.pool.AsyncConnectionPool;
import io.vertx.ext.sql.SQLConnection;
import scala.Option;
import scala.Tuple2;
import scala.collection.Map$;
import scala.collection.immutable.Map;
import scala.concurrent.ExecutionContext;
import scala.concurrent.duration.Duration;

Expand Down Expand Up @@ -117,14 +119,16 @@ protected Configuration getConfiguration(
Option<Duration> queryTimeoutOption = (queryTimeout == null) ?
Option.empty() : Option.apply(Duration.apply(queryTimeout, TimeUnit.MILLISECONDS));

Map<String, String> sslConfig = buildSslConfig(config);

log.info("Creating configuration for " + host + ":" + port);
return new Configuration(
username,
host,
port,
Option.apply(password),
Option.apply(database),
SSLConfiguration.apply(Map$.MODULE$.empty()),
SSLConfiguration.apply(sslConfig),
charset,
16777216,
PooledByteBufAllocator.DEFAULT,
Expand All @@ -133,5 +137,15 @@ protected Configuration getConfiguration(
queryTimeoutOption);
}

private Map<String, String> buildSslConfig(JsonObject config) {
Map<String, String> sslConfig = Map$.MODULE$.empty();
if (config.getString("sslMode")!= null) {
sslConfig = sslConfig.$plus(Tuple2.apply("sslmode", config.getString("sslMode")));
}
if (config.getString("sslRootCert") != null) {
sslConfig = sslConfig.$plus(Tuple2.apply("sslrootcert", config.getString("sslRootCert")));
}
return sslConfig;
}

}
16 changes: 15 additions & 1 deletion src/main/java/io/vertx/ext/asyncsql/package-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,9 @@
* "password" : <your-password>,
* "database" : <name-of-your-database>,
* "charset" : <name-of-the-character-set>,
* "queryTimeout" : <timeout-in-milliseconds>
* "queryTimeout" : <timeout-in-milliseconds>,
* "sslMode" : <"disable"|"prefer"|"require"|"verify-ca"|"verify-full">,
* "sslRootCert" : <path to file with certificate>
* }
* ----
*
Expand All @@ -197,6 +199,18 @@
* `database`:: The name of the database you want to connect to. Defaults to `testdb`.
* `charset`:: The name of the character set you want to use for the connection. Defaults to `UTF-8`.
* `queryTimeout`:: The timeout to wait for a query in milliseconds. Defaults to `10000` (= 10 seconds).
* `sslMode` :: If you want to enable SSL support you should enable this parameter.
* For example to connect Heroku you will need to use *prefer*.
*
* "disable" ::: only try a non-SSL connection
* "prefer" ::: first try an SSL connection; if that fails, try a non-SSL connection
* "require" ::: only try an SSL connection, but don't verify Certificate Authority
* "verify-ca" ::: only try an SSL connection, and verify that the server certificate is issued by a trusted
* certificate authority (CA)
* "verify-full" ::: only try an SSL connection, verify that the server certificate is issued by a trusted CA and
* that the server host name matches that in the certificate
* `sslRootCert` :: Path to SSL root certificate file. Is used if you want to verify privately issued certificate.
* Refer to https://github.com/mauricio/postgresql-async[postgresql-async] documentation for more details.
*/
@Document(fileName = "index.adoc")
@ModuleGen(name = "vertx-mysql-postgresql", groupPackage = "io.vertx") package io.vertx.ext.asyncsql;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package io.vertx.ext.asyncsql;

import io.vertx.core.Vertx;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.sql.SQLClient;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import org.junit.Test;

import java.util.List;

/**
* Tests the configuration options of the PostgreSQL client.
*/
public class PostgreSQLSslConfigurationTest extends ConfigurationTest {

@Override
protected SQLClient createClient(Vertx vertx, JsonObject config) {
return PostgreSQLClient.createNonShared(vertx, config);
}

@Override
public String sleepCommand(int seconds) {
return "pg_sleep(" + seconds + ")";
}

@Override
protected String getEncodingStatement() {
return "SHOW client_encoding";
}

@Override
protected String getEncodingValueFromResults(List<JsonArray> results) {
return results.get(0).getString(0);
}

@Test
public void testCorrectSslConfiguration(TestContext context) {
Async async = context.async();
String path = getClass()
.getResource("/ssl-docker/server.crt")
.getPath();

System.out.println("Path = " + path);

JsonObject sslConfig = new JsonObject()
.put("port", Integer.parseInt(System.getProperty("dbssl.port", "54321")))
.put("sslMode", "require")
.put("sslRootCert", path);

client = createClient(vertx, sslConfig);

System.out.println("testCorrectSslConfiguration");
client.getConnection(sqlConnectionAsyncResult -> {
context.assertTrue(sqlConnectionAsyncResult.succeeded());
conn = sqlConnectionAsyncResult.result();
System.out.println("testCorrectSslConfiguration step2");
conn.query("SELECT 1", ar -> {
System.out.println("testCorrectSslConfiguration callback2");
if (ar.failed()) {
context.fail("Should not fail on ssl connection");
} else {
System.out.println("testCorrectSslConfiguration all good!");
async.complete();
}
});
});
}

@Test
public void testWrongSslConfiguration(TestContext context) {
Async async = context.async();
client = createClient(vertx,
new JsonObject()
.put("host", System.getProperty("db.host", "localhost"))
.put("port", Integer.parseInt(System.getProperty("dbssl.port", "54321")))
.put("sslMode", "verify-ca")
.put("sslRootCert", "something-wrong.crt")
);

System.out.println("testWrongSslConfiguration");
client.getConnection(sqlConnectionAsyncResult -> {
System.out.println("testWrongSslConfiguration callback");
context.assertTrue(sqlConnectionAsyncResult.failed());
System.out.println("testWrongSslConfiguration success!");
async.complete();
});
}

@Test
public void testNoSslConfiguration(TestContext context) {
Async async = context.async();
client = createClient(vertx,
new JsonObject()
.put("host", System.getProperty("db.host", "localhost"))
.put("port", Integer.parseInt(System.getProperty("dbssl.port", "54321")))
);

System.out.println("testNoSslConfiguration");
client.getConnection(sqlConnectionAsyncResult -> {
System.out.println("testNoSslConfiguration callback");
context.assertTrue(sqlConnectionAsyncResult.failed());
System.out.println("testNoSslConfiguration success!");
async.complete();
});
}

}
4 changes: 3 additions & 1 deletion src/test/resources/docker/start-db.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
sleep 5
./start-postgres.sh
sleep 5
# Since the migration to docker-machine, the startup takes much more time.
./start-postgres-ssl.sh
sleep 5
# Since the migration to docker-machine, the startup takes much more time.
17 changes: 17 additions & 0 deletions src/test/resources/docker/start-postgres-ssl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

export POSTGRES_DB=testdb
export POSTGRES_USER=vertx
export POSTGRES_PASSWORD=password

docker run -d \
-e POSTGRES_USER \
-e POSTGRES_PASSWORD \
-e POSTGRES_DB \
--name "some-postgres-ssl" \
-v $(pwd)/src/test/resources/ssl-docker/server.crt:/docker-entrypoint-initdb.d/server.crt \
-v $(pwd)/src/test/resources/ssl-docker/server.key:/docker-entrypoint-initdb.d/server.key \
-v $(pwd)/src/test/resources/ssl-docker/init.sh:/docker-entrypoint-initdb.d/init.sh \
-p 54321:5432 \
"postgres:9.4.4"

Loading