Skip to content

Instantly share code, notes, and snippets.

@jameskyle
Last active June 8, 2023 22:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jameskyle/30a88b63ab90ac2de2f3b5c3f3565cf3 to your computer and use it in GitHub Desktop.
Save jameskyle/30a88b63ab90ac2de2f3b5c3f3565cf3 to your computer and use it in GitHub Desktop.
Dynamic bucket lookup and cross region copy object support.
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider
import software.amazon.awssdk.regions.Region
import software.amazon.awssdk.services.s3.S3Client
import software.amazon.awssdk.services.s3.model.{S3Exception,CopyObjectRequest,CopyObjectResponse,HeadBucketRequest}
import scala.util.{Try,Success,Failure}
/**
Cross region copy object example with region code discovery for a bucket.
**/
val defaultRegion = Region.US_WEST_2
val creds = ProfileCredentialsProvider.builder().build()
// I'd probably do a warm up where I collected all configs and iterated over them, creating a client for a new region when not found.
val clients = Map(
Region.US_WEST_2 -> S3Client.builder().region(Region.US_WEST_2).credentialsProvider(creds).build(),
Region.US_EAST_1 -> S3Client.builder().region(Region.US_EAST_1).credentialsProvider(creds).build(),
)
val defaultS3 = clients(Region.US_WEST_2)
val fromBucket = "source-bucket"
val sourceKey = "s3-testing/testfile.txt"
val toBucket = "destination-bucket"
val destKey = "s3-testing/testfile-copied.txt"
val copyReq = CopyObjectRequest.builder()
.sourceBucket(fromBucket)
.sourceKey(sourceKey)
.destinationBucket(toBucket)
.destinationKey(destKey)
.build()
val regionReq = HeadBucketRequest.builder().bucket(toBucket).build()
// feel like there ought to be a constant somewhere for the header region value
// so wouldn't have to use string literals.
val region = Try(defaultS3.headBucket(regionReq)) match {
Success(r) => r.sdkHttpResponse().headers().get("x-amz-bucket-region").get(0)
Failure(e) => e.asInstanceOf[S3Exception].awsErrorDetails().sdkHttpResponse().headers().get("x-amz-bucket-region").get(0)
}
val resp = clients(Region.of(region)).copyObject(copyReq)
// handle response
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment