Skip to content

Commit 78dd838

Browse files
committed
UploadId is always a UUID
1 parent c03fbb5 commit 78dd838

File tree

7 files changed

+80
-77
lines changed

7 files changed

+80
-77
lines changed

integration-tests/src/test/kotlin/com/adobe/testing/s3mock/its/MultipartIT.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ internal class MultipartIT : S3TestBase() {
743743
s3Client.listParts {
744744
it.bucket(bucketName)
745745
it.key("NON_EXISTENT_KEY")
746-
it.uploadId("NON_EXISTENT_UPLOAD_ID")
746+
it.uploadId(UUID.randomUUID().toString())
747747
}
748748
}
749749
.isInstanceOf(AwsServiceException::class.java)
@@ -1616,7 +1616,7 @@ internal class MultipartIT : S3TestBase() {
16161616
s3Client.abortMultipartUpload {
16171617
it.bucket(randomName)
16181618
it.key(UPLOAD_FILE_NAME)
1619-
it.uploadId("uploadId")
1619+
it.uploadId(UUID.randomUUID().toString())
16201620
}
16211621
}
16221622
.isInstanceOf(NoSuchBucketException::class.java)

server/src/main/java/com/adobe/testing/s3mock/MultipartController.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
import java.io.InputStream;
7575
import java.time.Instant;
7676
import java.util.List;
77+
import java.util.UUID;
7778
import org.apache.commons.io.FileUtils;
7879
import org.apache.commons.io.IOUtils;
7980
import org.jspecify.annotations.Nullable;
@@ -170,7 +171,7 @@ public ResponseEntity<ListMultipartUploadsResult> listMultipartUploads(
170171
public ResponseEntity<Void> abortMultipartUpload(
171172
@PathVariable String bucketName,
172173
@PathVariable ObjectKey key,
173-
@RequestParam String uploadId) {
174+
@RequestParam UUID uploadId) {
174175
bucketService.verifyBucketExists(bucketName);
175176
multipartService.verifyMultipartUploadExists(bucketName, uploadId);
176177
multipartService.abortMultipartUpload(bucketName, key.key(), uploadId);
@@ -193,7 +194,7 @@ public ResponseEntity<ListPartsResult> listParts(
193194
@PathVariable ObjectKey key,
194195
@RequestParam(name = MAX_PARTS, defaultValue = "1000", required = false) Integer maxParts,
195196
@RequestParam(name = PART_NUMBER_MARKER, required = false) Integer partNumberMarker,
196-
@RequestParam String uploadId) {
197+
@RequestParam UUID uploadId) {
197198
bucketService.verifyBucketExists(bucketName);
198199
multipartService.verifyMultipartUploadExists(bucketName, uploadId);
199200

@@ -226,7 +227,7 @@ public ResponseEntity<ListPartsResult> listParts(
226227
public ResponseEntity<Void> uploadPart(
227228
@PathVariable String bucketName,
228229
@PathVariable ObjectKey key,
229-
@RequestParam String uploadId,
230+
@RequestParam UUID uploadId,
230231
@RequestParam String partNumber,
231232
@RequestHeader HttpHeaders httpHeaders,
232233
InputStream inputStream) {
@@ -296,7 +297,7 @@ public ResponseEntity<CopyPartResult> uploadPartCopy(
296297
@RequestHeader(value = X_AMZ_COPY_SOURCE_IF_NONE_MATCH, required = false) List<String> noneMatch,
297298
@RequestHeader(value = X_AMZ_COPY_SOURCE_IF_MODIFIED_SINCE, required = false) List<Instant> ifModifiedSince,
298299
@RequestHeader(value = X_AMZ_COPY_SOURCE_IF_UNMODIFIED_SINCE, required = false) List<Instant> ifUnmodifiedSince,
299-
@RequestParam String uploadId,
300+
@RequestParam UUID uploadId,
300301
@RequestParam String partNumber,
301302
@RequestHeader HttpHeaders httpHeaders) {
302303
var bucket = bucketService.verifyBucketExists(bucketName);
@@ -413,7 +414,7 @@ public ResponseEntity<CompleteMultipartUploadResult> completeMultipartUpload(
413414
@PathVariable ObjectKey key,
414415
@RequestHeader(value = IF_MATCH, required = false) List<String> match,
415416
@RequestHeader(value = IF_NONE_MATCH, required = false) List<String> noneMatch,
416-
@RequestParam String uploadId,
417+
@RequestParam UUID uploadId,
417418
@RequestBody CompleteMultipartUpload upload,
418419
HttpServletRequest request,
419420
@RequestHeader HttpHeaders httpHeaders) {

server/src/main/java/com/adobe/testing/s3mock/service/MultipartService.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public MultipartService(BucketStore bucketStore, MultipartStore multipartStore)
7070
public String putPart(
7171
String bucketName,
7272
String key,
73-
String uploadId,
73+
UUID uploadId,
7474
String partNumber,
7575
Path path,
7676
Map<String, String> encryptionHeaders) {
@@ -91,7 +91,7 @@ public CopyPartResult copyPart(
9191
String partNumber,
9292
String destinationBucket,
9393
String destinationKey,
94-
String uploadId,
94+
UUID uploadId,
9595
Map<String, String> encryptionHeaders,
9696
String versionId) {
9797
var sourceBucketMetadata = bucketStore.getBucketMetadata(bucketName);
@@ -124,7 +124,7 @@ public ListPartsResult getMultipartUploadParts(
124124
String key,
125125
Integer maxParts,
126126
Integer partNumberMarker,
127-
String uploadId) {
127+
UUID uploadId) {
128128
var bucketMetadata = bucketStore.getBucketMetadata(bucketName);
129129
var id = bucketMetadata.getID(key);
130130
if (id == null) {
@@ -158,11 +158,11 @@ public ListPartsResult getMultipartUploadParts(
158158
parts,
159159
partNumberMarker,
160160
multipartUpload.storageClass(),
161-
uploadId,
161+
uploadId.toString(),
162162
null);
163163
}
164164

165-
public void abortMultipartUpload(String bucketName, String key, String uploadId) {
165+
public void abortMultipartUpload(String bucketName, String key, UUID uploadId) {
166166
var bucketMetadata = bucketStore.getBucketMetadata(bucketName);
167167
var id = bucketMetadata.getID(key);
168168
try {
@@ -176,7 +176,7 @@ public void abortMultipartUpload(String bucketName, String key, String uploadId)
176176
public CompleteMultipartUploadResult completeMultipartUpload(
177177
String bucketName,
178178
String key,
179-
String uploadId,
179+
UUID uploadId,
180180
List<CompletedPart> parts,
181181
Map<String, String> encryptionHeaders,
182182
String location,
@@ -322,7 +322,7 @@ public void verifyPartNumberLimits(String partNumberString) {
322322
}
323323

324324
public void verifyMultipartParts(String bucketName, String key,
325-
String uploadId, List<CompletedPart> requestedParts) throws S3Exception {
325+
UUID uploadId, List<CompletedPart> requestedParts) throws S3Exception {
326326
var bucketMetadata = bucketStore.getBucketMetadata(bucketName);
327327
var id = bucketMetadata.getID(key);
328328
if (id == null) {
@@ -353,7 +353,7 @@ public void verifyMultipartParts(String bucketName, String key,
353353
}
354354
}
355355

356-
public void verifyMultipartParts(String bucketName, UUID id, String uploadId) throws S3Exception {
356+
public void verifyMultipartParts(String bucketName, UUID id, UUID uploadId) throws S3Exception {
357357
verifyMultipartUploadExists(bucketName, uploadId);
358358
var bucketMetadata = bucketStore.getBucketMetadata(bucketName);
359359
var uploadedParts = multipartStore.getMultipartUploadParts(bucketMetadata, id, uploadId);
@@ -370,7 +370,7 @@ public void verifyMultipartParts(String bucketName, UUID id, String uploadId) th
370370
}
371371
}
372372

373-
public void verifyMultipartUploadExists(String bucketName, String uploadId) throws S3Exception {
373+
public void verifyMultipartUploadExists(String bucketName, UUID uploadId) throws S3Exception {
374374
try {
375375
var bucketMetadata = bucketStore.getBucketMetadata(bucketName);
376376
multipartStore.getMultipartUpload(bucketMetadata, uploadId);

server/src/main/java/com/adobe/testing/s3mock/store/MultipartStore.java

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public MultipartUpload createMultipartUpload(
9494
StorageClass storageClass,
9595
@Nullable ChecksumType checksumType,
9696
@Nullable ChecksumAlgorithm checksumAlgorithm) {
97-
var uploadId = UUID.randomUUID().toString();
97+
var uploadId = UUID.randomUUID();
9898
if (!createPartsFolder(bucket, uploadId)) {
9999
LOG.error("Directories for storing multipart uploads couldn't be created. bucket={}, key={}, "
100100
+ "id={}, uploadId={}", bucket, key, id, uploadId);
@@ -108,7 +108,7 @@ public MultipartUpload createMultipartUpload(
108108
key,
109109
owner,
110110
storageClass,
111-
uploadId
111+
uploadId.toString()
112112
);
113113
var multipartUploadInfo = new MultipartUploadInfo(upload,
114114
contentType,
@@ -121,7 +121,7 @@ public MultipartUpload createMultipartUpload(
121121
null,
122122
checksumType,
123123
checksumAlgorithm);
124-
lockStore.putIfAbsent(UUID.fromString(uploadId), new Object());
124+
lockStore.putIfAbsent(uploadId, new Object());
125125
writeMetafile(bucket, multipartUploadInfo);
126126

127127
return upload;
@@ -138,7 +138,7 @@ public List<MultipartUpload> listMultipartUploads(BucketMetadata bucketMetadata,
138138
.map(
139139
path -> {
140140
var fileName = path.getFileName().toString();
141-
var uploadMetadata = getUploadMetadata(bucketMetadata, fileName);
141+
var uploadMetadata = getUploadMetadata(bucketMetadata, UUID.fromString(fileName));
142142
if (uploadMetadata != null) {
143143
return uploadMetadata.upload();
144144
} else {
@@ -157,11 +157,11 @@ public List<MultipartUpload> listMultipartUploads(BucketMetadata bucketMetadata,
157157
@Nullable
158158
public MultipartUploadInfo getMultipartUploadInfo(
159159
BucketMetadata bucketMetadata,
160-
String uploadId) {
160+
UUID uploadId) {
161161
return getUploadMetadata(bucketMetadata, uploadId);
162162
}
163163

164-
public MultipartUpload getMultipartUpload(BucketMetadata bucketMetadata, String uploadId) {
164+
public MultipartUpload getMultipartUpload(BucketMetadata bucketMetadata, UUID uploadId) {
165165
var uploadMetadata = getUploadMetadata(bucketMetadata, uploadId);
166166
if (uploadMetadata != null) {
167167
return uploadMetadata.upload();
@@ -170,24 +170,24 @@ public MultipartUpload getMultipartUpload(BucketMetadata bucketMetadata, String
170170
}
171171
}
172172

173-
public void abortMultipartUpload(BucketMetadata bucket, UUID id, String uploadId) {
173+
public void abortMultipartUpload(BucketMetadata bucket, UUID id, UUID uploadId) {
174174
var multipartUploadInfo = getMultipartUploadInfo(bucket, uploadId);
175175
if (multipartUploadInfo != null) {
176-
synchronized (lockStore.get(UUID.fromString(uploadId))) {
176+
synchronized (lockStore.get(uploadId)) {
177177
try {
178178
FileUtils.deleteDirectory(getPartsFolder(bucket, uploadId).toFile());
179179
} catch (IOException e) {
180180
throw new IllegalStateException("Could not delete multipart-directory " + uploadId, e);
181181
}
182-
lockStore.remove(UUID.fromString(uploadId));
182+
lockStore.remove(uploadId);
183183
}
184184
}
185185
}
186186

187187
public String putPart(
188188
BucketMetadata bucket,
189189
UUID id,
190-
String uploadId,
190+
UUID uploadId,
191191
String partNumber,
192192
Path path,
193193
Map<String, String> encryptionHeaders) {
@@ -200,7 +200,7 @@ public CompleteMultipartUploadResult completeMultipartUpload(
200200
BucketMetadata bucket,
201201
String key,
202202
UUID id,
203-
String uploadId,
203+
UUID uploadId,
204204
List<CompletedPart> parts,
205205
Map<String, String> encryptionHeaders,
206206
@Nullable MultipartUploadInfo uploadInfo,
@@ -308,7 +308,7 @@ private String checksumFor(List<Path> paths, MultipartUploadInfo uploadInfo) {
308308
public List<Part> getMultipartUploadParts(
309309
BucketMetadata bucket,
310310
UUID id,
311-
String uploadId) {
311+
UUID uploadId) {
312312
var partsPath = getPartsFolder(bucket, uploadId);
313313
try (var directoryStream = newDirectoryStream(partsPath,
314314
path -> path.getFileName().toString().endsWith(PART_SUFFIX))) {
@@ -337,7 +337,7 @@ public String copyPart(
337337
String partNumber,
338338
BucketMetadata destinationBucket,
339339
UUID destinationId,
340-
String uploadId,
340+
UUID uploadId,
341341
@Nullable Map<String, String> encryptionHeaders,
342342
@Nullable String versionId) {
343343

@@ -398,7 +398,7 @@ private String copyPartToFile(
398398
private File createPartFile(
399399
BucketMetadata bucket,
400400
@Nullable UUID id,
401-
String uploadId,
401+
UUID uploadId,
402402
String partNumber) {
403403
if (id == null) {
404404
return null;
@@ -423,7 +423,7 @@ private File createPartFile(
423423
private void verifyMultipartUploadPreparation(
424424
BucketMetadata bucket,
425425
@Nullable UUID id,
426-
String uploadId) {
426+
UUID uploadId) {
427427
Path partsFolder = null;
428428
var multipartUploadInfo = getMultipartUploadInfo(bucket, uploadId);
429429
if (id != null) {
@@ -440,7 +440,7 @@ private void verifyMultipartUploadPreparation(
440440
}
441441
}
442442

443-
private boolean createPartsFolder(BucketMetadata bucket, String uploadId) {
443+
private boolean createPartsFolder(BucketMetadata bucket, UUID uploadId) {
444444
var partsFolder = getPartsFolder(bucket, uploadId).toFile();
445445
return partsFolder.mkdirs();
446446
}
@@ -450,24 +450,24 @@ private Path getMultipartsFolder(BucketMetadata bucket) {
450450
return Paths.get(bucket.path().toString(), MULTIPARTS_FOLDER);
451451
}
452452

453-
private Path getPartPath(BucketMetadata bucket, String uploadId, String partNumber) {
453+
private Path getPartPath(BucketMetadata bucket, UUID uploadId, String partNumber) {
454454
return getPartsFolder(bucket, uploadId).resolve(partNumber + PART_SUFFIX);
455455
}
456456

457-
private Path getUploadMetadataPath(BucketMetadata bucket, String uploadId) {
457+
private Path getUploadMetadataPath(BucketMetadata bucket, UUID uploadId) {
458458
return getPartsFolder(bucket, uploadId).resolve(MULTIPART_UPLOAD_META_FILE);
459459
}
460460

461-
private Path getPartsFolder(BucketMetadata bucket, String uploadId) {
462-
return getMultipartsFolder(bucket).resolve(uploadId);
461+
private Path getPartsFolder(BucketMetadata bucket, UUID uploadId) {
462+
return getMultipartsFolder(bucket).resolve(uploadId.toString());
463463
}
464464

465465
@Nullable
466-
private MultipartUploadInfo getUploadMetadata(BucketMetadata bucket, String uploadId) {
466+
private MultipartUploadInfo getUploadMetadata(BucketMetadata bucket, UUID uploadId) {
467467
var metaPath = getUploadMetadataPath(bucket, uploadId);
468468

469469
if (Files.exists(metaPath)) {
470-
synchronized (lockStore.get(UUID.fromString(uploadId))) {
470+
synchronized (lockStore.get(uploadId)) {
471471
try {
472472
return objectMapper.readValue(metaPath.toFile(), MultipartUploadInfo.class);
473473
} catch (IOException e) {
@@ -482,7 +482,7 @@ private void writeMetafile(BucketMetadata bucket, MultipartUploadInfo uploadInfo
482482
var uploadId = uploadInfo.upload().uploadId();
483483
try {
484484
synchronized (lockStore.get(UUID.fromString(uploadId))) {
485-
var metaFile = getUploadMetadataPath(bucket, uploadId).toFile();
485+
var metaFile = getUploadMetadataPath(bucket, UUID.fromString(uploadId)).toFile();
486486
objectMapper.writeValue(metaFile, uploadInfo);
487487
}
488488
} catch (IOException e) {

server/src/test/kotlin/com/adobe/testing/s3mock/MultipartControllerTest.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import org.springframework.web.util.UriComponentsBuilder
4545
import java.nio.file.Paths
4646
import java.time.Instant
4747
import java.util.Date
48+
import java.util.UUID
4849

4950
@MockBeans(
5051
MockBean(
@@ -87,7 +88,7 @@ internal class MultipartControllerTest : BaseControllerTest() {
8788
}
8889

8990
val key = "sampleFile.txt"
90-
val uploadId = "testUploadId"
91+
val uploadId = UUID.randomUUID()
9192
doThrow(S3Exception.ENTITY_TOO_SMALL)
9293
.whenever(multipartService)
9394
.verifyMultipartParts(
@@ -120,7 +121,7 @@ internal class MultipartControllerTest : BaseControllerTest() {
120121
@Throws(Exception::class)
121122
fun testCompleteMultipart_BadRequest_uploadIdNotFound() {
122123
givenBucket()
123-
val uploadId = "testUploadId"
124+
val uploadId = UUID.randomUUID()
124125

125126
val parts = listOf(
126127
createPart(0, 5L),
@@ -177,7 +178,7 @@ internal class MultipartControllerTest : BaseControllerTest() {
177178
fun testCompleteMultipart_BadRequest_partNotFound() {
178179
givenBucket()
179180
val key = "sampleFile.txt"
180-
val uploadId = "testUploadId"
181+
val uploadId = UUID.randomUUID()
181182

182183
val requestParts = listOf(createPart(1, 5L))
183184

@@ -230,7 +231,7 @@ internal class MultipartControllerTest : BaseControllerTest() {
230231
givenBucket()
231232

232233
val key = "sampleFile.txt"
233-
val uploadId = "testUploadId"
234+
val uploadId = UUID.randomUUID()
234235

235236
doThrow(S3Exception.INVALID_PART_ORDER)
236237
.whenever(multipartService)

0 commit comments

Comments
 (0)