Skip to content
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

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@

package com.amazon.awslabs.jdbc;

import static com.amazon.awslabs.jdbc.ConnectionPropertyNames.DATABASE_PROPERTY_NAME;
import static com.amazon.awslabs.jdbc.ConnectionPropertyNames.PASSWORD_PROPERTY_NAME;
import static com.amazon.awslabs.jdbc.ConnectionPropertyNames.USER_PROPERTY_NAME;
import static com.amazon.awslabs.jdbc.util.ConnectionUrlBuilder.buildUrl;
import static com.amazon.awslabs.jdbc.util.StringUtils.isNullOrEmpty;

Expand Down Expand Up @@ -90,16 +87,17 @@ public Connection connect(
copy.put(this.portPropertyName, hostSpec.getPort());
}

if (!isNullOrEmpty(this.databasePropertyName) && !isNullOrEmpty(props.getProperty(DATABASE_PROPERTY_NAME))) {
copy.setProperty(this.databasePropertyName, props.getProperty(DATABASE_PROPERTY_NAME));
if (!isNullOrEmpty(this.databasePropertyName)
&& !isNullOrEmpty(PropertyDefinition.DATABASE_NAME.getString(props))) {
copy.setProperty(this.databasePropertyName, PropertyDefinition.DATABASE_NAME.getString(props));
}

if (!isNullOrEmpty(this.userPropertyName) && !isNullOrEmpty(props.getProperty(USER_PROPERTY_NAME))) {
copy.setProperty(this.userPropertyName, props.getProperty(USER_PROPERTY_NAME));
if (!isNullOrEmpty(this.userPropertyName) && !isNullOrEmpty(PropertyDefinition.USER.getString(props))) {
copy.setProperty(this.userPropertyName, PropertyDefinition.USER.getString(props));
}

if (!isNullOrEmpty(this.passwordPropertyName) && !isNullOrEmpty(props.getProperty(PASSWORD_PROPERTY_NAME))) {
copy.setProperty(this.passwordPropertyName, props.getProperty(PASSWORD_PROPERTY_NAME));
if (!isNullOrEmpty(this.passwordPropertyName) && !isNullOrEmpty(PropertyDefinition.PASSWORD.getString(props))) {
copy.setProperty(this.passwordPropertyName, PropertyDefinition.PASSWORD.getString(props));
}

if (!isNullOrEmpty(this.urlPropertyName) && !isNullOrEmpty(props.getProperty(this.urlPropertyName))) {
Expand All @@ -120,6 +118,10 @@ public Connection connect(
urlProperties));
}

copy.remove(PropertyDefinition.DATABASE_NAME.name);
copy.remove(PropertyDefinition.USER.name);
copy.remove(PropertyDefinition.PASSWORD.name);

PropertyUtils.applyProperties(this.dataSource, copy);
return this.dataSource.getConnection();
}
Expand All @@ -139,18 +141,23 @@ public Connection connect(final @NonNull String url, final @NonNull Properties p
copy.setProperty(this.urlPropertyName, url);
}

if (!isNullOrEmpty(this.userPropertyName) && !isNullOrEmpty(props.getProperty(USER_PROPERTY_NAME))) {
copy.put(this.userPropertyName, props.getProperty(USER_PROPERTY_NAME));
if (!isNullOrEmpty(this.userPropertyName) && !isNullOrEmpty(PropertyDefinition.USER.getString(props))) {
copy.put(this.userPropertyName, PropertyDefinition.USER.getString(props));
}

if (!isNullOrEmpty(this.passwordPropertyName) && !isNullOrEmpty(props.getProperty(PASSWORD_PROPERTY_NAME))) {
copy.put(this.passwordPropertyName, props.getProperty(PASSWORD_PROPERTY_NAME));
if (!isNullOrEmpty(this.passwordPropertyName) && !isNullOrEmpty(PropertyDefinition.PASSWORD.getString(props))) {
copy.put(this.passwordPropertyName, PropertyDefinition.PASSWORD.getString(props));
}

if (!isNullOrEmpty(this.databasePropertyName) && !isNullOrEmpty(props.getProperty(DATABASE_PROPERTY_NAME))) {
copy.put(this.databasePropertyName, props.getProperty(DATABASE_PROPERTY_NAME));
if (!isNullOrEmpty(this.databasePropertyName)
&& !isNullOrEmpty(PropertyDefinition.DATABASE_NAME.getString(props))) {
copy.put(this.databasePropertyName, PropertyDefinition.DATABASE_NAME.getString(props));
}

copy.remove(PropertyDefinition.DATABASE_NAME.name);
copy.remove(PropertyDefinition.USER.name);
copy.remove(PropertyDefinition.PASSWORD.name);

PropertyUtils.applyProperties(this.dataSource, copy);
return this.dataSource.getConnection();
}
Expand Down
6 changes: 2 additions & 4 deletions wrapper/src/main/java/com/amazon/awslabs/jdbc/Driver.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

package com.amazon.awslabs.jdbc;

import static com.amazon.awslabs.jdbc.ConnectionPropertyNames.DATABASE_PROPERTY_NAME;

import com.amazon.awslabs.jdbc.util.DriverInfo;
import com.amazon.awslabs.jdbc.util.StringUtils;
import com.amazon.awslabs.jdbc.wrapper.ConnectionWrapper;
Expand All @@ -34,7 +32,7 @@

public class Driver implements java.sql.Driver {

private static final String PROTOCOL_PREFIX = "aws-proxy-jdbc:";
private static final String PROTOCOL_PREFIX = "aws-jdbc-wrapper:";
private static final Logger PARENT_LOGGER = Logger.getLogger("com.amazon.awslabs.jdbc");
private static final Logger LOGGER = Logger.getLogger("com.amazon.awslabs.jdbc.Driver");
private static @Nullable Driver registeredDriver;
Expand Down Expand Up @@ -131,7 +129,7 @@ public boolean acceptsURL(String url) throws SQLException {
if (dPos != -1) {
String database = urlServer.substring(dPos + 1);
if (!database.isEmpty()) {
propertiesFromUrl.setProperty(DATABASE_PROPERTY_NAME, database);
PropertyDefinition.DATABASE_NAME.set(propertiesFromUrl, database);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@

package com.amazon.awslabs.jdbc;

import static com.amazon.awslabs.jdbc.ConnectionPropertyNames.DATABASE_PROPERTY_NAME;
import static com.amazon.awslabs.jdbc.ConnectionPropertyNames.PASSWORD_PROPERTY_NAME;
import static com.amazon.awslabs.jdbc.ConnectionPropertyNames.USER_PROPERTY_NAME;
import static com.amazon.awslabs.jdbc.util.StringUtils.isNullOrEmpty;

import com.amazon.awslabs.jdbc.util.PropertyUtils;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
Expand Down Expand Up @@ -62,20 +60,27 @@ public Connection connect(
final @NonNull Properties props)
throws SQLException {

final String databaseName =
props.getProperty(DATABASE_PROPERTY_NAME) != null ? props.getProperty(DATABASE_PROPERTY_NAME) : "";
Properties copy = PropertyUtils.copyProperties(props);

final String databaseName = PropertyDefinition.DATABASE_NAME.getString(props) != null
? PropertyDefinition.DATABASE_NAME.getString(props)
: "";
final StringBuilder urlBuilder = new StringBuilder();
urlBuilder.append(protocol).append(hostSpec.getUrl()).append(databaseName);

if (!isNullOrEmpty(this.userPropertyName) && !isNullOrEmpty(props.getProperty(USER_PROPERTY_NAME))) {
props.setProperty(this.userPropertyName, props.getProperty(USER_PROPERTY_NAME));
if (!isNullOrEmpty(this.userPropertyName) && !isNullOrEmpty(PropertyDefinition.USER.getString(props))) {
copy.setProperty(this.userPropertyName, PropertyDefinition.USER.getString(props));
}

if (!isNullOrEmpty(this.passwordPropertyName) && !isNullOrEmpty(props.getProperty(PASSWORD_PROPERTY_NAME))) {
props.setProperty(this.passwordPropertyName, props.getProperty(PASSWORD_PROPERTY_NAME));
if (!isNullOrEmpty(this.passwordPropertyName) && !isNullOrEmpty(PropertyDefinition.PASSWORD.getString(props))) {
copy.setProperty(this.passwordPropertyName, PropertyDefinition.PASSWORD.getString(props));
}

return this.driver.connect(urlBuilder.toString(), props);
copy.remove(PropertyDefinition.DATABASE_NAME.name);
copy.remove(PropertyDefinition.USER.name);
copy.remove(PropertyDefinition.PASSWORD.name);

return this.driver.connect(urlBuilder.toString(), copy);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,14 @@

public class PropertyDefinition {

public static final ProxyDriverProperty CLUSTER_INSTANCE_HOST_PATTERN =
new ProxyDriverProperty(
"clusterInstanceHostPattern",
null,
"The cluster instance DNS pattern that will be used to build a complete instance endpoint. "
+ "A \"?\" character in this pattern should be used as a placeholder for cluster instance names. "
+ "This pattern is required to be specified for IP address or custom domain connections to AWS RDS "
+ "clusters. Otherwise, if unspecified, the pattern will be automatically created for AWS RDS clusters.");

public static final ProxyDriverProperty ENABLE_CLUSTER_AWARE_FAILOVER =
new ProxyDriverProperty(
"enableClusterAwareFailover", "true",
"Enable/disable cluster-aware failover logic");

public static final ProxyDriverProperty LOG_UNCLOSED_CONNECTIONS =
new ProxyDriverProperty(
"proxyDriverLogUnclosedConnections", "false",
"wrapperLogUnclosedConnections", "false",
"Allows the driver to track a point in the code where connection has been opened and never closed after");

public static final ProxyDriverProperty LOGGER_LEVEL =
new ProxyDriverProperty(
"proxyDriverLoggerLevel",
"wrapperLoggerLevel",
null,
"Logger level of the driver",
false,
Expand All @@ -57,21 +43,23 @@ public class PropertyDefinition {

public static final ProxyDriverProperty PLUGINS =
new ProxyDriverProperty(
"proxyDriverPlugins", null, "Comma separated list of connection plugin codes");
"wrapperPlugins", null, "Comma separated list of connection plugin codes");

public static final ProxyDriverProperty PROFILE_NAME =
new ProxyDriverProperty(
"proxyDriverProfileName", null, "Driver configuration profile name");
"wrapperProfileName", null, "Driver configuration profile name");

public static final ProxyDriverProperty USER =
new ProxyDriverProperty(
"wrapperUser", null, "Driver user name");

public static final ProxyDriverProperty USE_AWS_IAM =
public static final ProxyDriverProperty PASSWORD =
new ProxyDriverProperty(
"useAwsIam", "false", "Set to true to use AWS IAM database authentication");
"wrapperPassword", null, "Driver password");

public static final ProxyDriverProperty CLUSTER_ID = new ProxyDriverProperty(
"clusterId", "",
"A unique identifier for the cluster. "
+ "Connections with the same cluster id share a cluster topology cache. "
+ "If unspecified, a cluster id is automatically created for AWS RDS clusters.");
public static final ProxyDriverProperty DATABASE_NAME =
new ProxyDriverProperty(
"wrapperDatabaseName", null, "Driver database name");

private static final Map<String, ProxyDriverProperty> PROPS_BY_NAME =
new HashMap<String, ProxyDriverProperty>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@

package com.amazon.awslabs.jdbc.ds;

import static com.amazon.awslabs.jdbc.ConnectionPropertyNames.DATABASE_PROPERTY_NAME;
import static com.amazon.awslabs.jdbc.ConnectionPropertyNames.PASSWORD_PROPERTY_NAME;
import static com.amazon.awslabs.jdbc.ConnectionPropertyNames.USER_PROPERTY_NAME;
import static com.amazon.awslabs.jdbc.util.ConnectionUrlBuilder.buildUrl;
import static com.amazon.awslabs.jdbc.util.ConnectionUrlParser.parsePropertiesFromUrl;

import com.amazon.awslabs.jdbc.DataSourceConnectionProvider;
import com.amazon.awslabs.jdbc.Driver;
import com.amazon.awslabs.jdbc.DriverConnectionProvider;
import com.amazon.awslabs.jdbc.PropertyDefinition;
import com.amazon.awslabs.jdbc.util.ConnectionUrlParser;
import com.amazon.awslabs.jdbc.util.PropertyUtils;
import com.amazon.awslabs.jdbc.util.SqlState;
Expand Down Expand Up @@ -89,11 +87,12 @@ public Connection getConnection(String username, String password) throws SQLExce

Properties props = PropertyUtils.copyProperties(this.targetDataSourceProperties);
setCredentialProperties(props);

if (!isNullOrEmpty(this.targetDataSourceClassName)) {
final DataSource targetDataSource = createTargetDataSource();

if (!isNullOrEmpty(this.databasePropertyName) && !isNullOrEmpty(props.getProperty(this.databasePropertyName))) {
props.put(DATABASE_PROPERTY_NAME, props.getProperty(this.databasePropertyName));
PropertyDefinition.DATABASE_NAME.set(props, props.getProperty(this.databasePropertyName));
}

// If the url is set explicitly through setJdbcUrl or the connection properties.
Expand Down Expand Up @@ -143,8 +142,9 @@ public Connection getConnection(String username, String password) throws SQLExce
throw new SQLException("Can't find a suitable driver for " + this.jdbcUrl);
}

setDatabasePropertyFromUrl(props);
parsePropertiesFromUrl(this.jdbcUrl, props);
setCredentialProperties(props);
setDatabasePropertyFromUrl(props);

return new ConnectionWrapper(
props,
Expand Down Expand Up @@ -299,21 +299,21 @@ protected boolean isNullOrEmpty(final String str) {

private void setCredentialProperties(Properties props) {
// If username was provided as a get connection parameter and a userPropertyName is set.
if (!isNullOrEmpty(this.user) && !isNullOrEmpty(this.userPropertyName)) {
props.setProperty(USER_PROPERTY_NAME, this.user);
if (!isNullOrEmpty(this.user)) {
PropertyDefinition.USER.set(props, this.user);

// If username was provided in targetDataSourceProperties and a userPropertyName is set.
} else if (!isNullOrEmpty(this.userPropertyName) && !isNullOrEmpty(props.getProperty(this.userPropertyName))) {
props.setProperty(USER_PROPERTY_NAME, props.getProperty(this.userPropertyName));
PropertyDefinition.USER.set(props, props.getProperty(this.userPropertyName));
this.user = props.getProperty(this.userPropertyName);
}

if (!isNullOrEmpty(this.password) && !isNullOrEmpty(this.passwordPropertyName)) {
props.setProperty(PASSWORD_PROPERTY_NAME, this.password);
if (!isNullOrEmpty(this.password)) {
PropertyDefinition.PASSWORD.set(props, this.password);

} else if (!isNullOrEmpty(this.passwordPropertyName)
&& !isNullOrEmpty(props.getProperty(this.passwordPropertyName))) {
props.setProperty(PASSWORD_PROPERTY_NAME, props.getProperty(this.passwordPropertyName));
PropertyDefinition.PASSWORD.set(props, props.getProperty(this.passwordPropertyName));
this.password = props.getProperty(this.passwordPropertyName);
}
}
Expand All @@ -329,20 +329,20 @@ private DataSource createTargetDataSource() throws SQLException {
private void setDatabasePropertyFromUrl(Properties props) {
final String databaseName = ConnectionUrlParser.parseDatabaseFromUrl(this.jdbcUrl);
if (!isNullOrEmpty(databaseName)) {
props.setProperty(DATABASE_PROPERTY_NAME, databaseName);
PropertyDefinition.DATABASE_NAME.set(props, databaseName);
}
}

private void setCredentialPropertiesFromUrl(Properties props) {
final String userFromUrl = ConnectionUrlParser.parseUserFromUrl(this.jdbcUrl, this.userPropertyName);
if (isNullOrEmpty(this.user) && !isNullOrEmpty(userFromUrl)) {
props.setProperty(USER_PROPERTY_NAME, userFromUrl);
PropertyDefinition.USER.set(props, userFromUrl);
this.user = userFromUrl;
}

final String passwordFromUrl = ConnectionUrlParser.parsePasswordFromUrl(this.jdbcUrl, this.passwordPropertyName);
if (isNullOrEmpty(this.password) && !isNullOrEmpty(passwordFromUrl)) {
props.setProperty(PASSWORD_PROPERTY_NAME, passwordFromUrl);
PropertyDefinition.PASSWORD.set(props, passwordFromUrl);
this.password = passwordFromUrl;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,22 @@ public class AuroraHostListProvider implements HostListProvider, DynamicHostList
"Cluster topology refresh rate in millis. "
+ "The cached topology for the cluster will be invalidated after the specified time, "
+ "after which it will be updated during the next interaction with the connection.");

public static final ProxyDriverProperty CLUSTER_ID = new ProxyDriverProperty(
"clusterId", "",
"A unique identifier for the cluster. "
+ "Connections with the same cluster id share a cluster topology cache. "
+ "If unspecified, a cluster id is automatically created for AWS RDS clusters.");

public static final ProxyDriverProperty CLUSTER_INSTANCE_HOST_PATTERN =
new ProxyDriverProperty(
"clusterInstanceHostPattern",
null,
"The cluster instance DNS pattern that will be used to build a complete instance endpoint. "
+ "A \"?\" character in this pattern should be used as a placeholder for cluster instance names. "
+ "This pattern is required to be specified for IP address or custom domain connections to AWS RDS "
+ "clusters. Otherwise, if unspecified, the pattern will be automatically created for AWS RDS clusters.");

static final String PG_RETRIEVE_TOPOLOGY_SQL =
"SELECT SERVER_ID, SESSION_ID FROM aurora_replica_status() "
// filter out nodes that haven't been updated in the last 5 minutes
Expand Down Expand Up @@ -109,14 +125,14 @@ public AuroraHostListProvider(
this.originalUrl = originalUrl;
this.clusterId = UUID.randomUUID().toString();
this.refreshRateInMilliseconds = CLUSTER_TOPOLOGY_REFRESH_RATE_MS.getInteger(properties);
this.clusterInstanceTemplate = PropertyDefinition.CLUSTER_INSTANCE_HOST_PATTERN.get(this.properties) == null
this.clusterInstanceTemplate = CLUSTER_INSTANCE_HOST_PATTERN.get(this.properties) == null
? new HostSpec(rdsHelper.getRdsInstanceHostPattern(originalUrl))
: new HostSpec(PropertyDefinition.CLUSTER_INSTANCE_HOST_PATTERN.getString(this.properties));
: new HostSpec(CLUSTER_INSTANCE_HOST_PATTERN.getString(this.properties));
validateHostPatternSetting(this.clusterInstanceTemplate.getHost());

this.rdsUrlType = rdsHelper.identifyRdsType(originalUrl);

final String clusterIdSetting = PropertyDefinition.CLUSTER_ID.get(this.properties);
final String clusterIdSetting = CLUSTER_ID.get(this.properties);
if (!StringUtils.isNullOrEmpty(clusterIdSetting)) {
this.clusterId = clusterIdSetting;
} else if (rdsUrlType == RdsUrlType.RDS_PROXY) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class DataCacheConnectionPlugin extends AbstractConnectionPlugin {
"PreparedStatement.execute", "PreparedStatement.executeQuery",
"CallableStatement.execute", "CallableStatement.executeQuery")));

protected static final ProxyDriverProperty DATA_CACHE_TRIGGER_CONDITION = new ProxyDriverProperty(
public static final ProxyDriverProperty DATA_CACHE_TRIGGER_CONDITION = new ProxyDriverProperty(
"dataCacheTriggerCondition", "false",
"A regular expression that, if it's matched, allows the plugin to cache SQL results.");

Expand Down
Loading