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 cc17096e5..aed5f83d7 100644 --- a/wrapper/src/main/java/software/amazon/jdbc/hostlistprovider/RdsHostListProvider.java +++ b/wrapper/src/main/java/software/amazon/jdbc/hostlistprovider/RdsHostListProvider.java @@ -447,7 +447,7 @@ protected void validateHostPatternSetting(final String hostPattern) { } final RdsUrlType rdsUrlType = rdsHelper.identifyRdsType(hostPattern); - if (rdsUrlType == RdsUrlType.RDS_PROXY) { + if (rdsUrlType == RdsUrlType.RDS_PROXY || rdsUrlType == RdsUrlType.RDS_PROXY_ENDPOINT) { // "An RDS Proxy url can't be used as the 'clusterInstanceHostPattern' configuration setting." final String message = Messages.get("RdsHostListProvider.clusterInstanceHostPatternNotSupportedForRDSProxy"); 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 ef2f95550..25ce77ecb 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 @@ -388,6 +388,7 @@ private boolean isNodeStillValid(final String node, final Map.global-.global.rds.amazonaws.com + // Example: test-global-db-name.global-123456789012.global.rds.amazonaws.com + // + // + // RDS Proxy + // RDS Proxy Endpoint: .proxy-..rds.amazonaws.com + // Example: test-rds-proxy-name.proxy-123456789012.us-east-2.rds.amazonaws.com + // + // RDS Proxy Custom Endpoint: .endpoint.proxy-..rds.amazonaws.com + // Example: test-custom-endpoint-name.endpoint.proxy-123456789012.us-east-2.rds.amazonaws.com private static final Pattern AURORA_DNS_PATTERN = Pattern.compile( @@ -184,6 +198,30 @@ public class RdsUtils { + "(?[a-zA-Z0-9]+\\.global\\.rds\\.amazonaws\\.com\\.?)$", Pattern.CASE_INSENSITIVE); + private static final Pattern RDS_PROXY_ENDPOINT_DNS_PATTERN = + Pattern.compile( + "^(?.+)\\.endpoint\\." + + "(?proxy-)?" + + "(?[a-zA-Z0-9]+\\.(?[a-zA-Z0-9\\-]+)" + + "\\.rds\\.amazonaws\\.com\\.?)$", + Pattern.CASE_INSENSITIVE); + + private static final Pattern RDS_PROXY_ENDPOINT_CHINA_DNS_PATTERN = + Pattern.compile( + "^(?.+)\\.endpoint\\." + + "(?proxy-)+" + + "(?[a-zA-Z0-9]+\\.rds\\.(?[a-zA-Z0-9\\-]+)" + + "\\.amazonaws\\.com\\.cn\\.?)$", + Pattern.CASE_INSENSITIVE); + + private static final Pattern RDS_PROXY_ENDPOINT_OLD_CHINA_DNS_PATTERN = + Pattern.compile( + "^(?.+)\\.endpoint\\." + + "(?proxy-)?" + + "(?[a-zA-Z0-9]+\\.(?[a-zA-Z0-9\\-]+)" + + "\\.rds\\.amazonaws\\.com\\.cn\\.?)$", + Pattern.CASE_INSENSITIVE); + private static final Map cachedPatterns = new ConcurrentHashMap<>(); private static final Map cachedDnsPatterns = new ConcurrentHashMap<>(); @@ -225,6 +263,21 @@ public boolean isRdsProxyDns(final String host) { return dnsGroup != null && dnsGroup.startsWith("proxy-"); } + public boolean isRdsProxyEndpointDns(final String host) { + final String preparedHost = getPreparedHost(host); + if (StringUtils.isNullOrEmpty(preparedHost)) { + return false; + } + + final Matcher matcher = cacheMatcher(preparedHost, + RDS_PROXY_ENDPOINT_DNS_PATTERN, RDS_PROXY_ENDPOINT_CHINA_DNS_PATTERN, RDS_PROXY_ENDPOINT_OLD_CHINA_DNS_PATTERN); + if (getRegexGroup(matcher, DNS_GROUP) != null) { + return getRegexGroup(matcher, INSTANCE_GROUP) != null; + } + + return false; + } + public @Nullable String getRdsClusterId(final String host) { final String preparedHost = getPreparedHost(host); if (StringUtils.isNullOrEmpty(preparedHost)) { @@ -372,6 +425,8 @@ public RdsUrlType identifyRdsType(final String host) { return RdsUrlType.RDS_AURORA_LIMITLESS_DB_SHARD_GROUP; } else if (isRdsProxyDns(host)) { return RdsUrlType.RDS_PROXY; + } else if (isRdsProxyEndpointDns(host)) { + return RdsUrlType.RDS_PROXY_ENDPOINT; } else if (isRdsDns(host)) { return RdsUrlType.RDS_INSTANCE; } else { diff --git a/wrapper/src/test/java/software/amazon/jdbc/util/RdsUtilsTests.java b/wrapper/src/test/java/software/amazon/jdbc/util/RdsUtilsTests.java index 05ce83b7b..9938dc2e6 100644 --- a/wrapper/src/test/java/software/amazon/jdbc/util/RdsUtilsTests.java +++ b/wrapper/src/test/java/software/amazon/jdbc/util/RdsUtilsTests.java @@ -37,6 +37,8 @@ public class RdsUtilsTests { "instance-test-name.XYZ.us-east-2.rds.amazonaws.com"; private static final String usEastRegionProxy = "proxy-test-name.proxy-XYZ.us-east-2.rds.amazonaws.com"; + private static final String usEastRegionProxyEndpoint = + "endpoint-test-name.endpoint.proxy-XYZ.us-east-2.rds.amazonaws.com"; private static final String usEastRegionCustomDomain = "custom-test-name.cluster-custom-XYZ.us-east-2.rds.amazonaws.com"; private static final String usEastRegionLimitlessDbShardGroup = @@ -132,6 +134,7 @@ public void testIsRdsDns() { assertTrue(target.isRdsDns(usEastRegionClusterReadOnly)); assertTrue(target.isRdsDns(usEastRegionInstance)); assertTrue(target.isRdsDns(usEastRegionProxy)); + assertTrue(target.isRdsDns(usEastRegionProxyEndpoint)); assertTrue(target.isRdsDns(usEastRegionCustomDomain)); assertFalse(target.isRdsDns(usEastRegionElbUrl)); assertFalse(target.isRdsDns(usEastRegionElbUrlTrailingDot)); @@ -221,6 +224,7 @@ public void testIsRdsClusterDns() { assertTrue(target.isRdsClusterDns(usEastRegionClusterReadOnly)); assertFalse(target.isRdsClusterDns(usEastRegionInstance)); assertFalse(target.isRdsClusterDns(usEastRegionProxy)); + assertFalse(target.isRdsClusterDns(usEastRegionProxyEndpoint)); assertFalse(target.isRdsClusterDns(usEastRegionCustomDomain)); assertFalse(target.isRdsClusterDns(usEastRegionElbUrl)); assertFalse(target.isRdsClusterDns(usEastRegionLimitlessDbShardGroup)); @@ -260,6 +264,7 @@ public void testIsWriterClusterDns() { assertFalse(target.isWriterClusterDns(usEastRegionClusterReadOnly)); assertFalse(target.isWriterClusterDns(usEastRegionInstance)); assertFalse(target.isWriterClusterDns(usEastRegionProxy)); + assertFalse(target.isWriterClusterDns(usEastRegionProxyEndpoint)); assertFalse(target.isWriterClusterDns(usEastRegionCustomDomain)); assertFalse(target.isWriterClusterDns(usEastRegionElbUrl)); assertFalse(target.isWriterClusterDns(usEastRegionLimitlessDbShardGroup)); @@ -299,6 +304,7 @@ public void testIsReaderClusterDns() { assertTrue(target.isReaderClusterDns(usEastRegionClusterReadOnly)); assertFalse(target.isReaderClusterDns(usEastRegionInstance)); assertFalse(target.isReaderClusterDns(usEastRegionProxy)); + assertFalse(target.isReaderClusterDns(usEastRegionProxyEndpoint)); assertFalse(target.isReaderClusterDns(usEastRegionCustomDomain)); assertFalse(target.isReaderClusterDns(usEastRegionElbUrl)); assertFalse(target.isReaderClusterDns(usEastRegionLimitlessDbShardGroup)); @@ -338,6 +344,7 @@ public void testIsLimitlessDbShardGroupDns() { assertFalse(target.isLimitlessDbShardGroupDns(usEastRegionClusterReadOnly)); assertFalse(target.isLimitlessDbShardGroupDns(usEastRegionInstance)); assertFalse(target.isLimitlessDbShardGroupDns(usEastRegionProxy)); + assertFalse(target.isLimitlessDbShardGroupDns(usEastRegionProxyEndpoint)); assertFalse(target.isLimitlessDbShardGroupDns(usEastRegionCustomDomain)); assertFalse(target.isLimitlessDbShardGroupDns(usEastRegionElbUrl)); assertTrue(target.isLimitlessDbShardGroupDns(usEastRegionLimitlessDbShardGroup)); @@ -378,6 +385,7 @@ public void testGetRdsRegion() { assertEquals(expectedHostPattern, target.getRdsRegion(usEastRegionClusterReadOnly)); assertEquals(expectedHostPattern, target.getRdsRegion(usEastRegionInstance)); assertEquals(expectedHostPattern, target.getRdsRegion(usEastRegionProxy)); + assertEquals(expectedHostPattern, target.getRdsRegion(usEastRegionProxyEndpoint)); assertEquals(expectedHostPattern, target.getRdsRegion(usEastRegionCustomDomain)); assertEquals(expectedHostPattern, target.getRdsRegion(usEastRegionElbUrl)); assertEquals(expectedHostPattern, target.getRdsRegion(usEastRegionLimitlessDbShardGroup)); @@ -423,6 +431,12 @@ public void testIsGlobalDbWriterClusterDns() { assertTrue(target.isGlobalDbWriterClusterDns(globalDbWriterCluster)); } + @Test + public void testisRdsProxyEndpointDns() { + assertFalse(target.isRdsProxyEndpointDns(usEastRegionProxy)); + assertTrue(target.isRdsProxyEndpointDns(usEastRegionProxyEndpoint)); + } + @Test public void testBrokenPathsHostPattern() { final String incorrectChinaHostPattern = "?.rds.cn-northwest-1.rds.amazonaws.com.cn";