From 5d006e7310b536023254de7e5d1a16fbaa295be4 Mon Sep 17 00:00:00 2001 From: Mina Asham Date: Wed, 14 Jul 2021 20:28:05 +0100 Subject: [PATCH] Amazon S3: Add option to download to and overwrite existing files - Issue: https://github.com/aws/aws-sdk-java-v2/issues/2300 --- .../feature-AmazonS3-a7371a0.json | 6 +++++ .../awssdk/core/sync/ResponseTransformer.java | 26 ++++++++++++++++--- .../tests/ResponseTransformerTest.java | 12 +++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 .changes/next-release/feature-AmazonS3-a7371a0.json diff --git a/.changes/next-release/feature-AmazonS3-a7371a0.json b/.changes/next-release/feature-AmazonS3-a7371a0.json new file mode 100644 index 000000000000..549b798b435a --- /dev/null +++ b/.changes/next-release/feature-AmazonS3-a7371a0.json @@ -0,0 +1,6 @@ +{ + "type": "feature", + "category": "Amazon S3", + "contributor": "mina-asham", + "description": "Add option to download to and overwrite existing files" +} diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/sync/ResponseTransformer.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/sync/ResponseTransformer.java index e32695b3b0fb..9dd6284bf86f 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/sync/ResponseTransformer.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/sync/ResponseTransformer.java @@ -20,10 +20,13 @@ import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; +import java.nio.file.CopyOption; import java.nio.file.DirectoryNotEmptyException; import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; + import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.core.ResponseBytes; import software.amazon.awssdk.core.ResponseInputStream; @@ -93,17 +96,22 @@ default boolean needsConnectionLeftOpen() { /** * Creates a response transformer that writes all response content to the specified file. If the file already exists - * then a {@link java.nio.file.FileAlreadyExistsException} will be thrown. + * and overwrite parameter is set to false then a {@link java.nio.file.FileAlreadyExistsException} will be thrown. * * @param path Path to file to write to. + * @param overwrite Overwrite existing files. * @param Type of unmarshalled response POJO. * @return ResponseTransformer instance. */ - static ResponseTransformer toFile(Path path) { + static ResponseTransformer toFile(Path path, boolean overwrite) { return (resp, in) -> { try { InterruptMonitor.checkInterrupted(); - Files.copy(in, path); + if (overwrite) { + Files.copy(in, path, StandardCopyOption.REPLACE_EXISTING); + } else { + Files.copy(in, path); + } return resp; } catch (IOException copyException) { String copyError = "Failed to read response into file: " + path; @@ -133,6 +141,18 @@ static ResponseTransformer toFile(Path path) { }; } + /** + * Creates a response transformer that writes all response content to the specified file. If the file already exists + * then a {@link java.nio.file.FileAlreadyExistsException} will be thrown. + * + * @param path Path to file to write to. + * @param Type of unmarshalled response POJO. + * @return ResponseTransformer instance. + */ + static ResponseTransformer toFile(Path path) { + return toFile(path, false); + } + /** * Creates a response transformer that writes all response content to the specified file. If the file already exists * then a {@link java.nio.file.FileAlreadyExistsException} will be thrown. diff --git a/test/protocol-tests/src/test/java/software/amazon/awssdk/protocol/tests/ResponseTransformerTest.java b/test/protocol-tests/src/test/java/software/amazon/awssdk/protocol/tests/ResponseTransformerTest.java index ffe38a7a54e4..ad7ddeabf9a4 100644 --- a/test/protocol-tests/src/test/java/software/amazon/awssdk/protocol/tests/ResponseTransformerTest.java +++ b/test/protocol-tests/src/test/java/software/amazon/awssdk/protocol/tests/ResponseTransformerTest.java @@ -112,6 +112,18 @@ public void downloadToExistingFileDoesNotRetry() throws IOException { .isInstanceOf(SdkClientException.class); } + @Test + public void downloadToExistingFileWithOverwriteSucceeds() throws IOException { + stubForSuccess(); + + Path tmpFile = Files.createTempFile("overwrite-test.", ".tmp"); + tmpFile.toFile().deleteOnExit(); + + testClient().streamingOutputOperation(StreamingOutputOperationRequest.builder().build(), ResponseTransformer.toFile(tmpFile, true)); + + assertThat(Files.readAllLines(tmpFile)).containsExactly("test \uD83D\uDE02"); + } + @Test public void downloadToOutputStreamDoesNotRetry() throws IOException { stubForRetriesTimeoutReadingFromStreams();