Skip to content

Commit b32bb52

Browse files
author
Shintaro Onuma
committed
Parse S3 VPC endpoints for the region
1 parent 04e447c commit b32bb52

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/DefaultS3ClientFactory.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.io.IOException;
2222
import java.net.URI;
2323
import java.net.URISyntaxException;
24+
import java.util.regex.Matcher;
25+
import java.util.regex.Pattern;
2426

2527
import org.apache.hadoop.classification.VisibleForTesting;
2628
import org.apache.hadoop.fs.s3a.impl.AWSClientConfig;
@@ -82,6 +84,9 @@ public class DefaultS3ClientFactory extends Configured
8284

8385
private static final String S3_SERVICE_NAME = "s3";
8486

87+
private static final Pattern VPC_ENDPOINT_PATTERN =
88+
Pattern.compile("^(?:.+\\.)?([a-z0-9-]+)\\.vpce\\.");
89+
8590
/**
8691
* Subclasses refer to this.
8792
*/
@@ -361,6 +366,13 @@ private static URI getS3Endpoint(String endpoint, final Configuration conf) {
361366
*/
362367
private static Region getS3RegionFromEndpoint(String endpoint) {
363368

369+
// S3 VPC endpoint parsing
370+
Matcher matcher = VPC_ENDPOINT_PATTERN.matcher(endpoint);
371+
if(matcher.find()) {
372+
LOG.debug("Endpoint {} is vpc endpoint; parsing", endpoint);
373+
return Region.of(matcher.group(1));
374+
}
375+
364376
if(!endpoint.endsWith(CENTRAL_ENDPOINT)) {
365377
LOG.debug("Endpoint {} is not the default; parsing", endpoint);
366378
return AwsHostNameUtils.parseSigningRegion(endpoint, S3_SERVICE_NAME).orElse(null);

hadoop-tools/hadoop-aws/src/test/java/org/apache/hadoop/fs/s3a/ITestS3AEndpointRegion.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ public class ITestS3AEndpointRegion extends AbstractS3ATestBase {
8282

8383
private static final String VPC_ENDPOINT = "vpce-1a2b3c4d-5e6f.s3.us-west-2.vpce.amazonaws.com";
8484

85+
private static final String CN_VPC_ENDPOINT = "vpce-1a2b3c4d-5e6f.s3.cn-northwest-1.vpce.amazonaws.com.cn";
86+
8587
public static final String EXCEPTION_THROWN_BY_INTERCEPTOR = "Exception thrown by interceptor";
8688

8789
/**
@@ -247,7 +249,6 @@ public void testWithGovCloudEndpoint() throws Throwable {
247249
}
248250

249251
@Test
250-
@Ignore("Pending HADOOP-18938. S3A region logic to handle vpce and non standard endpoints")
251252
public void testWithVPCE() throws Throwable {
252253
describe("Test with vpc endpoint");
253254
Configuration conf = getConfiguration();
@@ -257,6 +258,16 @@ public void testWithVPCE() throws Throwable {
257258
expectInterceptorException(client);
258259
}
259260

261+
@Test
262+
public void testWithChinaVPCE() throws Throwable {
263+
describe("Test with china vpc endpoint");
264+
Configuration conf = getConfiguration();
265+
266+
S3Client client = createS3Client(conf, CN_VPC_ENDPOINT, null, CN_NORTHWEST_1, false);
267+
268+
expectInterceptorException(client);
269+
}
270+
260271
private final class RegionInterceptor implements ExecutionInterceptor {
261272
private final String endpoint;
262273
private final String region;

0 commit comments

Comments
 (0)