-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathS3ServiceImpl.java
More file actions
95 lines (83 loc) · 4.21 KB
/
S3ServiceImpl.java
File metadata and controls
95 lines (83 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package com.app.service;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedUpload;
import software.amazon.awssdk.transfer.s3.model.Upload;
import software.amazon.awssdk.transfer.s3.model.UploadRequest;
import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.concurrent.CompletableFuture;
@Service
@Log4j2
@RequiredArgsConstructor
public class S3ServiceImpl implements S3Service {
private final S3AsyncClient s3AsyncClient;
@Value("${aws.s3.bucket-name}")
private String bucketName;
private S3TransferManager createTransferManager() {
return S3TransferManager.builder()
.s3Client(s3AsyncClient)
.build();
}
@Override
public boolean uploadFile(MultipartFile file, boolean isReadPublicly) {
log.info("Started uploading file '{}' to S3 Bucket '{}'", file.getOriginalFilename(), bucketName);
try (S3TransferManager transferManager = createTransferManager()) {
UploadRequest uploadRequest;
if (isReadPublicly) {
uploadRequest = UploadRequest.builder()
.putObjectRequest(builder -> builder.bucket(bucketName).key(file.getOriginalFilename()).acl("public-read"))
.requestBody(AsyncRequestBody.fromBytes(file.getBytes()))
.addTransferListener(LoggingTransferListener.create()) // For logging progress
.build();
} else {
uploadRequest = UploadRequest.builder()
.putObjectRequest(builder -> builder.bucket(bucketName).key(file.getOriginalFilename()))
.requestBody(AsyncRequestBody.fromBytes(file.getBytes()))
.addTransferListener(LoggingTransferListener.create()) // For logging progress
.build();
}
// Start the file upload
Upload upload = transferManager.upload(uploadRequest);
// Wait for the upload to complete
CompletableFuture<CompletedUpload> uploadCompletion = upload.completionFuture();
uploadCompletion.join();
log.info("Successfully uploaded file to S3. Bucket: {}, Key: {}", bucketName, file.getOriginalFilename());
return true;
} catch (Exception e) {
log.error("Failed to upload file to S3. Bucket: {}, Key: {}", bucketName, file.getOriginalFilename(), e);
return false;
}
}
@Override
public CompletableFuture<ByteArrayInputStream> downloadFileAsStream(String key) {
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
.bucket(bucketName)
.key(key)
.build();
// Download the file directly into a ByteArrayOutputStream
return s3AsyncClient.getObject(getObjectRequest, AsyncResponseTransformer.toBytes())
.thenApply(response -> {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
byteArrayOutputStream.write(response.asByteArray());
} catch (Exception e) {
log.error("Failed to write response to ByteArrayOutputStream. Bucket: {}, Key: {}", bucketName, key, e);
}
return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
})
.exceptionally(e -> {
log.error("Failed to download file from S3. Bucket: {}, Key: {}", bucketName, key, e);
return null;
});
}
}