Skip to content

Commit 7f97ca2

Browse files
fix lost database name in properties during writer failover
rework AwsWrapperDataSource
1 parent 811a454 commit 7f97ca2

37 files changed

+354
-485
lines changed

config/checkstyle/checkstyle-suppressions.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@
2727
<suppress files="[\\/]MysqlConnectorJDataSourceHelper\.java" checks="IllegalImport"/>
2828
<suppress files="[\\/]PgDataSourceHelper\.java" checks="IllegalImport"/>
2929
<suppress files="[\\/]test[\\/]" checks="IllegalImport"/>
30+
<suppress files="[\\/]ExtendedFormatter\.java" checks="Header"/>
3031
</suppressions>

docs/using-the-jdbc-driver/DataSource.md

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,16 @@ you need to specify what property names the underlying datasource uses.
1616
For example, one datasource implementation could use the method `setUser` to set the datasource username,
1717
while another might use the method `setUsername` for the same task. See the table below for a list of configurable property names.
1818

19-
> **:warning: Note:** If the same connection property is provided both explicitly in the connection URL and in the datasource properties, the value set in the connection URL will take precedence.
20-
21-
| Property | Configuration Method | Description | Type | Required | Example |
22-
|-----------------------------|--------------------------------|---------------------------------------------------------------------------------------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------|
23-
| Server name | `setServerPropertyName` | The name of the server or host property. | `String` | Yes, if no URL is provided. | `serverName` |
24-
| Database name | `setDatabasePropertyName` | The name of the database property. | `String` | No | `databaseName` |
25-
| Port name | `setPortPropertyName` | The name of the port property. | `String` | No | `port` |
26-
| URL name | `setUrlPropertyName` | The name of the URL property. | `String` | No, but some drivers, such as MariaDb, require some parameters to be included in the URL so it is recommended to provide this parameter. | `url` |
27-
| JDBC URL | `setJdbcUrl` | The URL to connect with. | `String` | No, if there is enough information provided by the other properties that can be used to create a URL. | `jdbc:postgresql://localhost/postgres` |
28-
| JDBC protocol | `setJdbcProtocol` | The JDBC protocol that will be used. | `String` | Yes, if the JDBC URL has not been set. | `jdbc:postgresql:` |
29-
| Underlying DataSource class | `setTargetDataSourceClassName` | The fully qualified class name of the underlying DataSource class the AWS JDBC Driver should use. | `String` | Yes, if the JDBC URL has not been set. | `org.postgresql.ds.PGSimpleDataSource` |
19+
> **:warning: Note:** If the same connection property is provided both explicitly in the connection URL and in the datasource properties, the value set in the datasource properties will take precedence.
20+
21+
| Property | Configuration Method | Description | Type | Required | Example |
22+
|-----------------------------|--------------------------------|---------------------------------------------------------------------------------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------|
23+
| Server name | `setServerName` | The name of the server. | `String` | Yes, if no URL is provided. | `db-server.mydomain.com` |
24+
| Server port | `setServerPort` | The server port. | `String` | No | `5432` |
25+
| Database name | `setDatabase` | The name of the database. | `String` | No | `testDatabase` |
26+
| JDBC URL | `setJdbcUrl` | The URL to connect with. | `String` | No. Either URL or server name should be set. If both URL and server name have been set, URL will take precedence. Please note that some drivers, such as MariaDb, require some parameters to be included particularly in the URL. | `jdbc:postgresql://localhost/postgres` |
27+
| JDBC protocol | `setJdbcProtocol` | The JDBC protocol that will be used. | `String` | Yes, if the JDBC URL has not been set. | `jdbc:postgresql:` |
28+
| Underlying DataSource class | `setTargetDataSourceClassName` | The fully qualified class name of the underlying DataSource class the AWS JDBC Driver should use. | `String` | Yes, if the JDBC URL has not been set. | `org.postgresql.ds.PGSimpleDataSource` |
3029

3130
## Using the AwsWrapperDataSource with Connection Pooling Frameworks
3231

@@ -63,21 +62,20 @@ To use the AWS JDBC Driver with a connection pool, you must:
6362
```java
6463
// Note: jdbcProtocol is required when connecting via server name
6564
ds.addDataSourceProperty("jdbcProtocol", "jdbc:postgresql:");
66-
ds.addDataSourceProperty("serverPropertyName", "serverName");
67-
68-
ds.addDataSourceProperty("databasePropertyName", "databaseName");
69-
ds.addDataSourceProperty("portPropertyName", "port");
65+
ds.addDataSourceProperty("serverName", "db-identifier.cluster-XYZ.us-east-2.rds.amazonaws.com");
66+
ds.addDataSourceProperty("serverPort", "5432");
67+
ds.addDataSourceProperty("database", "postgres");
7068
```
7169

72-
4. Configure the driver-specific datasource:
70+
4. Set the driver-specific datasource:
7371
```java
7472
ds.addDataSourceProperty("targetDataSourceClassName", "org.postgresql.ds.PGSimpleDataSource");
75-
73+
```
74+
75+
5. Configure the driver-specific datasource, if needed. This step is optional:
76+
```java
7677
Properties targetDataSourceProps = new Properties();
77-
targetDataSourceProps.setProperty("serverName", "db-identifier.cluster-XYZ.us-east-2.rds.amazonaws.com");
78-
targetDataSourceProps.setProperty("databaseName", "postgres");
79-
targetDataSourceProps.setProperty("port", "5432");
80-
78+
targetDataSourceProps.setProperty("socketTimeout", "10");
8179
ds.addDataSourceProperty("targetDataSourceProperties", targetDataSourceProps);
8280
```
8381

examples/AWSDriverExample/src/main/java/software/amazon/DatasourceExample.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,15 @@ public static void main(String[] args) throws SQLException {
3232

3333
// Configure the property names for the underlying driver-specific data source:
3434
ds.setJdbcProtocol("jdbc:postgresql:");
35-
ds.setDatabasePropertyName("databaseName");
36-
ds.setServerPropertyName("serverName");
37-
ds.setPortPropertyName("port");
3835

3936
// Specify the driver-specific data source:
4037
ds.setTargetDataSourceClassName("org.postgresql.ds.PGSimpleDataSource");
4138

4239
// Configure the driver-specific data source:
4340
Properties targetDataSourceProps = new Properties();
4441
targetDataSourceProps.setProperty("serverName", "db-identifier.cluster-XYZ.us-east-2.rds.amazonaws.com");
45-
targetDataSourceProps.setProperty("databaseName", "employees");
46-
targetDataSourceProps.setProperty("port", "5432");
42+
targetDataSourceProps.setProperty("database", "employees");
43+
targetDataSourceProps.setProperty("serverPort", "5432");
4744
ds.setTargetDataSourceProperties(targetDataSourceProps);
4845

4946
// Try and make a connection:

examples/AWSDriverExample/src/main/java/software/amazon/ReadWriteSplittingSpringJdbcTemplateExample.java

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,15 @@ private static void scenario3() throws SQLException {
7979
private static DataSource getSimplePostgresDataSource() {
8080
AwsWrapperDataSource ds = new AwsWrapperDataSource();
8181
ds.setJdbcProtocol("jdbc:postgresql:");
82-
ds.setDatabasePropertyName("databaseName");
83-
ds.setServerPropertyName("serverName");
84-
ds.setPortPropertyName("port");
82+
ds.setServerName(DATABASE_URL);
83+
ds.setDatabase(DATABASE_NAME);
84+
ds.setServerPort("5432");
8585

8686
ds.setTargetDataSourceClassName("org.postgresql.ds.PGSimpleDataSource");
8787

8888
Properties targetDataSourceProps = new Properties();
8989
targetDataSourceProps.setProperty(
9090
PropertyDefinition.PLUGINS.name, "readWriteSplitting,failover,efm");
91-
targetDataSourceProps.setProperty("serverName", DATABASE_URL);
92-
targetDataSourceProps.setProperty("databaseName", DATABASE_NAME);
93-
targetDataSourceProps.setProperty("port", "5432");
9491

9592
ds.setUser(USERNAME);
9693
ds.setPassword(PASSWORD);
@@ -112,19 +109,15 @@ private static DataSource getHikariCPDataSource() {
112109

113110
ds.setDataSourceClassName(AwsWrapperDataSource.class.getName());
114111
ds.addDataSourceProperty("jdbcProtocol", "jdbc:postgresql:");
115-
ds.addDataSourceProperty("serverPropertyName", "serverName");
116-
117-
ds.addDataSourceProperty("databasePropertyName", "databaseName");
118-
ds.addDataSourceProperty("portPropertyName", "port");
112+
ds.addDataSourceProperty("serverName", DATABASE_URL);
113+
ds.addDataSourceProperty("serverPort", "5432");
114+
ds.addDataSourceProperty("database", DATABASE_NAME);
119115

120116
ds.addDataSourceProperty("targetDataSourceClassName", "org.postgresql.ds.PGSimpleDataSource");
121117

122118
Properties targetDataSourceProps = new Properties();
123119
targetDataSourceProps.setProperty(PropertyDefinition.PLUGINS.name,
124120
"readWriteSplitting,failover,efm");
125-
targetDataSourceProps.setProperty("serverName", DATABASE_URL);
126-
targetDataSourceProps.setProperty("databaseName", DATABASE_NAME);
127-
targetDataSourceProps.setProperty("port", "5432");
128121

129122
ds.addDataSourceProperty("targetDataSourceProperties", targetDataSourceProps);
130123

examples/HikariExample/src/main/java/software/amazon/HikariExample.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,17 @@ public static void main(String[] args) throws SQLException {
4343

4444
// Configure AwsWrapperDataSource:
4545
ds.addDataSourceProperty("jdbcProtocol", "jdbc:postgresql:");
46-
ds.addDataSourceProperty("databasePropertyName", "databaseName");
47-
ds.addDataSourceProperty("portPropertyName", "portNumber");
48-
ds.addDataSourceProperty("serverPropertyName", "serverName");
46+
ds.addDataSourceProperty("database", DATABASE_NAME);
47+
ds.addDataSourceProperty("serverPort", "5432");
48+
ds.addDataSourceProperty("serverName", ENDPOINT);
4949

5050
// Specify the driver-specific data source for AwsWrapperDataSource:
5151
ds.addDataSourceProperty("targetDataSourceClassName", "org.postgresql.ds.PGSimpleDataSource");
5252

53-
// Configuring PGSimpleDataSource:
54-
Properties targetDataSourceProps = new Properties();
55-
targetDataSourceProps.setProperty("serverName", ENDPOINT);
56-
targetDataSourceProps.setProperty("databaseName", DATABASE_NAME);
57-
targetDataSourceProps.setProperty("portNumber", "5432");
58-
59-
ds.addDataSourceProperty("targetDataSourceProperties", targetDataSourceProps);
53+
// Configuring PGSimpleDataSource (optional):
54+
// Properties targetDataSourceProps = new Properties();
55+
// targetDataSourceProps.setProperty("socketTimeout", "10");
56+
// ds.addDataSourceProperty("targetDataSourceProperties", targetDataSourceProps);
6057

6158
// Attempt a connection:
6259
try (final Connection conn = ds.getConnection();

examples/HikariExample/src/main/java/software/amazon/HikariFailoverExample.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ public static void main(String[] args) throws SQLException {
4646

4747
// Configure AwsWrapperDataSource:
4848
ds.addDataSourceProperty("jdbcProtocol", "jdbc:postgresql:");
49-
ds.addDataSourceProperty("databasePropertyName", "databaseName");
50-
ds.addDataSourceProperty("portPropertyName", "portNumber");
51-
ds.addDataSourceProperty("serverPropertyName", "serverName");
49+
ds.addDataSourceProperty("serverName", ENDPOINT);
50+
ds.addDataSourceProperty("portNumber", "5432");
51+
ds.addDataSourceProperty("database", DATABASE_NAME);
5252

5353
// The failover plugin throws failover-related exceptions that need to be handled explicitly by HikariCP,
5454
// otherwise connections will be closed immediately after failover. Set `ExceptionOverrideClassName` to provide
@@ -58,11 +58,10 @@ public static void main(String[] args) throws SQLException {
5858
// Specify the driver-specific data source for AwsWrapperDataSource:
5959
ds.addDataSourceProperty("targetDataSourceClassName", "org.postgresql.ds.PGSimpleDataSource");
6060

61-
// Configuring PGSimpleDataSource:
6261
Properties targetDataSourceProps = new Properties();
63-
targetDataSourceProps.setProperty("serverName", ENDPOINT);
64-
targetDataSourceProps.setProperty("databaseName", DATABASE_NAME);
65-
targetDataSourceProps.setProperty("portNumber", "5432");
62+
63+
// Configuring PGSimpleDataSource if needed:
64+
// targetDataSourceProps.setProperty("ssl", "true");
6665

6766
// Enable the failover and host monitoring connection plugins.
6867
targetDataSourceProps.setProperty("wrapperPlugins", "failover,efm");

wrapper/src/main/java/software/amazon/jdbc/DataSourceConnectionProvider.java

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
package software.amazon.jdbc;
1818

19-
import static software.amazon.jdbc.util.StringUtils.isNullOrEmpty;
20-
2119
import java.sql.Connection;
2220
import java.sql.SQLException;
2321
import java.util.Collections;
@@ -29,7 +27,6 @@
2927
import java.util.logging.Logger;
3028
import javax.sql.DataSource;
3129
import org.checkerframework.checker.nullness.qual.NonNull;
32-
import org.checkerframework.checker.nullness.qual.Nullable;
3330
import software.amazon.jdbc.dialect.Dialect;
3431
import software.amazon.jdbc.exceptions.SQLLoginException;
3532
import software.amazon.jdbc.targetdriverdialect.TargetDriverDialect;
@@ -53,28 +50,16 @@ public class DataSourceConnectionProvider implements ConnectionProvider {
5350
}
5451
});
5552
private final @NonNull DataSource dataSource;
56-
private final @Nullable String serverPropertyName;
57-
private final @Nullable String portPropertyName;
58-
private final @Nullable String urlPropertyName;
59-
private final @Nullable String databasePropertyName;
6053
private final @NonNull TargetDriverDialect targetDriverDialect;
6154

6255

6356
private final ReentrantLock lock = new ReentrantLock();
6457

6558
public DataSourceConnectionProvider(
6659
final @NonNull DataSource dataSource,
67-
final @NonNull TargetDriverDialect targetDriverDialect,
68-
final @Nullable String serverPropertyName,
69-
final @Nullable String portPropertyName,
70-
final @Nullable String urlPropertyName,
71-
final @Nullable String databasePropertyName) {
60+
final @NonNull TargetDriverDialect targetDriverDialect) {
7261
this.dataSource = dataSource;
7362
this.targetDriverDialect = targetDriverDialect;
74-
this.serverPropertyName = serverPropertyName;
75-
this.portPropertyName = portPropertyName;
76-
this.urlPropertyName = urlPropertyName;
77-
this.databasePropertyName = databasePropertyName;
7863
}
7964

8065
/**
@@ -143,11 +128,7 @@ public Connection connect(
143128
ds,
144129
protocol,
145130
hostSpec,
146-
copy,
147-
this.serverPropertyName,
148-
this.portPropertyName,
149-
this.urlPropertyName,
150-
this.databasePropertyName);
131+
copy);
151132
conn = ds.getConnection();
152133

153134
} else {
@@ -161,11 +142,7 @@ public Connection connect(
161142
this.dataSource,
162143
protocol,
163144
hostSpec,
164-
copy,
165-
this.serverPropertyName,
166-
this.portPropertyName,
167-
this.urlPropertyName,
168-
this.databasePropertyName);
145+
copy);
169146
conn = this.dataSource.getConnection();
170147
} finally {
171148
this.lock.unlock();
@@ -191,16 +168,7 @@ public Connection connect(
191168
@Deprecated
192169
public Connection connect(final @NonNull String url, final @NonNull Properties props) throws SQLException {
193170
final Properties copy = PropertyUtils.copyProperties(props);
194-
195-
if (!isNullOrEmpty(this.urlPropertyName)) {
196-
copy.setProperty(this.urlPropertyName, url);
197-
}
198-
199-
if (!isNullOrEmpty(this.databasePropertyName)
200-
&& !isNullOrEmpty(PropertyDefinition.DATABASE.getString(props))) {
201-
copy.put(this.databasePropertyName, PropertyDefinition.DATABASE.getString(props));
202-
}
203-
171+
copy.setProperty("url", url);
204172
PropertyDefinition.removeAllExceptCredentials(copy);
205173
PropertyUtils.applyProperties(this.dataSource, copy);
206174
return this.dataSource.getConnection();

wrapper/src/main/java/software/amazon/jdbc/DriverConnectionProvider.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,9 @@ public Connection connect(
110110
final @NonNull Properties props)
111111
throws SQLException {
112112

113+
final Properties copy = PropertyUtils.copyProperties(props);
113114
final ConnectInfo connectInfo =
114-
this.targetDriverDialect.prepareConnectInfo(protocol, hostSpec, props);
115+
this.targetDriverDialect.prepareConnectInfo(protocol, hostSpec, copy);
115116

116117
LOGGER.finest(() -> "Connecting to " + connectInfo.url
117118
+ PropertyUtils.logProperties(connectInfo.props, "\nwith properties: \n"));

0 commit comments

Comments
 (0)