diff --git a/doc/files.md b/doc/files.md index 566dcfdcb..746ae52b5 100644 --- a/doc/files.md +++ b/doc/files.md @@ -144,6 +144,23 @@ BoxFile.Info newFileInfo = rootFolder.uploadFile(stream, "My File.txt"); stream.close(); ``` +Note that using `FileInputStream` allows you to read the content of the file only once. +If the first upload attempt fails, the stream will become exhausted, +and request retry with no content might be performed. To retry an upload, you would have to +create a new `FileInputStream` and call `uploadFile()` method again. + +If you want the SDK to automatically retry the upload in case of any error, you need to provide an +`InputStream` class that supports the `reset()` operation. For example, you can read all bytes from your file into +a `ByteArrayInputStream` and then use it for the upload method. Be aware that this approach will load the whole file +into memory, so it is not recommended for large files, as it can exhaust easily your memory. + +```java +BoxFolder rootFolder = BoxFolder.getRootFolder(api); +InputStream stream = new ByteArrayInputStream(Files.readAllBytes(new File(path).toPath())); +BoxFile.Info newFileInfo = rootFolder.uploadFile(stream, "My File.txt"); +stream.close(); +``` + Upload progress can be tracked by providing the size of the file and a [`ProgressListener`][progress] to [`uploadFile(InputStream fileContents, String fileName, long fileSize, ProgressListener progress)`][upload2]. diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java index 5d820635a..5c1d0e780 100644 --- a/src/test/java/com/box/sdk/BoxFolderTest.java +++ b/src/test/java/com/box/sdk/BoxFolderTest.java @@ -8,6 +8,7 @@ import static com.box.sdk.http.ContentType.APPLICATION_JSON_PATCH; import static com.box.sdk.http.ContentType.APPLICATION_OCTET_STREAM; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static com.github.tomakehurst.wiremock.stubbing.Scenario.STARTED; import static java.lang.String.format; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -1255,6 +1256,40 @@ public void testUploadFileWithDescriptionSucceeds() { assertEquals(fileDescription, file.getDescription()); } + @Test + public void testUploadFileSucceedsAfter500InTheFirstAttempt() throws IOException { + final String folderID = "12345"; + final String fileURL = "/2.0/files/content"; + final String fileContent = "Test file"; + final String fileName = "Test File.txt"; + InputStream stream = new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8)); + + String result = TestUtils.getFixture("BoxFile/CreateFileWithDescription201"); + + wireMockRule.stubFor(WireMock.post(WireMock.urlPathEqualTo(fileURL)) + .inScenario("Retry Scenario") + .whenScenarioStateIs(STARTED) + .willReturn(WireMock.aResponse() + .withStatus(500)) + .willSetStateTo("Retry")); + + wireMockRule.stubFor(WireMock.post(WireMock.urlPathEqualTo(fileURL)) + .inScenario("Retry Scenario") + .whenScenarioStateIs("Retry") + .willReturn(WireMock.aResponse() + .withHeader("Content-Type", APPLICATION_JSON_PATCH) + .withBody(result) + .withStatus(201)) + .willSetStateTo("Success")); + + BoxFolder folder = new BoxFolder(this.api, folderID); + BoxFile.Info file = folder.uploadFile(stream, fileName); + + WireMock.verify(2, WireMock.postRequestedFor(WireMock.urlEqualTo("/2.0/files/content"))); + + assertEquals(fileName, file.getName()); + } + @Test public void testGetFolderItemsWithSortAndOffset() { final String folderID = "12345";