in wrapper/src/main/java/software/amazon/jdbc/plugin/staledns/AuroraStaleDnsHelper.java [61:165]
public Connection getVerifiedConnection(
final boolean isInitialConnection,
final HostListProviderService hostListProviderService,
final String driverProtocol,
final HostSpec hostSpec,
final Properties props,
final JdbcCallable<Connection, SQLException> connectFunc) throws SQLException {
if (!this.rdsUtils.isWriterClusterDns(hostSpec.getHost())) {
return connectFunc.call();
}
final Connection conn = connectFunc.call();
String clusterInetAddress = null;
try {
clusterInetAddress = InetAddress.getByName(hostSpec.getHost()).getHostAddress();
} catch (UnknownHostException e) {
// ignore
}
final String hostInetAddress = clusterInetAddress;
LOGGER.finest(() -> Messages.get("AuroraStaleDnsHelper.clusterEndpointDns",
new Object[]{hostInetAddress}));
if (clusterInetAddress == null) {
return conn;
}
if (this.pluginService.getHostRole(conn) == HostRole.READER) {
// This is if-statement is only reached if the connection url is a writer cluster endpoint.
// If the new connection resolves to a reader instance, this means the topology is outdated.
// Force refresh to update the topology.
this.pluginService.forceRefreshHostList(conn);
} else {
this.pluginService.refreshHostList(conn);
}
LOGGER.finest(() -> Utils.logTopology(this.pluginService.getAllHosts()));
if (this.writerHostSpec == null) {
final HostSpec writerCandidate = this.getWriter();
if (writerCandidate != null && this.rdsUtils.isRdsClusterDns(writerCandidate.getHost())) {
return null;
}
this.writerHostSpec = writerCandidate;
}
LOGGER.finest(() -> Messages.get("AuroraStaleDnsHelper.writerHostSpec",
new Object[]{this.writerHostSpec}));
if (this.writerHostSpec == null) {
return conn;
}
if (this.writerHostAddress == null) {
try {
this.writerHostAddress = InetAddress.getByName(this.writerHostSpec.getHost()).getHostAddress();
} catch (UnknownHostException e) {
// ignore
}
}
LOGGER.finest(() -> Messages.get("AuroraStaleDnsHelper.writerInetAddress",
new Object[]{this.writerHostAddress}));
if (this.writerHostAddress == null) {
return conn;
}
if (!writerHostAddress.equals(clusterInetAddress)) {
// DNS resolves a cluster endpoint to a wrong writer
// opens a connection to a proper writer node
LOGGER.fine(() -> Messages.get("AuroraStaleDnsHelper.staleDnsDetected",
new Object[]{this.writerHostSpec}));
staleDNSDetectedCounter.inc();
final List<HostSpec> allowedHosts = this.pluginService.getHosts();
if (!Utils.containsUrl(allowedHosts, this.writerHostSpec.getUrl())) {
throw new SQLException(
Messages.get("AuroraStaleDnsHelper.currentWriterNotAllowed",
new Object[] {
this.writerHostSpec == null ? "<null>" : this.writerHostSpec.getUrl(),
Utils.logTopology(allowedHosts, "")})
);
}
final Connection writerConn = this.pluginService.connect(this.writerHostSpec, props);
if (isInitialConnection) {
hostListProviderService.setInitialConnectionHostSpec(this.writerHostSpec);
}
if (conn != null) {
try {
conn.close();
} catch (final SQLException ex) {
// ignore
}
return writerConn;
}
}
return conn;
}