63
63
import org .junit .jupiter .api .io .TempDir ;
64
64
import software .amazon .awssdk .core .ResponseBytes ;
65
65
import software .amazon .awssdk .core .sync .RequestBody ;
66
+ import software .amazon .awssdk .services .s3 .S3AsyncClient ;
66
67
import software .amazon .awssdk .services .s3 .S3Client ;
67
68
import software .amazon .awssdk .services .s3 .model .CompleteMultipartUploadResponse ;
68
69
import software .amazon .awssdk .services .s3 .model .CompletedMultipartUpload ;
83
84
import software .amazon .awssdk .services .s3 .model .Tagging ;
84
85
import software .amazon .awssdk .services .s3 .model .UploadPartRequest ;
85
86
import software .amazon .awssdk .services .s3 .model .UploadPartResponse ;
87
+ import software .amazon .awssdk .transfer .s3 .S3TransferManager ;
88
+ import software .amazon .awssdk .transfer .s3 .model .DownloadFileRequest ;
89
+ import software .amazon .awssdk .transfer .s3 .model .FileDownload ;
90
+ import software .amazon .awssdk .transfer .s3 .model .ResumableFileDownload ;
86
91
87
92
/**
88
93
* This is an abstract class to test the AWS Java S3 SDK operations.
@@ -103,6 +108,7 @@ public abstract class AbstractS3SDKV2Tests extends OzoneTestBase {
103
108
104
109
private static MiniOzoneCluster cluster = null ;
105
110
private static S3Client s3Client = null ;
111
+ private static S3AsyncClient s3AsyncClient = null ;
106
112
107
113
/**
108
114
* Create a MiniOzoneCluster with S3G enabled for testing.
@@ -116,7 +122,10 @@ static void startCluster(OzoneConfiguration conf) throws Exception {
116
122
.setNumDatanodes (5 )
117
123
.build ();
118
124
cluster .waitForClusterToBeReady ();
119
- s3Client = new S3ClientFactory (s3g .getConf ()).createS3ClientV2 ();
125
+
126
+ S3ClientFactory s3Factory = new S3ClientFactory (s3g .getConf ());
127
+ s3Client = s3Factory .createS3ClientV2 ();
128
+ s3AsyncClient = s3Factory .createS3AsyncClientV2 ();
120
129
}
121
130
122
131
/**
@@ -340,6 +349,46 @@ public void testLowLevelMultipartUpload(@TempDir Path tempDir) throws Exception
340
349
assertEquals (userMetadata , headObjectResponse .metadata ());
341
350
}
342
351
352
+ @ Test
353
+ public void testResumableDownloadWithEtagMismatch () throws Exception {
354
+ // Arrange
355
+ final String bucketName = getBucketName ("resumable" );
356
+ final String keyName = getKeyName ("resumable" );
357
+ final String fileContent = "This is a test file for resumable download." ;
358
+ s3Client .createBucket (b -> b .bucket (bucketName ));
359
+ s3Client .putObject (b -> b .bucket (bucketName ).key (keyName ), RequestBody .fromString (fileContent ));
360
+
361
+ // Prepare a temp file for download
362
+ Path downloadPath = Files .createTempFile ("downloaded" , ".txt" );
363
+
364
+ // Set up S3TransferManager
365
+ try (S3TransferManager transferManager =
366
+ S3TransferManager .builder ().s3Client (s3AsyncClient ).build ()) {
367
+
368
+ // First download
369
+ DownloadFileRequest downloadRequest = DownloadFileRequest .builder ()
370
+ .getObjectRequest (b -> b .bucket (bucketName ).key (keyName ))
371
+ .destination (downloadPath )
372
+ .build ();
373
+ FileDownload download = transferManager .downloadFile (downloadRequest );
374
+ ResumableFileDownload resumableFileDownload = download .pause ();
375
+
376
+ // Simulate etag mismatch by modifying the file in S3
377
+ final String newContent = "This is new content to cause etag mismatch." ;
378
+ s3Client .putObject (b -> b .bucket (bucketName ).key (keyName ), RequestBody .fromString (newContent ));
379
+
380
+ // Resume download
381
+ FileDownload resumedDownload = transferManager .resumeDownloadFile (resumableFileDownload );
382
+ resumedDownload .completionFuture ().get ();
383
+
384
+ String downloadedContent = new String (Files .readAllBytes (downloadPath ), StandardCharsets .UTF_8 );
385
+ assertEquals (newContent , downloadedContent );
386
+
387
+ File downloadFile = downloadPath .toFile ();
388
+ assertTrue (downloadFile .delete ());
389
+ }
390
+ }
391
+
343
392
private String getBucketName () {
344
393
return getBucketName ("" );
345
394
}
0 commit comments