package com.bazaarvoice.emodb.blob.db.s3; import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider; import com.amazonaws.client.builder.AwsClientBuilder; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.bazaarvoice.emodb.blob.db.s3.config.S3BucketConfiguration; import com.bazaarvoice.emodb.blob.db.s3.config.S3ClientConfiguration; import com.bazaarvoice.emodb.blob.db.s3.config.S3Configuration; import javax.annotation.Nullable; import javax.inject.Inject; import java.time.Clock; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; public class AmazonS3Provider { private final Map<String, AmazonS3> _s3BucketNamesToS3Clients; @Inject public AmazonS3Provider(@Nullable S3Configuration s3Configuration, Clock clock) { _s3BucketNamesToS3Clients = getS3BucketNamesToS3Clients(s3Configuration, clock); } private Map<String, AmazonS3> getS3BucketNamesToS3Clients(S3Configuration s3Configuration, Clock clock) { // TODO remove condition in EMO-7107 if (null != s3Configuration && null != s3Configuration.getS3BucketConfigurations()) { return s3Configuration.getS3BucketConfigurations().stream() .collect(Collectors.toMap( s3BucketConfiguration -> s3BucketConfiguration.getName(), s3BucketConfiguration -> getAmazonS3(s3BucketConfiguration, clock)) ); } else { return new HashMap<>(); } } public AmazonS3 get(String bucket) { return _s3BucketNamesToS3Clients.get(bucket); } Map<String, AmazonS3> getS3BucketNamesToS3Clients() { return _s3BucketNamesToS3Clients; } private static AmazonS3 getAmazonS3(final S3BucketConfiguration s3BucketConfiguration, Clock clock) { AmazonS3ClientBuilder amazonS3ClientBuilder = AmazonS3ClientBuilder.standard() .withCredentials(getAwsCredentialsProvider(s3BucketConfiguration)) .withAccelerateModeEnabled(s3BucketConfiguration.getAccelerateModeEnabled()); S3ClientConfiguration.RateLimitConfiguration rateLimitConfiguration = new S3ClientConfiguration.RateLimitConfiguration(); if (null != s3BucketConfiguration.getRegion()) { amazonS3ClientBuilder .withRegion(Regions.fromName(s3BucketConfiguration.getRegion())); } else if (null != s3BucketConfiguration.getS3ClientConfiguration()) { S3ClientConfiguration.EndpointConfiguration endpointConfiguration = s3BucketConfiguration.getS3ClientConfiguration().getEndpointConfiguration(); amazonS3ClientBuilder .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endpointConfiguration.getServiceEndpoint(), endpointConfiguration.getSigningRegion())); rateLimitConfiguration = s3BucketConfiguration.getS3ClientConfiguration().getRateLimitConfiguration(); } AmazonS3 amazonS3 = amazonS3ClientBuilder .build(); return new S3RateLimiter(clock, rateLimitConfiguration) .rateLimit(amazonS3); } private static AWSCredentialsProvider getAwsCredentialsProvider(final S3BucketConfiguration s3BucketConfiguration) { final AWSCredentialsProvider credentialsProvider; if (null != s3BucketConfiguration.getRoleArn()) { final STSAssumeRoleSessionCredentialsProvider.Builder credentialsProviderBuilder = new STSAssumeRoleSessionCredentialsProvider.Builder(s3BucketConfiguration.getRoleArn(), s3BucketConfiguration.getName() + "session"); if (null != s3BucketConfiguration.getRoleExternalId()) { credentialsProviderBuilder.withExternalId(s3BucketConfiguration.getRoleExternalId()); } credentialsProvider = credentialsProviderBuilder.build(); } else { credentialsProvider = new DefaultAWSCredentialsProviderChain(); } return credentialsProvider; } }