Skip to content

Commit 4b34e04

Browse files
committed
use query comment or connection attributes to provide driver metadata
1 parent 5c584e9 commit 4b34e04

20 files changed

+337
-342
lines changed

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

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,34 @@ public class ConnectionPluginChainBuilder {
8787
}
8888
};
8989

90+
protected static final Map<String /* clazz */, String> pluginCodeByPlugin =
91+
new HashMap<String, String>() {
92+
{
93+
put("software.amazon.jdbc.plugin.ExecutionTimeConnectionPlugin", "executionTime");
94+
put("software.amazon.jdbc.plugin.LogQueryConnectionPlugin", "logQuery");
95+
put("software.amazon.jdbc.plugin.DataCacheConnectionPlugin", "dataCache");
96+
put("software.amazon.jdbc.plugin.customendpoint.CustomEndpointPlugin", "customEndpoint");
97+
put("software.amazon.jdbc.plugin.efm.HostMonitoringConnectionPlugin", "efm");
98+
put("software.amazon.jdbc.plugin.efm2.HostMonitoringConnectionPlugin", "efm2");
99+
put("software.amazon.jdbc.plugin.failover.FailoverConnectionPlugin", "failover");
100+
put("software.amazon.jdbc.plugin.failover2.FailoverConnectionPlugin", "failover2");
101+
put("software.amazon.jdbc.plugin.iam.IamAuthConnectionPlugin", "iam");
102+
put("software.amazon.jdbc.plugin.AwsSecretsManagerConnectionPlugin", "awsSecretsManager");
103+
put("software.amazon.jdbc.plugin.federatedauth.FederatedAuthPlugin", "federatedAuth");
104+
put("software.amazon.jdbc.plugin.federatedauth.OktaAuthPlugin", "okta");
105+
put("software.amazon.jdbc.plugin.staledns.AuroraStaleDnsPlugin", "auroraStaleDns");
106+
put("software.amazon.jdbc.plugin.readwritesplitting.ReadWriteSplittingPlugin", "readWriteSplitting");
107+
put("software.amazon.jdbc.plugin.AuroraConnectionTrackerPlugin", "auroraConnectionTracker");
108+
put("software.amazon.jdbc.plugin.DriverMetaDataConnectionPlugin", "driverMetaData");
109+
put("software.amazon.jdbc.plugin.ConnectTimeConnectionPlugin", "connectTime");
110+
put("software.amazon.jdbc.plugin.dev.DeveloperConnectionPlugin", "dev");
111+
put("software.amazon.jdbc.plugin.strategy.fastestresponse.FastestResponseStrategyPlugin",
112+
"fastestResponseStrategy");
113+
put("software.amazon.jdbc.plugin.AuroraInitialConnectionStrategyPlugin", "initialConnection");
114+
put("software.amazon.jdbc.plugin.limitless.LimitlessConnectionPlugin", "limitless");
115+
}
116+
};
117+
90118
/**
91119
* The final list of plugins will be sorted by weight, starting from the lowest values up to
92120
* the highest values. The first plugin of the list will have the lowest weight, and the
@@ -151,7 +179,7 @@ public List<ConnectionPlugin> getPlugins(
151179
pluginFactories = configurationProfile.getPluginFactories();
152180
} else {
153181

154-
final List<String> pluginCodeList = getPluginCodes(props);
182+
final List<String> pluginCodeList = this.getPluginCodes(props);
155183
pluginFactories = new ArrayList<>(pluginCodeList.size());
156184

157185
for (final String pluginCode : pluginCodeList) {
@@ -213,14 +241,23 @@ public List<ConnectionPlugin> getPlugins(
213241
return plugins;
214242
}
215243

216-
public static List<String> getPluginCodes(final Properties props) {
244+
public List<String> getPluginCodes(final Properties props) {
217245
String pluginCodes = PropertyDefinition.PLUGINS.getString(props);
218246
if (pluginCodes == null) {
219247
pluginCodes = DEFAULT_PLUGINS;
220248
}
221249
return StringUtils.split(pluginCodes, ",", true);
222250
}
223251

252+
public String getPluginCodes(final List<ConnectionPlugin> plugins) {
253+
return plugins.stream()
254+
.filter(x -> !(x instanceof DefaultConnectionPlugin))
255+
.map(x -> pluginCodeByPlugin.getOrDefault(x.getClass().getName(), "unknown"))
256+
.distinct()
257+
.sorted()
258+
.collect(Collectors.joining("+"));
259+
}
260+
224261
protected List<Class<? extends ConnectionPluginFactory>> sortPluginFactories(
225262
final List<Class<? extends ConnectionPluginFactory>> unsortedPluginFactories) {
226263

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: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,13 +718,14 @@ public void updateDialect(final @NonNull Connection connection) throws SQLExcept
718718
this.dialect = this.dialectProvider.getDialect(
719719
this.originalUrl,
720720
this.initialConnectionHostSpec,
721-
connection);
721+
connection,
722+
this.props);
722723
if (originalDialect == this.dialect) {
723724
return;
724725
}
725726

726727
final HostListProviderSupplier supplier = this.dialect.getHostListProvider();
727-
this.setHostListProvider(supplier.getProvider(props, this.originalUrl, this, this));
728+
this.setHostListProvider(supplier.getProvider(this.props, this.originalUrl, this, this));
728729
this.refreshHostList(connection);
729730
}
730731

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,6 +22,7 @@
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;
2627
import software.amazon.jdbc.hostlistprovider.monitoring.MonitoringRdsHostListProvider;
2728
import software.amazon.jdbc.plugin.failover2.FailoverConnectionPlugin;
@@ -50,33 +51,22 @@ public class AuroraMysqlDialect extends MysqlDialect implements BlueGreenDialect
5051
+ " table_schema = 'mysql' AND table_name = 'rds_topology'";
5152

5253
@Override
53-
public boolean isDialect(final Connection connection) {
54-
Statement stmt = null;
55-
ResultSet rs = null;
54+
public boolean isDialect(final Connection connection, final Properties properties) {
55+
if (super.isDialect(connection, properties)) {
56+
// If super.isDialect() returns true then there is no need to check other conditions.
57+
return false;
58+
}
59+
5660
try {
57-
stmt = connection.createStatement();
58-
rs = stmt.executeQuery("SHOW VARIABLES LIKE 'aurora_version'");
59-
if (rs.next()) {
60-
// If variable with such name is presented then it means it's an Aurora cluster
61-
return true;
62-
}
63-
} catch (final SQLException ex) {
64-
// ignore
65-
} finally {
66-
if (stmt != null) {
67-
try {
68-
stmt.close();
69-
} catch (SQLException ex) {
70-
// ignore
71-
}
72-
}
73-
if (rs != null) {
74-
try {
75-
rs.close();
76-
} catch (SQLException ex) {
77-
// ignore
61+
try (Statement stmt = connection.createStatement();
62+
ResultSet rs = stmt.executeQuery("SHOW VARIABLES LIKE 'aurora_version'")) {
63+
if (rs.next()) {
64+
// If variable with such name is presented then it means it's an Aurora cluster
65+
return true;
7866
}
7967
}
68+
} catch (SQLException ex) {
69+
// do nothing
8070
}
8171
return false;
8272
}

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

Lines changed: 20 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
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;
2526
import software.amazon.jdbc.hostlistprovider.monitoring.MonitoringRdsHostListProvider;
@@ -64,72 +65,36 @@ public class AuroraPgDialect extends PgDialect implements AuroraLimitlessDialect
6465
"SELECT 'get_blue_green_fast_switchover_metadata'::regproc";
6566

6667
@Override
67-
public boolean isDialect(final Connection connection) {
68-
if (!super.isDialect(connection)) {
68+
public boolean isDialect(final Connection connection, final Properties properties) {
69+
if (!super.isDialect(connection, properties)) {
6970
return false;
7071
}
7172

72-
Statement stmt = null;
73-
ResultSet rs = null;
74-
boolean hasExtensions = false;
75-
boolean hasTopology = false;
7673
try {
77-
stmt = connection.createStatement();
78-
rs = stmt.executeQuery(extensionsSql);
79-
if (rs.next()) {
74+
try (Statement stmt = connection.createStatement();
75+
ResultSet rs = stmt.executeQuery(extensionsSql)) {
76+
if (!rs.next()) {
77+
return false;
78+
}
8079
final boolean auroraUtils = rs.getBoolean("aurora_stat_utils");
8180
LOGGER.finest(() -> String.format("auroraUtils: %b", auroraUtils));
82-
if (auroraUtils) {
83-
hasExtensions = true;
84-
}
85-
}
86-
} catch (SQLException ex) {
87-
// ignore
88-
} finally {
89-
if (stmt != null) {
90-
try {
91-
stmt.close();
92-
} catch (SQLException ex) {
93-
// ignore
81+
if (!auroraUtils) {
82+
return false;
9483
}
9584
}
96-
if (rs != null) {
97-
try {
98-
rs.close();
99-
} catch (SQLException ex) {
100-
// ignore
101-
}
102-
}
103-
}
104-
if (!hasExtensions) {
105-
return false;
106-
}
107-
try {
108-
stmt = connection.createStatement();
109-
rs = stmt.executeQuery(topologySql);
110-
if (rs.next()) {
111-
LOGGER.finest(() -> "hasTopology: true");
112-
hasTopology = true;
113-
}
114-
} catch (final SQLException ex) {
115-
// ignore
116-
} finally {
117-
if (stmt != null) {
118-
try {
119-
stmt.close();
120-
} catch (SQLException ex) {
121-
// ignore
122-
}
123-
}
124-
if (rs != null) {
125-
try {
126-
rs.close();
127-
} catch (SQLException ex) {
128-
// ignore
85+
86+
try (Statement stmt = connection.createStatement();
87+
ResultSet rs = stmt.executeQuery(topologySql)) {
88+
if (rs.next()) {
89+
LOGGER.finest(() -> "hasTopology: true");
90+
return true;
12991
}
92+
LOGGER.finest(() -> "hasTopology: false");
13093
}
94+
} catch (SQLException ex) {
95+
// do nothing
13196
}
132-
return hasExtensions && hasTopology;
97+
return false;
13398
}
13499

135100
@Override

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,23 @@ public interface Dialect {
3232

3333
String getHostAliasQuery();
3434

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

37-
boolean isDialect(Connection connection);
40+
boolean isDialect(final Connection connection, final Properties properties);
3841

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

4144
HostListProviderSupplier getHostListProvider();
4245

4346
void prepareConnectProperties(
44-
final @NonNull Properties connectProperties, final @NonNull String protocol, final @NonNull HostSpec hostSpec);
47+
final @NonNull Properties connectProperties,
48+
final @NonNull String protocol,
49+
final @NonNull HostSpec hostSpec);
4550

4651
EnumSet<FailoverRestriction> getFailoverRestrictions();
52+
53+
void reportMetadata(final @NonNull Connection connection, final @NonNull Properties properties);
4754
}

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public class DialectManager implements DialectProvider {
7979
private final RdsUtils rdsHelper = new RdsUtils();
8080
private final ConnectionUrlParser connectionUrlParser = new ConnectionUrlParser();
8181
private boolean canUpdate = false;
82+
private boolean shouldReportMetadata = false;
8283
private Dialect dialect = null;
8384
private String dialectCode;
8485

@@ -131,6 +132,7 @@ public Dialect getDialect(
131132
this.dialectCode = DialectCodes.CUSTOM;
132133
this.dialect = customDialect;
133134
this.logCurrentDialect();
135+
this.shouldReportMetadata = true;
134136
return this.dialect;
135137
}
136138

@@ -145,6 +147,7 @@ public Dialect getDialect(
145147
this.dialectCode = dialectCode;
146148
this.dialect = userDialect;
147149
this.logCurrentDialect();
150+
this.shouldReportMetadata = true;
148151
return userDialect;
149152
} else {
150153
throw new SQLException(
@@ -157,8 +160,8 @@ public Dialect getDialect(
157160
}
158161

159162
String host = url;
160-
final List<HostSpec> hosts = this.connectionUrlParser.getHostsFromConnectionUrl(url, true,
161-
() -> pluginService.getHostSpecBuilder());
163+
final List<HostSpec> hosts = this.connectionUrlParser.getHostsFromConnectionUrl(
164+
url, true, pluginService::getHostSpecBuilder);
162165
if (!Utils.isNullOrEmpty(hosts)) {
163166
host = hosts.get(0).getHost();
164167
}
@@ -232,10 +235,15 @@ public Dialect getDialect(
232235
public Dialect getDialect(
233236
final @NonNull String originalUrl,
234237
final @NonNull HostSpec hostSpec,
235-
final @NonNull Connection connection) throws SQLException {
238+
final @NonNull Connection connection,
239+
final @NonNull Properties properties) throws SQLException {
236240

237241
if (!this.canUpdate) {
238242
this.logCurrentDialect();
243+
if (this.shouldReportMetadata) {
244+
this.dialect.reportMetadata(connection, properties);
245+
this.shouldReportMetadata = false;
246+
}
239247
return this.dialect;
240248
}
241249

@@ -247,7 +255,7 @@ public Dialect getDialect(
247255
throw new SQLException(
248256
Messages.get("DialectManager.unknownDialectCode", new Object[] {dialectCandidateCode}));
249257
}
250-
boolean isDialect = dialectCandidate.isDialect(connection);
258+
boolean isDialect = dialectCandidate.isDialect(connection, properties);
251259
if (isDialect) {
252260
this.canUpdate = false;
253261
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)