-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathS3Util.java
More file actions
148 lines (123 loc) · 5.06 KB
/
Copy pathS3Util.java
File metadata and controls
148 lines (123 loc) · 5.06 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package org.clokey.util;
import com.amazonaws.HttpMethod;
import com.amazonaws.SdkClientException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.Headers;
import com.amazonaws.services.s3.model.*;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.clokey.enums.FileExtension;
import org.clokey.enums.ImageType;
import org.clokey.properties.S3Properties;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
@Slf4j
public class S3Util {
private final AmazonS3 amazonS3;
private final S3Properties s3Properties;
public String createPresignedUrl(
ImageType imageType, Long memberId, FileExtension fileExtension, String md5Hash) {
String imageKey = UUID.randomUUID().toString();
String fileName = createFileName(imageType, memberId, imageKey, fileExtension);
String bucket = s3Properties.bucket();
GeneratePresignedUrlRequest generatePresignedUrlRequest =
generatePresignedUrlRequest(
bucket, fileName, fileExtension.getExtension(), md5Hash);
return amazonS3.generatePresignedUrl(generatePresignedUrlRequest).toString();
}
private String createFileName(
ImageType imageType, Long memberId, String imageKey, FileExtension fileExtension) {
return memberId
+ "/"
+ imageType.getType()
+ "/"
+ imageKey
+ "."
+ fileExtension.getExtension();
}
private GeneratePresignedUrlRequest generatePresignedUrlRequest(
String bucket, String fileName, String imageFileExtension, String md5Hash) {
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(bucket, fileName, HttpMethod.PUT)
.withKey(fileName)
.withContentType("image/" + imageFileExtension)
.withExpiration(getPresignedUrlExpiration());
generatePresignedUrlRequest.addRequestParameter("x-amz-tagging", "status=pending");
generatePresignedUrlRequest.setContentMd5(md5Hash);
return generatePresignedUrlRequest;
}
public void deleteAllByUrls(List<String> urls) {
if (urls == null || urls.isEmpty()) {
log.info("deleteAllByUrls skipped: received null or empty urls");
return;
}
String bucket = s3Properties.bucket();
List<DeleteObjectsRequest.KeyVersion> keys =
urls.stream()
.map(this::extractObjectKey)
.map(DeleteObjectsRequest.KeyVersion::new)
.toList();
DeleteObjectsRequest request = new DeleteObjectsRequest(bucket).withKeys(keys);
amazonS3.deleteObjects(request);
}
public void deleteByUrl(String url) {
String bucket = s3Properties.bucket();
String objectKey = extractObjectKey(url);
amazonS3.deleteObject(bucket, objectKey);
}
private String extractObjectKey(String url) {
int comIndex = url.indexOf(".com/");
return url.substring(comIndex + 5);
}
private Date getPresignedUrlExpiration() {
Date expiration = new Date();
long expTimeMillis = expiration.getTime();
expTimeMillis += TimeUnit.HOURS.toMillis(1);
expiration.setTime(expTimeMillis);
return expiration;
}
public void updateTagToCompleteByUrl(String url) {
String bucket = s3Properties.bucket();
String key = extractObjectKey(url);
List<Tag> tags = List.of(new Tag("status", "complete"));
ObjectTagging tagging = new ObjectTagging(tags);
SetObjectTaggingRequest request = new SetObjectTaggingRequest(bucket, key, tagging);
amazonS3.setObjectTagging(request);
}
public void updateTagsToCompleteByUrls(List<String> urls) {
for (String url : urls) {
updateTagToCompleteByUrl(url);
}
}
public boolean doesFileExistByUrl(String url) {
String bucket = s3Properties.bucket();
String key = extractObjectKey(url);
try {
return amazonS3.doesObjectExist(bucket, key);
} catch (AmazonS3Exception e) {
if (e.getStatusCode() == 403) {
log.warn("Access denied for key={}, treating as non-existent", key);
return false;
}
log.error("S3 error while checking existence: {}", e.getErrorMessage(), e);
return false;
} catch (SdkClientException e) {
log.error("Network error while connecting to S3: {}", e.getMessage());
return false;
}
}
public boolean doAllFilesExistByUrls(List<String> urls) {
for (String url : urls) {
if (!doesFileExistByUrl(url)) {
log.warn("File not found or inaccessible: {}", url);
return false;
}
}
return true;
}
}