hq/app/aws/s3/S3.scala (51 lines of code) (raw):

package aws.s3 import model.{BucketEncryptionResponse, BucketNotFound, Encrypted, NotEncrypted} import utils.attempt.{Attempt, FailedAttempt, Failure} import scala.concurrent.ExecutionContext import scala.io.BufferedSource import scala.util.control.NonFatal import software.amazon.awssdk.services.s3.S3Client import software.amazon.awssdk.services.s3.model.S3Exception import software.amazon.awssdk.services.s3.model.{GetObjectRequest, GetBucketEncryptionRequest} object S3 { def getS3Object(s3Client: S3Client, bucket: String, key: String): Attempt[BufferedSource] = { val request = GetObjectRequest.builder().bucket(bucket).key(key).build() try { Attempt.Right { scala.io.Source .fromInputStream(s3Client.getObject(request)) } } catch { case NonFatal(e) => Attempt.Left(FailedAttempt(Failure( s"Unable to get S3 object for bucket $bucket and key $key", "Failed to fetch an S3 object", 500, throwable = Some(e) ))) } } def getBucketEncryption(client: S3Client, bucketName: String)(implicit ec: ExecutionContext): Attempt[BucketEncryptionResponse] = { val request = GetBucketEncryptionRequest.builder().bucket(bucketName).build() try { Attempt.Right { Option( client.getBucketEncryption(request).serverSideEncryptionConfiguration ).fold[BucketEncryptionResponse](NotEncrypted)(_ => Encrypted) } } catch { // If there is no bucket encryption, AWS returns an error... // Assume bucket is not encrypted if we receive the specific error case e: S3Exception if e.getMessage.contains("ServerSideEncryptionConfigurationNotFoundError") => Attempt.Right(NotEncrypted) case e: S3Exception if e.getMessage.contains("NoSuchBucket") => Attempt.Right(BucketNotFound) case NonFatal(e) => Attempt.Left(FailedAttempt(Failure( s"unable to get S3 bucket encryption status for bucket $bucketName", "Encryption status for this bucket was not found.", 500, context = Some(e.getMessage), throwable = Some(e) ))) } } }