diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a126693b..e0bd913e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/#semantic-versioning-200). +## [2.3.6] - ? + +### :crab: Changed +- Log level of `Failover.startWriterFailover` and `Failover.establishedConnection` from `fine` to `info` for better visibility of failover-related logs ([Issue #890](https://github.com/awslabs/aws-advanced-jdbc-wrapper/issues/890)). + ## [2.3.5] - 2024-03-14 ### :magic_wand: Added diff --git a/aws-advanced-jdbc-wrapper-bundle/build.gradle.kts b/aws-advanced-jdbc-wrapper-bundle/build.gradle.kts index 9b7c0b648..c1e73df96 100644 --- a/aws-advanced-jdbc-wrapper-bundle/build.gradle.kts +++ b/aws-advanced-jdbc-wrapper-bundle/build.gradle.kts @@ -24,8 +24,8 @@ repositories { } dependencies { - implementation("software.amazon.awssdk:rds:2.25.2") - implementation("software.amazon.awssdk:sts:2.25.2") + implementation("software.amazon.awssdk:rds:2.25.12") + implementation("software.amazon.awssdk:sts:2.25.17") implementation(project(":aws-advanced-jdbc-wrapper")) } diff --git a/benchmarks/build.gradle.kts b/benchmarks/build.gradle.kts index e8f6c54c0..559957a22 100644 --- a/benchmarks/build.gradle.kts +++ b/benchmarks/build.gradle.kts @@ -22,7 +22,7 @@ dependencies { jmhImplementation(project(":aws-advanced-jdbc-wrapper")) implementation("org.postgresql:postgresql:42.7.2") implementation("mysql:mysql-connector-java:8.0.33") - implementation("org.mariadb.jdbc:mariadb-java-client:3.3.2") + implementation("org.mariadb.jdbc:mariadb-java-client:3.3.3") implementation("com.zaxxer:HikariCP:4.0.3") testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.1") diff --git a/examples/AWSDriverExample/build.gradle.kts b/examples/AWSDriverExample/build.gradle.kts index e12160cb6..3b92a244a 100644 --- a/examples/AWSDriverExample/build.gradle.kts +++ b/examples/AWSDriverExample/build.gradle.kts @@ -18,13 +18,13 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-jdbc:2.7.13") // 2.7.13 is the last version compatible with Java 8 implementation("org.postgresql:postgresql:42.7.2") implementation("mysql:mysql-connector-java:8.0.33") - implementation("software.amazon.awssdk:rds:2.25.2") + implementation("software.amazon.awssdk:rds:2.25.12") implementation("software.amazon.awssdk:secretsmanager:2.25.2") - implementation("software.amazon.awssdk:sts:2.25.2") + implementation("software.amazon.awssdk:sts:2.25.17") implementation("com.fasterxml.jackson.core:jackson-databind:2.16.1") implementation(project(":aws-advanced-jdbc-wrapper")) - implementation("io.opentelemetry:opentelemetry-api:1.35.0") + implementation("io.opentelemetry:opentelemetry-api:1.36.0") implementation("io.opentelemetry:opentelemetry-sdk:1.35.0") - implementation("io.opentelemetry:opentelemetry-exporter-otlp:1.35.0") + implementation("io.opentelemetry:opentelemetry-exporter-otlp:1.36.0") implementation("com.amazonaws:aws-xray-recorder-sdk-core:2.15.0") } diff --git a/examples/DBCPExample/build.gradle.kts b/examples/DBCPExample/build.gradle.kts index 90659d561..a33f63121 100644 --- a/examples/DBCPExample/build.gradle.kts +++ b/examples/DBCPExample/build.gradle.kts @@ -19,5 +19,5 @@ dependencies { implementation("mysql:mysql-connector-java:8.0.33") implementation(project(":aws-advanced-jdbc-wrapper")) implementation("org.apache.commons:commons-dbcp2:2.12.0") - implementation("software.amazon.awssdk:rds:2.25.2") + implementation("software.amazon.awssdk:rds:2.25.12") } diff --git a/examples/SpringHibernateBalancedReaderOneDataSourceExample/build.gradle.kts b/examples/SpringHibernateBalancedReaderOneDataSourceExample/build.gradle.kts index 26f18bf8e..63679725b 100644 --- a/examples/SpringHibernateBalancedReaderOneDataSourceExample/build.gradle.kts +++ b/examples/SpringHibernateBalancedReaderOneDataSourceExample/build.gradle.kts @@ -23,6 +23,6 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.springframework.retry:spring-retry") implementation("org.postgresql:postgresql:42.7.2") - implementation("software.amazon.awssdk:rds:2.25.2") + implementation("software.amazon.awssdk:rds:2.25.12") implementation(project(":aws-advanced-jdbc-wrapper")) } diff --git a/examples/SpringHibernateBalancedReaderTwoDataSourceExample/build.gradle.kts b/examples/SpringHibernateBalancedReaderTwoDataSourceExample/build.gradle.kts index 26f18bf8e..63679725b 100644 --- a/examples/SpringHibernateBalancedReaderTwoDataSourceExample/build.gradle.kts +++ b/examples/SpringHibernateBalancedReaderTwoDataSourceExample/build.gradle.kts @@ -23,6 +23,6 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.springframework.retry:spring-retry") implementation("org.postgresql:postgresql:42.7.2") - implementation("software.amazon.awssdk:rds:2.25.2") + implementation("software.amazon.awssdk:rds:2.25.12") implementation(project(":aws-advanced-jdbc-wrapper")) } diff --git a/examples/SpringHibernateExample/build.gradle.kts b/examples/SpringHibernateExample/build.gradle.kts index 694415c30..608a57c22 100644 --- a/examples/SpringHibernateExample/build.gradle.kts +++ b/examples/SpringHibernateExample/build.gradle.kts @@ -23,6 +23,6 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.postgresql:postgresql:42.7.2") - implementation("software.amazon.awssdk:rds:2.25.2") + implementation("software.amazon.awssdk:rds:2.25.12") implementation(project(":aws-advanced-jdbc-wrapper")) } diff --git a/examples/SpringWildflyExample/spring/build.gradle.kts b/examples/SpringWildflyExample/spring/build.gradle.kts index e2434c0e7..eff3854c7 100644 --- a/examples/SpringWildflyExample/spring/build.gradle.kts +++ b/examples/SpringWildflyExample/spring/build.gradle.kts @@ -24,6 +24,6 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") runtimeOnly("org.springframework.boot:spring-boot-devtools") implementation("org.postgresql:postgresql:42.7.2") - implementation("software.amazon.awssdk:rds:2.25.2") + implementation("software.amazon.awssdk:rds:2.25.12") implementation(project(":aws-advanced-jdbc-wrapper")) } diff --git a/wrapper/build.gradle.kts b/wrapper/build.gradle.kts index c07b56136..ba75dc644 100644 --- a/wrapper/build.gradle.kts +++ b/wrapper/build.gradle.kts @@ -29,24 +29,24 @@ plugins { dependencies { implementation("org.checkerframework:checker-qual:3.42.0") compileOnly("org.apache.httpcomponents:httpclient:4.5.14") - compileOnly("software.amazon.awssdk:rds:2.25.2") + compileOnly("software.amazon.awssdk:rds:2.25.12") compileOnly("software.amazon.awssdk:auth:2.25.2") // Required for IAM (light implementation) compileOnly("software.amazon.awssdk:http-client-spi:2.25.2") // Required for IAM (light implementation) - compileOnly("software.amazon.awssdk:sts:2.25.2") + compileOnly("software.amazon.awssdk:sts:2.25.17") compileOnly("com.zaxxer:HikariCP:4.0.3") // Version 4.+ is compatible with Java 8 compileOnly("software.amazon.awssdk:secretsmanager:2.25.2") compileOnly("com.fasterxml.jackson.core:jackson-databind:2.16.1") compileOnly("mysql:mysql-connector-java:8.0.33") compileOnly("org.postgresql:postgresql:42.7.2") - compileOnly("org.mariadb.jdbc:mariadb-java-client:3.3.2") + compileOnly("org.mariadb.jdbc:mariadb-java-client:3.3.3") compileOnly("org.osgi:org.osgi.core:6.0.0") compileOnly("org.osgi:org.osgi.core:6.0.0") compileOnly("com.amazonaws:aws-xray-recorder-sdk-core:2.15.0") - compileOnly("io.opentelemetry:opentelemetry-api:1.35.0") + compileOnly("io.opentelemetry:opentelemetry-api:1.36.0") compileOnly("io.opentelemetry:opentelemetry-sdk:1.35.0") compileOnly("io.opentelemetry:opentelemetry-sdk-metrics:1.35.0") - testImplementation("org.junit.platform:junit-platform-commons:1.10.1") + testImplementation("org.junit.platform:junit-platform-commons:1.10.2") testImplementation("org.junit.platform:junit-platform-engine:1.10.1") testImplementation("org.junit.platform:junit-platform-launcher:1.10.2") testImplementation("org.junit.platform:junit-platform-suite-engine:1.10.2") @@ -57,31 +57,31 @@ dependencies { testImplementation("org.apache.commons:commons-dbcp2:2.11.0") testImplementation("org.postgresql:postgresql:42.7.2") testImplementation("mysql:mysql-connector-java:8.0.33") - testImplementation("org.mariadb.jdbc:mariadb-java-client:3.3.2") + testImplementation("org.mariadb.jdbc:mariadb-java-client:3.3.3") testImplementation("com.zaxxer:HikariCP:4.0.3") // Version 4.+ is compatible with Java 8 testImplementation("org.springframework.boot:spring-boot-starter-jdbc:2.7.13") // 2.7.13 is the last version compatible with Java 8 testImplementation("org.mockito:mockito-inline:4.11.0") // 4.11.0 is the last version compatible with Java 8 - testImplementation("software.amazon.awssdk:rds:2.25.2") + testImplementation("software.amazon.awssdk:rds:2.25.12") testImplementation("software.amazon.awssdk:auth:2.25.2") // Required for IAM (light implementation) testImplementation("software.amazon.awssdk:http-client-spi:2.25.2") // Required for IAM (light implementation) testImplementation("software.amazon.awssdk:ec2:2.25.2") testImplementation("software.amazon.awssdk:secretsmanager:2.25.2") - testImplementation("software.amazon.awssdk:sts:2.25.2") - testImplementation("org.testcontainers:testcontainers:1.19.5") + testImplementation("software.amazon.awssdk:sts:2.25.17") + testImplementation("org.testcontainers:testcontainers:1.19.7") testImplementation("org.testcontainers:mysql:1.19.7") - testImplementation("org.testcontainers:postgresql:1.19.5") - testImplementation("org.testcontainers:mariadb:1.19.5") - testImplementation("org.testcontainers:junit-jupiter:1.19.5") - testImplementation("org.testcontainers:toxiproxy:1.19.5") + testImplementation("org.testcontainers:postgresql:1.19.7") + testImplementation("org.testcontainers:mariadb:1.19.7") + testImplementation("org.testcontainers:junit-jupiter:1.19.7") + testImplementation("org.testcontainers:toxiproxy:1.19.7") testImplementation("eu.rekawek.toxiproxy:toxiproxy-java:2.1.7") testImplementation("org.apache.poi:poi-ooxml:5.2.5") testImplementation("org.slf4j:slf4j-simple:2.0.12") testImplementation("com.fasterxml.jackson.core:jackson-databind:2.16.1") testImplementation("com.amazonaws:aws-xray-recorder-sdk-core:2.15.0") - testImplementation("io.opentelemetry:opentelemetry-api:1.35.0") + testImplementation("io.opentelemetry:opentelemetry-api:1.36.0") testImplementation("io.opentelemetry:opentelemetry-sdk:1.35.0") testImplementation("io.opentelemetry:opentelemetry-sdk-metrics:1.35.0") - testImplementation("io.opentelemetry:opentelemetry-exporter-otlp:1.35.0") + testImplementation("io.opentelemetry:opentelemetry-exporter-otlp:1.36.0") } repositories { diff --git a/wrapper/src/main/java/software/amazon/jdbc/HostSpec.java b/wrapper/src/main/java/software/amazon/jdbc/HostSpec.java index 736daa85f..2904095ba 100644 --- a/wrapper/src/main/java/software/amazon/jdbc/HostSpec.java +++ b/wrapper/src/main/java/software/amazon/jdbc/HostSpec.java @@ -25,6 +25,7 @@ import java.util.concurrent.ConcurrentHashMap; import software.amazon.jdbc.hostavailability.HostAvailability; import software.amazon.jdbc.hostavailability.HostAvailabilityStrategy; +import software.amazon.jdbc.util.StringUtils; /** * An object representing connection info for a given host. Modifiable fields are thread-safe to support sharing this @@ -150,8 +151,10 @@ public void addAlias(final String... alias) { } Arrays.asList(alias).forEach(x -> { - this.aliases.add(x); - this.allAliases.add(x); + if (!StringUtils.isNullOrEmpty(x)) { + this.aliases.add(x); + this.allAliases.add(x); + } }); } @@ -160,8 +163,10 @@ public void removeAlias(final String... alias) { return; } Arrays.asList(alias).forEach(x -> { - this.aliases.remove(x); - this.allAliases.remove(x); + if (!StringUtils.isNullOrEmpty(x)) { + this.aliases.remove(x); + this.allAliases.remove(x); + } }); } diff --git a/wrapper/src/main/java/software/amazon/jdbc/hostlistprovider/RdsHostListProvider.java b/wrapper/src/main/java/software/amazon/jdbc/hostlistprovider/RdsHostListProvider.java index 6f0e6900b..50ddc1be3 100644 --- a/wrapper/src/main/java/software/amazon/jdbc/hostlistprovider/RdsHostListProvider.java +++ b/wrapper/src/main/java/software/amazon/jdbc/hostlistprovider/RdsHostListProvider.java @@ -648,17 +648,38 @@ public HostSpec identifyConnection(Connection connection) throws SQLException { if (resultSet.next()) { final String instanceName = resultSet.getString(1); - final List topology = this.refresh(); + List topology = this.refresh(connection); + + boolean isForcedRefresh = false; + if (topology == null) { + topology = this.forceRefresh(connection); + isForcedRefresh = true; + } if (topology == null) { return null; } - return topology + HostSpec foundHost = topology .stream() .filter(host -> Objects.equals(instanceName, host.getHostId())) .findAny() .orElse(null); + + if (foundHost == null && !isForcedRefresh) { + topology = this.forceRefresh(connection); + if (topology == null) { + return null; + } + + foundHost = topology + .stream() + .filter(host -> Objects.equals(instanceName, host.getHostId())) + .findAny() + .orElse(null); + } + + return foundHost; } } catch (final SQLException e) { throw new SQLException(Messages.get("RdsHostListProvider.errorIdentifyConnection"), e); diff --git a/wrapper/src/main/java/software/amazon/jdbc/plugin/failover/FailoverConnectionPlugin.java b/wrapper/src/main/java/software/amazon/jdbc/plugin/failover/FailoverConnectionPlugin.java index 22ce339ff..2cd76f5ed 100644 --- a/wrapper/src/main/java/software/amazon/jdbc/plugin/failover/FailoverConnectionPlugin.java +++ b/wrapper/src/main/java/software/amazon/jdbc/plugin/failover/FailoverConnectionPlugin.java @@ -610,7 +610,7 @@ protected void failoverReader(final HostSpec failedHostSpec) throws SQLException this.pluginService.getCurrentHostSpec().removeAlias(oldAliases.toArray(new String[]{})); updateTopology(true); - LOGGER.fine( + LOGGER.info( () -> Messages.get( "Failover.establishedConnection", new Object[]{this.pluginService.getCurrentHostSpec()})); @@ -642,7 +642,7 @@ protected void failoverWriter() throws SQLException { this.failoverWriterTriggeredCounter.inc(); try { - LOGGER.fine(() -> Messages.get("Failover.startWriterFailover")); + LOGGER.info(() -> Messages.get("Failover.startWriterFailover")); final WriterFailoverResult failoverResult = this.writerFailoverHandler.failover(this.pluginService.getHosts()); if (failoverResult != null) { final SQLException exception = failoverResult.getException(); diff --git a/wrapper/src/main/java/software/amazon/jdbc/util/RdsUtils.java b/wrapper/src/main/java/software/amazon/jdbc/util/RdsUtils.java index 951ca2a96..ffd2a6f54 100644 --- a/wrapper/src/main/java/software/amazon/jdbc/util/RdsUtils.java +++ b/wrapper/src/main/java/software/amazon/jdbc/util/RdsUtils.java @@ -141,7 +141,7 @@ public boolean isRdsDns(final String host) { } public boolean isRdsInstance(final String host) { - return getDnsGroup(host) == null; + return getDnsGroup(host) == null && isRdsDns(host); } public boolean isRdsProxyDns(final String host) { diff --git a/wrapper/src/test/java/integration/host/TestEnvironment.java b/wrapper/src/test/java/integration/host/TestEnvironment.java index 7f8c81726..aa78141bd 100644 --- a/wrapper/src/test/java/integration/host/TestEnvironment.java +++ b/wrapper/src/test/java/integration/host/TestEnvironment.java @@ -494,17 +494,18 @@ private static String getAuroraDbEngineVersion(TestEnvironment env) { default: throw new NotImplementedException(request.getDatabaseEngine().toString()); } - return findAuroraDbEngineVersion(env, engineName, systemPropertyVersion.toLowerCase()); + return findAuroraDbEngineVersion(env, engineName, systemPropertyVersion); } private static String findAuroraDbEngineVersion( TestEnvironment env, String engineName, String systemPropertyVersion) { - if (systemPropertyVersion == null) { + + if (StringUtils.isNullOrEmpty(systemPropertyVersion)) { return env.auroraUtil.getLTSVersion(engineName); } - switch (systemPropertyVersion) { + switch (systemPropertyVersion.toLowerCase()) { case "lts": return env.auroraUtil.getLTSVersion(engineName); case "latest": diff --git a/wrapper/src/test/java/software/amazon/jdbc/hostlistprovider/RdsHostListProviderTest.java b/wrapper/src/test/java/software/amazon/jdbc/hostlistprovider/RdsHostListProviderTest.java index ff17abcb7..6459b79dc 100644 --- a/wrapper/src/test/java/software/amazon/jdbc/hostlistprovider/RdsHostListProviderTest.java +++ b/wrapper/src/test/java/software/amazon/jdbc/hostlistprovider/RdsHostListProviderTest.java @@ -473,7 +473,8 @@ void testIdentifyConnectionNullTopology() throws SQLException { when(mockResultSet.next()).thenReturn(true); when(mockResultSet.getString(eq(1))).thenReturn("instance-1"); - when(rdsHostListProvider.refresh(eq(mockConnection))).thenReturn(null); + doReturn(null).when(rdsHostListProvider).refresh(mockConnection); + doReturn(null).when(rdsHostListProvider).forceRefresh(mockConnection); assertNull(rdsHostListProvider.identifyConnection(mockConnection)); } @@ -492,7 +493,8 @@ void testIdentifyConnectionHostNotInTopology() throws SQLException { "jdbc:someprotocol://url")); when(mockResultSet.next()).thenReturn(true); when(mockResultSet.getString(eq(1))).thenReturn("instance-1"); - when(rdsHostListProvider.refresh(eq(mockConnection))).thenReturn(cachedTopology); + doReturn(cachedTopology).when(rdsHostListProvider).refresh(mockConnection); + doReturn(cachedTopology).when(rdsHostListProvider).forceRefresh(mockConnection); assertNull(rdsHostListProvider.identifyConnection(mockConnection)); } @@ -512,7 +514,8 @@ void testIdentifyConnectionHostInTopology() throws SQLException { "jdbc:someprotocol://url")); when(mockResultSet.next()).thenReturn(true); when(mockResultSet.getString(eq(1))).thenReturn("instance-a-1"); - when(rdsHostListProvider.refresh()).thenReturn(cachedTopology); + doReturn(cachedTopology).when(rdsHostListProvider).refresh(mockConnection); + doReturn(cachedTopology).when(rdsHostListProvider).forceRefresh(mockConnection); final HostSpec actual = rdsHostListProvider.identifyConnection(mockConnection); assertEquals("instance-a-1.xyz.us-east-2.rds.amazonaws.com", actual.getHost()); diff --git a/wrapper/src/test/java/software/amazon/jdbc/hostlistprovider/RdsMultiAzDbClusterListProviderTest.java b/wrapper/src/test/java/software/amazon/jdbc/hostlistprovider/RdsMultiAzDbClusterListProviderTest.java index b5bca63b5..b70b257bd 100644 --- a/wrapper/src/test/java/software/amazon/jdbc/hostlistprovider/RdsMultiAzDbClusterListProviderTest.java +++ b/wrapper/src/test/java/software/amazon/jdbc/hostlistprovider/RdsMultiAzDbClusterListProviderTest.java @@ -46,6 +46,7 @@ import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.Captor; @@ -454,7 +455,8 @@ void testIdentifyConnectionNullTopology() throws SQLException { when(mockResultSet.next()).thenReturn(true); when(mockResultSet.getString(eq(1))).thenReturn("instance-1"); - when(rdsMazDbClusterHostListProvider.refresh(eq(mockConnection))).thenReturn(null); + doReturn(null).when(rdsMazDbClusterHostListProvider).refresh(mockConnection); + doReturn(null).when(rdsMazDbClusterHostListProvider).forceRefresh(mockConnection); assertNull(rdsMazDbClusterHostListProvider.identifyConnection(mockConnection)); } @@ -473,7 +475,8 @@ void testIdentifyConnectionHostNotInTopology() throws SQLException { "jdbc:someprotocol://url")); when(mockResultSet.next()).thenReturn(true); when(mockResultSet.getString(eq(1))).thenReturn("instance-1"); - when(rdsMazDbClusterHostListProvider.refresh(eq(mockConnection))).thenReturn(cachedTopology); + doReturn(cachedTopology).when(rdsMazDbClusterHostListProvider).refresh(mockConnection); + doReturn(cachedTopology).when(rdsMazDbClusterHostListProvider).forceRefresh(mockConnection); assertNull(rdsMazDbClusterHostListProvider.identifyConnection(mockConnection)); } @@ -482,10 +485,10 @@ void testIdentifyConnectionHostNotInTopology() throws SQLException { void testIdentifyConnectionHostInTopology() throws SQLException { final HostSpec expectedHost = new HostSpecBuilder(new SimpleHostAvailabilityStrategy()) .host("instance-a-1.xyz.us-east-2.rds.amazonaws.com") + .hostId("instance-a-1") .port(HostSpec.NO_PORT) .role(HostRole.WRITER) .build(); - expectedHost.setHostId("instance-a-1"); final List cachedTopology = Collections.singletonList(expectedHost); rdsMazDbClusterHostListProvider = Mockito.spy(getRdsMazDbClusterHostListProvider( @@ -493,7 +496,8 @@ void testIdentifyConnectionHostInTopology() throws SQLException { "jdbc:someprotocol://url")); when(mockResultSet.next()).thenReturn(true); when(mockResultSet.getString(eq(1))).thenReturn("instance-a-1"); - when(rdsMazDbClusterHostListProvider.refresh()).thenReturn(cachedTopology); + doReturn(cachedTopology).when(rdsMazDbClusterHostListProvider).refresh(mockConnection); + doReturn(cachedTopology).when(rdsMazDbClusterHostListProvider).forceRefresh(mockConnection); final HostSpec actual = rdsMazDbClusterHostListProvider.identifyConnection(mockConnection); assertEquals("instance-a-1.xyz.us-east-2.rds.amazonaws.com", actual.getHost());