-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix missing AWS region in S3 operations #9546
Conversation
if (locationConstraint == BucketLocationConstraint.UNKNOWN_TO_SDK_VERSION) { | ||
Logger.getLogger("S3-BucketLocator").fine("AWS returned an unknown location constraint."); | ||
return null; | ||
} | ||
|
||
var inferredRegion = Region.of(locationConstraint.toString()); | ||
boolean isKnown = Region.regions().contains(inferredRegion); | ||
if (isKnown) { | ||
return inferredRegion; | ||
} else { | ||
Logger.getLogger("S3-BucketLocator").fine("AWS returned a location constraint that cannot be mapped to a known region: " + locationConstraint); | ||
return null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that sometimes getBucketLocation
may not be able to find out the true bucket location.
In such case, we will fall back to the region set in credentials which seems our best bet - as the user can always amend that region to be right. If the region is wrong, the user will be getting failures like: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.
(message coming from AWS SDK)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The AWS docs seem to suggest using HeadBucket
instead of GetBucketLocation
but I could not get it to work, because ironically HeadBucket
fails with the above error:
((S3_Error.Error 'The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.' 'PermanentRedirect'))
even on the same configuration that allows GetBucketLocation
to work...
The patch was
Index: std-bits/aws/src/main/java/org/enso/aws/BucketLocator.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/std-bits/aws/src/main/java/org/enso/aws/BucketLocator.java b/std-bits/aws/src/main/java/org/enso/aws/BucketLocator.java
--- a/std-bits/aws/src/main/java/org/enso/aws/BucketLocator.java (revision fc80d4d118f4e2797a281b95ba96ffae68afe26a)
+++ b/std-bits/aws/src/main/java/org/enso/aws/BucketLocator.java (date 1711457551132)
@@ -1,9 +1,10 @@
package org.enso.aws;
import software.amazon.awssdk.regions.Region;
-import software.amazon.awssdk.services.s3.model.BucketLocationConstraint;
+import software.amazon.awssdk.services.s3.model.HeadBucketResponse;
import java.util.HashMap;
+import java.util.Optional;
import java.util.logging.Logger;
/**
@@ -35,25 +36,9 @@
DefaultRegionProvider defaultRegionProvider = new DefaultRegionProvider(null, Region.US_EAST_1);
var clientBuilder = new ClientBuilder(associatedCredential, defaultRegionProvider.getRegion());
try (var client = clientBuilder.buildGlobalS3Client()) {
- BucketLocationConstraint locationConstraint = client.getBucketLocation(builder -> builder.bucket(bucketName)).locationConstraint();
- if (locationConstraint == null) {
- // Weird edge case: documentation says that buckets in region us-east-1 return null
- return Region.US_EAST_1;
- }
-
- if (locationConstraint == BucketLocationConstraint.UNKNOWN_TO_SDK_VERSION) {
- Logger.getLogger("S3-BucketLocator").fine("AWS returned an unknown location constraint.");
- return null;
- }
-
- var inferredRegion = Region.of(locationConstraint.toString());
- boolean isKnown = Region.regions().contains(inferredRegion);
- if (isKnown) {
- return inferredRegion;
- } else {
- Logger.getLogger("S3-BucketLocator").fine("AWS returned a location constraint that cannot be mapped to a known region: " + locationConstraint);
- return null;
- }
+ HeadBucketResponse response = client.headBucket(builder -> builder.bucket(bucketName));
+ Optional<String> regionId = response.sdkHttpResponse().firstMatchingHeader("x-amz-bucket-region");
+ return regionId.map(Region::of).orElse(null);
} catch (Exception e) {
Logger.getLogger("S3-BucketLocator").fine("Failed to locate bucket " + bucketName + ": " + e.getMessage());
return null;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After all I figured out we can extract the region from the S3Exception
that happens when HeadBucket
fails, so I switched to this strategy.
I thought to keep the legacy strategy as a fallback just in case - if the headers ever disappear from the exception for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OTOH I'm wondering if that's not introducing unnecessary maintenance burden.
What do you'all think? Shall I keep the fallback, or shall we remove it, knowing that we can add it if we ever run into issues with the current way of fetching regions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think any harm leaving the fallback - my guess is it will never be fired but not a big burden and nice to have the fallback if response format changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably remove the index.html
symlink that points to a nonexistent file (causing issues when formatting)
fc80d4d
to
e139f12
Compare
7799140
to
08f6da2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good - couple of minor suggestions.
distribution/lib/Standard/AWS/0.0.0-dev/src/AWS_Credential.enso
Outdated
Show resolved
Hide resolved
# Conflicts: # app/ide-desktop/lib/dashboard/src/index.html
Pull Request Description
AWS_
config, thus ensuring that the tested setups work in a clean environment.AWS_Region
widget based on autoscoping.AWS_Credential.profile_names
crashing if no AWS config was found. Now it returns no profiles if not found. Added a regression test.Important Notes
Checklist
Please ensure that the following checklist has been satisfied before submitting the PR:
Scala,
Java,
and
Rust
style guides. In case you are using a language not listed above, follow the Rust style guide.
./run ide build
.