Skip to content

[WIP] driver metadata #1432

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,34 @@ public class ConnectionPluginChainBuilder {
}
};

protected static final Map<String /* clazz */, String> pluginCodeByPlugin =
new HashMap<String, String>() {
{
put("software.amazon.jdbc.plugin.ExecutionTimeConnectionPlugin", "executionTime");
put("software.amazon.jdbc.plugin.LogQueryConnectionPlugin", "logQuery");
put("software.amazon.jdbc.plugin.DataCacheConnectionPlugin", "dataCache");
put("software.amazon.jdbc.plugin.customendpoint.CustomEndpointPlugin", "customEndpoint");
put("software.amazon.jdbc.plugin.efm.HostMonitoringConnectionPlugin", "efm");
put("software.amazon.jdbc.plugin.efm2.HostMonitoringConnectionPlugin", "efm2");
put("software.amazon.jdbc.plugin.failover.FailoverConnectionPlugin", "failover");
put("software.amazon.jdbc.plugin.failover2.FailoverConnectionPlugin", "failover2");
put("software.amazon.jdbc.plugin.iam.IamAuthConnectionPlugin", "iam");
put("software.amazon.jdbc.plugin.AwsSecretsManagerConnectionPlugin", "awsSecretsManager");
put("software.amazon.jdbc.plugin.federatedauth.FederatedAuthPlugin", "federatedAuth");
put("software.amazon.jdbc.plugin.federatedauth.OktaAuthPlugin", "okta");
put("software.amazon.jdbc.plugin.staledns.AuroraStaleDnsPlugin", "auroraStaleDns");
put("software.amazon.jdbc.plugin.readwritesplitting.ReadWriteSplittingPlugin", "readWriteSplitting");
put("software.amazon.jdbc.plugin.AuroraConnectionTrackerPlugin", "auroraConnectionTracker");
put("software.amazon.jdbc.plugin.DriverMetaDataConnectionPlugin", "driverMetaData");
put("software.amazon.jdbc.plugin.ConnectTimeConnectionPlugin", "connectTime");
put("software.amazon.jdbc.plugin.dev.DeveloperConnectionPlugin", "dev");
put("software.amazon.jdbc.plugin.strategy.fastestresponse.FastestResponseStrategyPlugin",
"fastestResponseStrategy");
put("software.amazon.jdbc.plugin.AuroraInitialConnectionStrategyPlugin", "initialConnection");
put("software.amazon.jdbc.plugin.limitless.LimitlessConnectionPlugin", "limitless");
}
};

/**
* The final list of plugins will be sorted by weight, starting from the lowest values up to
* the highest values. The first plugin of the list will have the lowest weight, and the
Expand Down Expand Up @@ -189,7 +217,7 @@ public List<ConnectionPlugin> getPlugins(
}
} else {

final List<String> pluginCodeList = getPluginCodes(props);
final List<String> pluginCodeList = this.getPluginCodes(props);
pluginFactories = new ArrayList<>(pluginCodeList.size());

for (final String pluginCode : pluginCodeList) {
Expand Down Expand Up @@ -242,14 +270,23 @@ public List<ConnectionPlugin> getPlugins(
return plugins;
}

public static List<String> getPluginCodes(final Properties props) {
public List<String> getPluginCodes(final Properties props) {
String pluginCodes = PropertyDefinition.PLUGINS.getString(props);
if (pluginCodes == null) {
pluginCodes = DEFAULT_PLUGINS;
}
return StringUtils.split(pluginCodes, ",", true);
}

public String getPluginCodes(final List<ConnectionPlugin> plugins) {
return plugins.stream()
.filter(x -> !(x instanceof DefaultConnectionPlugin))
.map(x -> pluginCodeByPlugin.getOrDefault(x.getClass().getName(), "unknown"))
.distinct()
.sorted()
.collect(Collectors.joining("+"));
}

protected List<ConnectionPluginFactory> sortPluginFactories(
final List<ConnectionPluginFactory> unsortedPluginFactories) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public class ConnectionPluginManager implements CanReleaseResources, Wrapper {

private static final Logger LOGGER = Logger.getLogger(ConnectionPluginManager.class.getName());

public static final String EFFECTIVE_PLUGIN_CODES_PROPERTY = "46762024-847c-41c8-aa46-0c65e8560c89";

protected static final Map<Class<? extends ConnectionPlugin>, String> pluginNameByClass =
new HashMap<Class<? extends ConnectionPlugin>, String>() {
{
Expand Down Expand Up @@ -97,6 +99,7 @@ public class ConnectionPluginManager implements CanReleaseResources, Wrapper {

protected Properties props = new Properties();
protected List<ConnectionPlugin> plugins;
protected String effectivePluginCodes;
protected final @NonNull ConnectionProvider defaultConnProvider;
protected final @Nullable ConnectionProvider effectiveConnProvider;
protected final ConnectionWrapper connectionWrapper;
Expand Down Expand Up @@ -197,6 +200,8 @@ public void init(
pluginManagerService,
props,
configurationProfile);
this.effectivePluginCodes = pluginChainBuilder.getPluginCodes(this.plugins);
this.props.setProperty(EFFECTIVE_PLUGIN_CODES_PROPERTY, this.effectivePluginCodes);
}

protected <T, E extends Exception> T executeWithSubscribedPlugins(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,8 @@ public void updateDialect(final @NonNull Connection connection) throws SQLExcept
this.dialect = this.dialectProvider.getDialect(
this.originalUrl,
this.initialConnectionHostSpec,
connection);
connection,
this.props);
if (originalDialect == this.dialect) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ public static void removeAllExceptCredentials(final Properties props) {
final String password = props.getProperty(PropertyDefinition.PASSWORD.name, null);

removeAll(props);
props.remove(ConnectionPluginManager.EFFECTIVE_PLUGIN_CODES_PROPERTY);

if (user != null) {
props.setProperty(PropertyDefinition.USER.name, user);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Collections;
import java.util.List;
import software.amazon.jdbc.PluginService;
import java.util.Properties;
import software.amazon.jdbc.hostlistprovider.AuroraHostListProvider;
import software.amazon.jdbc.hostlistprovider.monitoring.MonitoringRdsHostListProvider;
import software.amazon.jdbc.plugin.failover2.FailoverConnectionPlugin;
Expand Down Expand Up @@ -51,33 +52,22 @@ public class AuroraMysqlDialect extends MysqlDialect implements BlueGreenDialect
+ " table_schema = 'mysql' AND table_name = 'rds_topology'";

@Override
public boolean isDialect(final Connection connection) {
Statement stmt = null;
ResultSet rs = null;
public boolean isDialect(final Connection connection, final Properties properties) {
if (super.isDialect(connection, properties)) {
// If super.isDialect() returns true then there is no need to check other conditions.
return false;
}

try {
stmt = connection.createStatement();
rs = stmt.executeQuery("SHOW VARIABLES LIKE 'aurora_version'");
if (rs.next()) {
// If variable with such name is presented then it means it's an Aurora cluster
return true;
}
} catch (final SQLException ex) {
// ignore
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException ex) {
// ignore
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException ex) {
// ignore
try (Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SHOW VARIABLES LIKE 'aurora_version'")) {
if (rs.next()) {
// If variable with such name is presented then it means it's an Aurora cluster
return true;
}
}
} catch (SQLException ex) {
// do nothing
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.util.logging.Logger;
import org.checkerframework.checker.nullness.qual.NonNull;
import software.amazon.jdbc.ConnectionPluginManager;
import software.amazon.jdbc.HostSpec;
import software.amazon.jdbc.PluginService;
import software.amazon.jdbc.hostlistprovider.AuroraHostListProvider;
import software.amazon.jdbc.hostlistprovider.monitoring.MonitoringRdsHostListProvider;
Expand Down Expand Up @@ -65,72 +69,36 @@ public class AuroraPgDialect extends PgDialect implements AuroraLimitlessDialect
"SELECT 'get_blue_green_fast_switchover_metadata'::regproc";

@Override
public boolean isDialect(final Connection connection) {
if (!super.isDialect(connection)) {
public boolean isDialect(final Connection connection, final Properties properties) {
if (!super.isDialect(connection, properties)) {
return false;
}

Statement stmt = null;
ResultSet rs = null;
boolean hasExtensions = false;
boolean hasTopology = false;
try {
stmt = connection.createStatement();
rs = stmt.executeQuery(extensionsSql);
if (rs.next()) {
try (Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(extensionsSql)) {
if (!rs.next()) {
return false;
}
final boolean auroraUtils = rs.getBoolean("aurora_stat_utils");
LOGGER.finest(() -> String.format("auroraUtils: %b", auroraUtils));
if (auroraUtils) {
hasExtensions = true;
}
}
} catch (SQLException ex) {
// ignore
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException ex) {
// ignore
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException ex) {
// ignore
}
}
}
if (!hasExtensions) {
return false;
}
try {
stmt = connection.createStatement();
rs = stmt.executeQuery(topologySql);
if (rs.next()) {
LOGGER.finest(() -> "hasTopology: true");
hasTopology = true;
}
} catch (final SQLException ex) {
// ignore
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException ex) {
// ignore
if (!auroraUtils) {
return false;
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException ex) {
// ignore

try (Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(topologySql)) {
if (rs.next()) {
LOGGER.finest(() -> "hasTopology: true");
return true;
}
LOGGER.finest(() -> "hasTopology: false");
}
} catch (SQLException ex) {
// do nothing
}
return hasExtensions && hasTopology;
return false;
}

@Override
Expand Down Expand Up @@ -178,4 +146,21 @@ public boolean isBlueGreenStatusAvailable(final Connection connection) {
return false;
}
}

@Override
public void prepareConnectProperties(
final @NonNull Properties connectProperties,
final @NonNull String protocol,
final @NonNull HostSpec hostSpec) {

final String driverInfoOption = String.format(
"-c aurora.connection_str=_jdbc_wrapper_name:aws_jdbc_driver,_jdbc_wrapper_version:%s,_jdbc_wrapper_plugins:%s",
DriverInfo.DRIVER_VERSION,
connectProperties.getProperty(ConnectionPluginManager.EFFECTIVE_PLUGIN_CODES_PROPERTY));
connectProperties.setProperty("options",
connectProperties.getProperty("options") == null
? driverInfoOption
: connectProperties.getProperty("options") + " " + driverInfoOption);
connectProperties.remove(ConnectionPluginManager.EFFECTIVE_PLUGIN_CODES_PROPERTY);
}
}
11 changes: 8 additions & 3 deletions wrapper/src/main/java/software/amazon/jdbc/dialect/Dialect.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,21 @@ public interface Dialect {

String getHostAliasQuery();

String getServerVersionQuery();
// The query should return two column:
// - parameter name
// - parameter value with a database version
String getServerVersionQuery(final Properties properties);

boolean isDialect(Connection connection);
boolean isDialect(final Connection connection, final Properties properties);

List</* dialect code */ String> getDialectUpdateCandidates();

HostListProviderSupplier getHostListProvider();

void prepareConnectProperties(
final @NonNull Properties connectProperties, final @NonNull String protocol, final @NonNull HostSpec hostSpec);
final @NonNull Properties connectProperties,
final @NonNull String protocol,
final @NonNull HostSpec hostSpec);

EnumSet<FailoverRestriction> getFailoverRestrictions();
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ public Dialect getDialect(
public Dialect getDialect(
final @NonNull String originalUrl,
final @NonNull HostSpec hostSpec,
final @NonNull Connection connection) throws SQLException {
final @NonNull Connection connection,
final @NonNull Properties properties) throws SQLException {

if (!this.canUpdate) {
this.logCurrentDialect();
Expand All @@ -249,7 +250,7 @@ public Dialect getDialect(
throw new SQLException(
Messages.get("DialectManager.unknownDialectCode", new Object[] {dialectCandidateCode}));
}
boolean isDialect = dialectCandidate.isDialect(connection);
boolean isDialect = dialectCandidate.isDialect(connection, properties);
if (isDialect) {
this.canUpdate = false;
this.dialectCode = dialectCandidateCode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ Dialect getDialect(
Dialect getDialect(
final @NonNull String originalUrl,
final @NonNull HostSpec hostSpec,
final @NonNull Connection connection) throws SQLException;
final @NonNull Connection connection,
final @NonNull Properties properties) throws SQLException;
}
Loading
Loading