Issue
We have the Spring Boot 2 app, and there is such a task - we have previously persisted AWS S3 connection details (bucket, path, access, secret), and we need to create AWS S3 client on-the-flight, just to test connection with the given details.
I suppose that bean of @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
is needed, but how to set these connection details dynamically?
Maybe there is a better approach, any comments/solutions are appreciated, thank you!
Solution
We can create AWS S3 client dynamically by passing AccessKeyId, SecretAccessKey and Region. Here is the solution.
AWS SDK v1.X
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.12.315</version>
</dependency>
@Service
public class AwsS3ClientBuilderService {
public AmazonS3 createAwsS3Client(String accessKeyId, String secretAccessKey, String region){
final BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKeyId, secretAccessKey);
return AmazonS3ClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(basicAWSCredentials))
.withRegion(region)
.build();
}
}
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
private final AwsS3ClientBuilderService awsS3ClientBuilderService;
@Autowired
public DemoApplication(AwsS3ClientBuilderService awsS3ClientBuilderService) {
this.awsS3ClientBuilderService = awsS3ClientBuilderService;
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class);
}
@Override
public void run(String... args) throws Exception {
final AmazonS3 amazonS3 = awsS3ClientBuilderService
.createAwsS3Client("accessKeyId","secretAccessKey","eu-west-1");
GetObjectRequest getObjectRequest = new GetObjectRequest("bucketName","keyName");
final S3Object s3Object = amazonS3.getObject(getObjectRequest);
final S3ObjectInputStream objectContent = s3Object.getObjectContent();
//....
}
}
AWS SDK v2.X
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.17.285</version>
</dependency>
@Service
public class AwsS3ClientBuilderService {
public S3Client createAwsS3Client(String accessKeyId, String secretAccessKey, String region){
AwsBasicCredentials awsBasicCredentials = AwsBasicCredentials.create(accessKeyId, secretAccessKey);
return S3Client
.builder()
.region(Region.of(region))
.credentialsProvider(StaticCredentialsProvider.create(awsBasicCredentials))
.build();
}
}
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
private final AwsS3ClientBuilderService awsS3ClientBuilderService;
@Autowired
public DemoApplication(AwsS3ClientBuilderService awsS3ClientBuilderService) {
this.awsS3ClientBuilderService = awsS3ClientBuilderService;
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class);
}
@Override
public void run(String... args) throws Exception {
try (S3Client s3Client = awsS3ClientBuilderService
.createAwsS3Client("accessKeyId", "secretAccessKey", "eu-west-1")) {
GetObjectRequest getObjectRequest= GetObjectRequest
.builder()
.bucket("buketName")
.key("keyName")
.build();
final ResponseInputStream<GetObjectResponse> responseInputStream = s3Client.getObject(getObjectRequest);
final GetObjectResponse getObjectResponse = responseInputStream.response();
//...
}
}
}
Answered By - Rohit Agarwal
Answer Checked By - Gilberto Lyons (JavaFixing Admin)