Adding logic to flex the MySQL r2dbc connection sting based on classpath (#73)

* Adding logic to flex the MySQL jdbc and r2dbc connection sting based on classpath

This PR is related to issue #72.

Co-authored-by: gm2552 <meyerg@vmware.com>
This commit is contained in:
Greg Meyer
2022-06-13 10:40:59 -05:00
committed by GitHub
parent 5ab708ff04
commit c9fdc1e6b1
4 changed files with 47 additions and 6 deletions

View File

@@ -168,12 +168,14 @@ Disable Property: `org.springframework.cloud.bindings.boot.mysql.enable`
| -------- | ------------------
| `spring.datasource.driver-class-name` | `org.mariadb.jdbc.Driver` or `com.mysql.cj.jdbc.Driver` depending on classpath
| `spring.datasource.password` | `{password}`
| `spring.datasource.url` | `{jdbc-url}` or if not set then `jdbc:mysql://{host}:{port}/{database}`
| `spring.datasource.url` | `{jdbc-url}` or if not set then `jdbc:mysql://{host}:{port}/{database}` or `jdbc:mariadb://{host}:{port}/{database}` depending on classpath
| `spring.datasource.username` | `{username}`
| `spring.r2dbc.url` | `{r2dbc-url}` or if not set then `r2dbc:mysql://{host}:{port}/{database}`
| `spring.r2dbc.url` | `{r2dbc-url}` or if not set then `r2dbc:mysql://{host}:{port}/{database}` or `r2dbc:mariadb//{host}:{port}/{database}` depending on classpath
| `spring.r2dbc.password` | `{password}`
| `spring.r2dbc.username` | `{username}`
**Note:** Libraries on the classpath are examined for the purpose of evaluating the appropriate `jdbc` and `r2dbc` URLs. The existence of both MySQL and MariaDB libraries on the classpath is not supported and may lead to non-deterministic results.
### Neo4J
Type: `neo4j`
Disable Property: `org.springframework.cloud.bindings.boot.neo4j.enable`

View File

@@ -26,6 +26,7 @@
<properties>
<java.version>1.8</java.version>
<jsr305.version>3.0.2</jsr305.version>
<mariadb-r2dbc.version>1.0.3</mariadb-r2dbc.version>
<spring-boot.version>2.3.3.RELEASE</spring-boot.version>
<!-- Plugins -->
@@ -69,6 +70,12 @@
<artifactId>mariadb-java-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mariadb</groupId>
<artifactId>r2dbc-mariadb</artifactId>
<version>${mariadb-r2dbc.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>

View File

@@ -36,6 +36,16 @@ public final class MySqlBindingsPropertiesProcessor implements BindingsPropertie
**/
public static final String TYPE = "mysql";
/**
* MySQL connection protocol constant.
*/
private static final String MYSQL_PROTOCOL = "mysql";
/**
* MariaDB connection protocol constant.
*/
private static final String MARIADB_PROTOCOL = "mariadb";
@Override
public void process(Environment environment, Bindings bindings, Map<String, Object> properties) {
if (!isTypeEnabled(environment, TYPE)) {
@@ -49,7 +59,7 @@ public final class MySqlBindingsPropertiesProcessor implements BindingsPropertie
map.from("username").to("spring.datasource.username");
map.from("password").to("spring.datasource.password");
map.from("host", "port", "database").to("spring.datasource.url",
(host, port, database) -> String.format("jdbc:mysql://%s:%s/%s", host, port, database));
(host, port, database) -> String.format("jdbc:%s://%s:%s/%s", evalProtocol(), host, port, database));
// jdbcURL takes precedence
map.from("jdbc-url").to("spring.datasource.url");
@@ -68,12 +78,34 @@ public final class MySqlBindingsPropertiesProcessor implements BindingsPropertie
//r2dbc properties
map.from("password").to("spring.r2dbc.password");
map.from("host", "port", "database").to("spring.r2dbc.url",
(host, port, database) -> String.format("r2dbc:mysql://%s:%s/%s", host, port, database));
(host, port, database) -> String.format("r2dbc:%s://%s:%s/%s", evalProtocol(), host, port, database));
map.from("username").to("spring.r2dbc.username");
// r2dbcURL takes precedence
map.from("r2dbc-url").to("spring.r2dbc.url");
});
}
private String evalProtocol()
{
// Default to "mysql"
String connectionProtocol = MYSQL_PROTOCOL;
/* Starting with Spring Boot 2.7.0, the previous MySQL r2dbc driver is no longer supported and
* documentation suggests using the MariaDB R2DBC driver as an alternative. Some versions
* of the MariaDB R2DBC driver do not support "mysql" as part of the connection
* protocol; "mariadb" should be used instead when the MariaDB R2DBC driver class is on
* the classpath.
*/
try {
Class.forName("org.mariadb.r2dbc.MariadbConnection");
connectionProtocol = MARIADB_PROTOCOL;
}
catch (ClassNotFoundException ignored) {
}
return connectionProtocol;
}
}

View File

@@ -54,7 +54,7 @@ final class MySqlBindingsPropertiesProcessorTest {
assertThat(properties)
.containsEntry("spring.datasource.driver-class-name", "org.mariadb.jdbc.Driver")
.containsEntry("spring.datasource.password", "test-password")
.containsEntry("spring.datasource.url", "jdbc:mysql://test-host:test-port/test-database")
.containsEntry("spring.datasource.url", "jdbc:mariadb://test-host:test-port/test-database")
.containsEntry("spring.datasource.username", "test-username");
}
@@ -81,7 +81,7 @@ final class MySqlBindingsPropertiesProcessorTest {
new MySqlBindingsPropertiesProcessor().process(environment, bindings, properties);
assertThat(properties)
.containsEntry("spring.r2dbc.password", "test-password")
.containsEntry("spring.r2dbc.url", "r2dbc:mysql://test-host:test-port/test-database")
.containsEntry("spring.r2dbc.url", "r2dbc:mariadb://test-host:test-port/test-database")
.containsEntry("spring.r2dbc.username", "test-username");
}