awspring / spring-cloud-aws

The New Home for Spring Cloud AWS
http://awspring.io
Apache License 2.0
828 stars 283 forks source link

Ability to declare default S3 bucket name and presigned URL validity #1148

Open hardikSinghBehl opened 2 months ago

hardikSinghBehl commented 2 months ago

Type: Feature

Is your feature request related to a problem? Please describe.

More often that not, in the microservices architecture, a single microservice operates against a single S3 bucket. Spring Cloud AWS helps me eliminate verbose bean declarations and boilerplate code, but I still need to create a separate @ConfigurationProperties class to store attributes of bucket name and validity of presigned URL.

A sample .yaml file snippet of a microservice:

spring:
  cloud:
    aws:
      credentials:
        access-key: ${AWS_ACCESS_KEY}
        secret-key: ${AWS_SECRET_KEY}
      s3:
        region: ${AWS_S3_REGION}

com:
  behl:
    aws:
      s3:
        bucket-name: ${AWS_S3_BUCKET_NAME}
        presigned-url:
          validity: ${AWS_S3_PRESIGNED_URL_VALIDITY}

The above 2 custom properties are mapped to a @ConfigurationProperties class which is referenced when interacting with S3Template:

@Component
@RequiredArgsConstructor
@EnableConfigurationProperties(AwsS3BucketProperties.class)
class SampleClass{

  private final AwsS3BucketProperties awsS3BucketProperties;

  void sampleSave(Multipartfile file){
    var bucketName = awsS3BucketProperties.getBucketName();
    s3Template.upload(bucketName, file.getName(), file.getInputStream());
  }

  URL samplePresign(String objectKey){
    var bucketName = awsS3BucketProperties.getBucketName();
    var urlValidity = awsS3BucketProperties.getPresignedUrl().getValidity();
    var urlValidityDuration = Duration.ofSeconds(urlValidity);

    return s3Template.createSignedPutURL(bucketName, objectKey, urlValidityDuration);
  }

}

Describe the solution you'd like

It'll be pretty cool to have the functionality to declare the default s3 bucket and presigned url validity (in java.time.Duration) in the Spring Cloud AWS configuration properties itself:

spring:
  cloud:
    aws:
      credentials:
        access-key: ${AWS_ACCESS_KEY}
        secret-key: ${AWS_SECRET_KEY}
      s3:
        region: ${AWS_S3_REGION}
        default:
          bucket: ${AWS_S3_BUCKET_NAME}
          presigned-url-validity: ${AWS_S3_PRESIGNED_URL_VALIDITY}

The above assumes the default validity of both GET and PUT presigned URL to be same but the solution should allow to configure the duration of GET and PUT presigned URLs separately. With the above configuration, the service could use the S3Template like below without the need of creating a custom configuration class.

@Component
class SampleClass{

  void sampleSave(Multipartfile file){
    s3Template.upload(file.getName(), file.getInputStream());
  }

  URL samplePresign(String objectKey){   
    return s3Template.createSignedPutURL(objectKey);
  }

}

Again, would like to point that this will only benefit the applications interacting with a single S3 bucket. Applications interacting with more than 1, can use the library with existing methods.

A similar functionality is available in SnsTemplate with method setDefaultDestinationName. But that does not give the functionality to define the topic name in .yaml or .properties file, as compared to the proposed solution above.

Additional context Can submit PR if the feature is approved.

hardikSinghBehl commented 1 month ago

Hi @MatejNedic, @maciejwalkowiak, @tomazfernandes. Could you evaluate this feature