Skip to content

Commit c7a91f2

Browse files
committed
use query comment to provide driver metadata
1 parent a1d8080 commit c7a91f2

20 files changed

+294
-357
lines changed

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

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,44 @@
2626
import java.util.logging.Logger;
2727
import java.util.stream.Collectors;
2828
import org.checkerframework.checker.nullness.qual.Nullable;
29+
import software.amazon.jdbc.plugin.AuroraConnectionTrackerPlugin;
2930
import software.amazon.jdbc.plugin.AuroraConnectionTrackerPluginFactory;
31+
import software.amazon.jdbc.plugin.AuroraInitialConnectionStrategyPlugin;
3032
import software.amazon.jdbc.plugin.AuroraInitialConnectionStrategyPluginFactory;
33+
import software.amazon.jdbc.plugin.AwsSecretsManagerConnectionPlugin;
3134
import software.amazon.jdbc.plugin.AwsSecretsManagerConnectionPluginFactory;
35+
import software.amazon.jdbc.plugin.ConnectTimeConnectionPlugin;
3236
import software.amazon.jdbc.plugin.ConnectTimeConnectionPluginFactory;
37+
import software.amazon.jdbc.plugin.DataCacheConnectionPlugin;
3338
import software.amazon.jdbc.plugin.DataCacheConnectionPluginFactory;
3439
import software.amazon.jdbc.plugin.DefaultConnectionPlugin;
40+
import software.amazon.jdbc.plugin.DriverMetaDataConnectionPlugin;
3541
import software.amazon.jdbc.plugin.DriverMetaDataConnectionPluginFactory;
42+
import software.amazon.jdbc.plugin.ExecutionTimeConnectionPlugin;
3643
import software.amazon.jdbc.plugin.ExecutionTimeConnectionPluginFactory;
44+
import software.amazon.jdbc.plugin.LogQueryConnectionPlugin;
3745
import software.amazon.jdbc.plugin.LogQueryConnectionPluginFactory;
46+
import software.amazon.jdbc.plugin.customendpoint.CustomEndpointPlugin;
3847
import software.amazon.jdbc.plugin.customendpoint.CustomEndpointPluginFactory;
48+
import software.amazon.jdbc.plugin.dev.DeveloperConnectionPlugin;
3949
import software.amazon.jdbc.plugin.dev.DeveloperConnectionPluginFactory;
50+
import software.amazon.jdbc.plugin.efm.HostMonitoringConnectionPlugin;
4051
import software.amazon.jdbc.plugin.efm.HostMonitoringConnectionPluginFactory;
52+
import software.amazon.jdbc.plugin.failover.FailoverConnectionPlugin;
4153
import software.amazon.jdbc.plugin.failover.FailoverConnectionPluginFactory;
54+
import software.amazon.jdbc.plugin.federatedauth.FederatedAuthPlugin;
4255
import software.amazon.jdbc.plugin.federatedauth.FederatedAuthPluginFactory;
56+
import software.amazon.jdbc.plugin.federatedauth.OktaAuthPlugin;
4357
import software.amazon.jdbc.plugin.federatedauth.OktaAuthPluginFactory;
58+
import software.amazon.jdbc.plugin.iam.IamAuthConnectionPlugin;
4459
import software.amazon.jdbc.plugin.iam.IamAuthConnectionPluginFactory;
60+
import software.amazon.jdbc.plugin.limitless.LimitlessConnectionPlugin;
4561
import software.amazon.jdbc.plugin.limitless.LimitlessConnectionPluginFactory;
62+
import software.amazon.jdbc.plugin.readwritesplitting.ReadWriteSplittingPlugin;
4663
import software.amazon.jdbc.plugin.readwritesplitting.ReadWriteSplittingPluginFactory;
64+
import software.amazon.jdbc.plugin.staledns.AuroraStaleDnsPlugin;
4765
import software.amazon.jdbc.plugin.staledns.AuroraStaleDnsPluginFactory;
66+
import software.amazon.jdbc.plugin.strategy.fastestresponse.FastestResponseStrategyPlugin;
4867
import software.amazon.jdbc.plugin.strategy.fastestresponse.FastestResponseStrategyPluginFactory;
4968
import software.amazon.jdbc.profile.ConfigurationProfile;
5069
import software.amazon.jdbc.util.Messages;
@@ -85,6 +104,33 @@ public class ConnectionPluginChainBuilder {
85104
}
86105
};
87106

107+
protected static final Map<Class<? extends ConnectionPlugin>, String> pluginCodeByPlugin =
108+
new HashMap<Class<? extends ConnectionPlugin>, String>() {
109+
{
110+
put(ExecutionTimeConnectionPlugin.class, "executionTime");
111+
put(LogQueryConnectionPlugin.class, "logQuery");
112+
put(DataCacheConnectionPlugin.class, "dataCache");
113+
put(CustomEndpointPlugin.class, "customEndpoint");
114+
put(HostMonitoringConnectionPlugin.class, "efm");
115+
put(software.amazon.jdbc.plugin.efm2.HostMonitoringConnectionPlugin.class, "efm2");
116+
put(FailoverConnectionPlugin.class, "failover");
117+
put(software.amazon.jdbc.plugin.failover2.FailoverConnectionPlugin.class, "failover2");
118+
put(IamAuthConnectionPlugin.class, "iam");
119+
put(AwsSecretsManagerConnectionPlugin.class, "awsSecretsManager");
120+
put(FederatedAuthPlugin.class, "federatedAuth");
121+
put(OktaAuthPlugin.class, "okta");
122+
put(AuroraStaleDnsPlugin.class, "auroraStaleDns");
123+
put(ReadWriteSplittingPlugin.class, "readWriteSplitting");
124+
put(AuroraConnectionTrackerPlugin.class, "auroraConnectionTracker");
125+
put(DriverMetaDataConnectionPlugin.class, "driverMetaData");
126+
put(ConnectTimeConnectionPlugin.class, "connectTime");
127+
put(DeveloperConnectionPlugin.class, "dev");
128+
put(FastestResponseStrategyPlugin.class, "fastestResponseStrategy");
129+
put(AuroraInitialConnectionStrategyPlugin.class, "initialConnection");
130+
put(LimitlessConnectionPlugin.class, "limitless");
131+
}
132+
};
133+
88134
/**
89135
* The final list of plugins will be sorted by weight, starting from the lowest values up to
90136
* the highest values. The first plugin of the list will have the lowest weight, and the
@@ -148,7 +194,7 @@ public List<ConnectionPlugin> getPlugins(
148194
pluginFactories = configurationProfile.getPluginFactories();
149195
} else {
150196

151-
final List<String> pluginCodeList = getPluginCodes(props);
197+
final List<String> pluginCodeList = this.getPluginCodes(props);
152198
pluginFactories = new ArrayList<>(pluginCodeList.size());
153199

154200
for (final String pluginCode : pluginCodeList) {
@@ -210,14 +256,23 @@ public List<ConnectionPlugin> getPlugins(
210256
return plugins;
211257
}
212258

213-
public static List<String> getPluginCodes(final Properties props) {
259+
public List<String> getPluginCodes(final Properties props) {
214260
String pluginCodes = PropertyDefinition.PLUGINS.getString(props);
215261
if (pluginCodes == null) {
216262
pluginCodes = DEFAULT_PLUGINS;
217263
}
218264
return StringUtils.split(pluginCodes, ",", true);
219265
}
220266

267+
public String getPluginCodes(final List<ConnectionPlugin> plugins) {
268+
return plugins.stream()
269+
.filter(x -> !(x instanceof DefaultConnectionPlugin))
270+
.map(x -> pluginCodeByPlugin.getOrDefault(x, "unknown"))
271+
.distinct()
272+
.sorted()
273+
.collect(Collectors.joining("+"));
274+
}
275+
221276
protected List<Class<? extends ConnectionPluginFactory>> sortPluginFactories(
222277
final List<Class<? extends ConnectionPluginFactory>> unsortedPluginFactories) {
223278

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,15 @@ public class ConnectionPluginManager implements CanReleaseResources, Wrapper {
100100
private static final String INIT_HOST_PROVIDER_METHOD = "initHostProvider";
101101
private static final String NOTIFY_CONNECTION_CHANGED_METHOD = "notifyConnectionChanged";
102102
private static final String NOTIFY_NODE_LIST_CHANGED_METHOD = "notifyNodeListChanged";
103+
104+
public static final String EFFECTIVE_PLUGIN_CODES_PROPERTY = "36377fa6-f016-483f-a78a-02f68c71201a";
103105
private static final SqlMethodAnalyzer sqlMethodAnalyzer = new SqlMethodAnalyzer();
104106

105107
private final ReentrantLock lock = new ReentrantLock();
106108

107109
protected Properties props = new Properties();
108110
protected List<ConnectionPlugin> plugins;
111+
protected String effectivePluginCodes;
109112
protected final @NonNull ConnectionProvider defaultConnProvider;
110113
protected final @Nullable ConnectionProvider effectiveConnProvider;
111114
protected final ConnectionWrapper connectionWrapper;
@@ -204,6 +207,8 @@ public void init(
204207
pluginManagerService,
205208
props,
206209
configurationProfile);
210+
this.effectivePluginCodes = pluginChainBuilder.getPluginCodes(this.plugins);
211+
this.props.setProperty(EFFECTIVE_PLUGIN_CODES_PROPERTY, this.effectivePluginCodes);
207212
}
208213

209214
protected <T, E extends Exception> T executeWithSubscribedPlugins(

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import software.amazon.jdbc.dialect.Dialect;
4242
import software.amazon.jdbc.dialect.DialectManager;
4343
import software.amazon.jdbc.dialect.DialectProvider;
44-
import software.amazon.jdbc.dialect.HostListProviderSupplier;
44+
import software.amazon.jdbc.hostlistprovider.HostListProviderSupplier;
4545
import software.amazon.jdbc.exceptions.ExceptionHandler;
4646
import software.amazon.jdbc.exceptions.ExceptionManager;
4747
import software.amazon.jdbc.hostavailability.HostAvailability;
@@ -709,13 +709,14 @@ public void updateDialect(final @NonNull Connection connection) throws SQLExcept
709709
this.dialect = this.dialectProvider.getDialect(
710710
this.originalUrl,
711711
this.initialConnectionHostSpec,
712-
connection);
712+
connection,
713+
this.props);
713714
if (originalDialect == this.dialect) {
714715
return;
715716
}
716717

717718
final HostListProviderSupplier supplier = this.dialect.getHostListProvider();
718-
this.setHostListProvider(supplier.getProvider(props, this.originalUrl, this, this));
719+
this.setHostListProvider(supplier.getProvider(this.props, this.originalUrl, this, this));
719720
}
720721

721722
@Override

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ public static void removeAllExceptCredentials(final Properties props) {
233233
final String password = props.getProperty(PropertyDefinition.PASSWORD.name, null);
234234

235235
removeAll(props);
236+
props.remove(ConnectionPluginManager.EFFECTIVE_PLUGIN_CODES_PROPERTY);
236237

237238
if (user != null) {
238239
props.setProperty(PropertyDefinition.USER.name, user);

wrapper/src/main/java/software/amazon/jdbc/dialect/AuroraMysqlDialect.java

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
import java.sql.Statement;
2323
import java.util.Collections;
2424
import java.util.List;
25+
import java.util.Properties;
2526
import software.amazon.jdbc.hostlistprovider.AuroraHostListProvider;
27+
import software.amazon.jdbc.hostlistprovider.HostListProviderSupplier;
2628
import software.amazon.jdbc.hostlistprovider.monitoring.MonitoringRdsHostListProvider;
2729
import software.amazon.jdbc.plugin.failover2.FailoverConnectionPlugin;
2830

@@ -43,33 +45,21 @@ public class AuroraMysqlDialect extends MysqlDialect {
4345
private static final String IS_READER_QUERY = "SELECT @@innodb_read_only";
4446

4547
@Override
46-
public boolean isDialect(final Connection connection) {
47-
Statement stmt = null;
48-
ResultSet rs = null;
48+
public boolean isDialect(final Connection connection, final Properties properties) {
49+
if (!super.isDialect(connection, properties)) {
50+
return false;
51+
}
52+
4953
try {
50-
stmt = connection.createStatement();
51-
rs = stmt.executeQuery("SHOW VARIABLES LIKE 'aurora_version'");
52-
if (rs.next()) {
53-
// If variable with such name is presented then it means it's an Aurora cluster
54-
return true;
55-
}
56-
} catch (final SQLException ex) {
57-
// ignore
58-
} finally {
59-
if (stmt != null) {
60-
try {
61-
stmt.close();
62-
} catch (SQLException ex) {
63-
// ignore
64-
}
65-
}
66-
if (rs != null) {
67-
try {
68-
rs.close();
69-
} catch (SQLException ex) {
70-
// ignore
54+
try (Statement stmt = connection.createStatement();
55+
ResultSet rs = stmt.executeQuery("SHOW VARIABLES LIKE 'aurora_version'")) {
56+
if (rs.next()) {
57+
// If variable with such name is presented then it means it's an Aurora cluster
58+
return true;
7159
}
7260
}
61+
} catch (SQLException ex) {
62+
// do nothing
7363
}
7464
return false;
7565
}

wrapper/src/main/java/software/amazon/jdbc/dialect/AuroraPgDialect.java

Lines changed: 21 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
import java.sql.ResultSet;
2121
import java.sql.SQLException;
2222
import java.sql.Statement;
23+
import java.util.Properties;
2324
import java.util.logging.Logger;
2425
import software.amazon.jdbc.hostlistprovider.AuroraHostListProvider;
26+
import software.amazon.jdbc.hostlistprovider.HostListProviderSupplier;
2527
import software.amazon.jdbc.hostlistprovider.monitoring.MonitoringRdsHostListProvider;
2628
import software.amazon.jdbc.plugin.failover2.FailoverConnectionPlugin;
2729

@@ -57,72 +59,36 @@ public class AuroraPgDialect extends PgDialect implements AuroraLimitlessDialect
5759
"select router_endpoint, load from aurora_limitless_router_endpoints()";
5860

5961
@Override
60-
public boolean isDialect(final Connection connection) {
61-
if (!super.isDialect(connection)) {
62+
public boolean isDialect(final Connection connection, final Properties properties) {
63+
if (!super.isDialect(connection, properties)) {
6264
return false;
6365
}
6466

65-
Statement stmt = null;
66-
ResultSet rs = null;
67-
boolean hasExtensions = false;
68-
boolean hasTopology = false;
6967
try {
70-
stmt = connection.createStatement();
71-
rs = stmt.executeQuery(extensionsSql);
72-
if (rs.next()) {
68+
try (Statement stmt = connection.createStatement();
69+
ResultSet rs = stmt.executeQuery(extensionsSql)) {
70+
if (!rs.next()) {
71+
return false;
72+
}
7373
final boolean auroraUtils = rs.getBoolean("aurora_stat_utils");
7474
LOGGER.finest(() -> String.format("auroraUtils: %b", auroraUtils));
75-
if (auroraUtils) {
76-
hasExtensions = true;
77-
}
78-
}
79-
} catch (SQLException ex) {
80-
// ignore
81-
} finally {
82-
if (stmt != null) {
83-
try {
84-
stmt.close();
85-
} catch (SQLException ex) {
86-
// ignore
75+
if (!auroraUtils) {
76+
return false;
8777
}
8878
}
89-
if (rs != null) {
90-
try {
91-
rs.close();
92-
} catch (SQLException ex) {
93-
// ignore
94-
}
95-
}
96-
}
97-
if (!hasExtensions) {
98-
return false;
99-
}
100-
try {
101-
stmt = connection.createStatement();
102-
rs = stmt.executeQuery(topologySql);
103-
if (rs.next()) {
104-
LOGGER.finest(() -> "hasTopology: true");
105-
hasTopology = true;
106-
}
107-
} catch (final SQLException ex) {
108-
// ignore
109-
} finally {
110-
if (stmt != null) {
111-
try {
112-
stmt.close();
113-
} catch (SQLException ex) {
114-
// ignore
115-
}
116-
}
117-
if (rs != null) {
118-
try {
119-
rs.close();
120-
} catch (SQLException ex) {
121-
// ignore
79+
80+
try (Statement stmt = connection.createStatement();
81+
ResultSet rs = stmt.executeQuery(topologySql)) {
82+
if (rs.next()) {
83+
LOGGER.finest(() -> "hasTopology: true");
84+
return true;
12285
}
86+
LOGGER.finest(() -> "hasTopology: false");
12387
}
88+
} catch (SQLException ex) {
89+
// do nothing
12490
}
125-
return hasExtensions && hasTopology;
91+
return false;
12692
}
12793

12894
@Override

wrapper/src/main/java/software/amazon/jdbc/dialect/Dialect.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.checkerframework.checker.nullness.qual.NonNull;
2424
import software.amazon.jdbc.HostSpec;
2525
import software.amazon.jdbc.exceptions.ExceptionHandler;
26+
import software.amazon.jdbc.hostlistprovider.HostListProviderSupplier;
2627
import software.amazon.jdbc.plugin.failover.FailoverRestriction;
2728

2829
public interface Dialect {
@@ -32,16 +33,18 @@ public interface Dialect {
3233

3334
String getHostAliasQuery();
3435

35-
String getServerVersionQuery();
36+
String getServerVersionQuery(final Properties properties);
3637

37-
boolean isDialect(Connection connection);
38+
boolean isDialect(final Connection connection, final Properties properties);
3839

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

4142
HostListProviderSupplier getHostListProvider();
4243

4344
void prepareConnectProperties(
44-
final @NonNull Properties connectProperties, final @NonNull String protocol, final @NonNull HostSpec hostSpec);
45+
final @NonNull Properties connectProperties,
46+
final @NonNull String protocol,
47+
final @NonNull HostSpec hostSpec);
4548

4649
EnumSet<FailoverRestriction> getFailoverRestrictions();
4750
}

wrapper/src/main/java/software/amazon/jdbc/dialect/DialectManager.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ public Dialect getDialect(
157157
}
158158

159159
String host = url;
160-
final List<HostSpec> hosts = this.connectionUrlParser.getHostsFromConnectionUrl(url, true,
161-
() -> pluginService.getHostSpecBuilder());
160+
final List<HostSpec> hosts = this.connectionUrlParser.getHostsFromConnectionUrl(
161+
url, true, pluginService::getHostSpecBuilder);
162162
if (!Utils.isNullOrEmpty(hosts)) {
163163
host = hosts.get(0).getHost();
164164
}
@@ -232,7 +232,8 @@ public Dialect getDialect(
232232
public Dialect getDialect(
233233
final @NonNull String originalUrl,
234234
final @NonNull HostSpec hostSpec,
235-
final @NonNull Connection connection) throws SQLException {
235+
final @NonNull Connection connection,
236+
final @NonNull Properties properties) throws SQLException {
236237

237238
if (!this.canUpdate) {
238239
this.logCurrentDialect();
@@ -247,7 +248,7 @@ public Dialect getDialect(
247248
throw new SQLException(
248249
Messages.get("DialectManager.unknownDialectCode", new Object[] {dialectCandidateCode}));
249250
}
250-
boolean isDialect = dialectCandidate.isDialect(connection);
251+
boolean isDialect = dialectCandidate.isDialect(connection, properties);
251252
if (isDialect) {
252253
this.canUpdate = false;
253254
this.dialectCode = dialectCandidateCode;

wrapper/src/main/java/software/amazon/jdbc/dialect/DialectProvider.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,6 @@ Dialect getDialect(
3131
Dialect getDialect(
3232
final @NonNull String originalUrl,
3333
final @NonNull HostSpec hostSpec,
34-
final @NonNull Connection connection) throws SQLException;
34+
final @NonNull Connection connection,
35+
final @NonNull Properties properties) throws SQLException;
3536
}

0 commit comments

Comments
 (0)