BAEL-4856 Integrate progress when downloading
This commit is contained in:
parent
91dfad8bec
commit
34c9e82eee
@ -7,6 +7,9 @@ import okhttp3.ResponseBody;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.springframework.http.HttpHeaders.CONTENT_LENGTH;
|
||||
|
||||
public class BinaryFileDownloader implements AutoCloseable {
|
||||
|
||||
@ -22,7 +25,8 @@ public class BinaryFileDownloader implements AutoCloseable {
|
||||
Request request = createRequest(url);
|
||||
Response response = executeRequest(request);
|
||||
ResponseBody responseBody = getResponseBodyOrFail(response);
|
||||
return write(responseBody);
|
||||
double length = getResponseLength(response);
|
||||
return write(responseBody, length);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -43,8 +47,12 @@ public class BinaryFileDownloader implements AutoCloseable {
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
private long write(ResponseBody responseBody) throws IOException {
|
||||
return writer.write(responseBody.byteStream());
|
||||
private double getResponseLength(Response response) {
|
||||
return Double.parseDouble(Objects.requireNonNull(response.header(CONTENT_LENGTH, "1")));
|
||||
}
|
||||
|
||||
private long write(ResponseBody responseBody, double length) throws IOException {
|
||||
return writer.write(responseBody.byteStream(), length);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -9,12 +9,14 @@ public class BinaryFileWriter implements AutoCloseable {
|
||||
|
||||
private static final int CHUNK_SIZE = 1024;
|
||||
private final OutputStream outputStream;
|
||||
private final ProgressCallable progressCallable;
|
||||
|
||||
public BinaryFileWriter(OutputStream outputStream) {
|
||||
public BinaryFileWriter(OutputStream outputStream, ProgressCallable progressCallable) {
|
||||
this.outputStream = outputStream;
|
||||
this.progressCallable = progressCallable;
|
||||
}
|
||||
|
||||
public long write(InputStream inputStream) throws IOException {
|
||||
public long write(InputStream inputStream, double length) throws IOException {
|
||||
try (BufferedInputStream input = new BufferedInputStream(inputStream)) {
|
||||
byte[] dataBuffer = new byte[CHUNK_SIZE];
|
||||
int readBytes;
|
||||
@ -22,6 +24,7 @@ public class BinaryFileWriter implements AutoCloseable {
|
||||
while ((readBytes = input.read(dataBuffer)) != -1) {
|
||||
totalBytes += readBytes;
|
||||
outputStream.write(dataBuffer, 0, readBytes);
|
||||
progressCallable.onProgress(totalBytes / length * 100.0);
|
||||
}
|
||||
return totalBytes;
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package com.baeldung.okhttp.download;
|
||||
|
||||
public interface ProgressCallable {
|
||||
|
||||
void onProgress(double progress);
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.baeldung.okhttp.download;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.mockwebserver.MockResponse;
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class BinaryFileDownloaderIntegrationTest {
|
||||
|
||||
@Rule
|
||||
public MockWebServer server = new MockWebServer();
|
||||
|
||||
@Test
|
||||
public void givenATextFile_whenDownload_thenExpectFileDownloaded() throws IOException {
|
||||
String body = "Hello Baeldung Readers!";
|
||||
server.enqueue(new MockResponse().setBody(body));
|
||||
String fileName = "download.txt";
|
||||
BinaryFileWriter writer = new BinaryFileWriter(new FileOutputStream(fileName), progress -> assertEquals(100.0, progress, .0));
|
||||
BinaryFileDownloader tested = new BinaryFileDownloader(new OkHttpClient(), writer);
|
||||
|
||||
long downloaded = tested.download(server.url("/greetings").toString());
|
||||
|
||||
assertEquals(body.length(), downloaded);
|
||||
File downloadedFile = new File(fileName);
|
||||
assertTrue(downloadedFile.isFile());
|
||||
assertTrue(downloadedFile.delete());
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,7 @@ import java.io.InputStream;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyDouble;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@ -42,12 +43,12 @@ public class BinaryFileDownloaderUnitTest {
|
||||
ResponseBody body = ResponseBody.create("BODY", MediaType.get("application/text"));
|
||||
Response response = createResponse(url, body);
|
||||
when(call.execute()).thenReturn(response);
|
||||
when(writer.write(any())).thenReturn(1L);
|
||||
when(writer.write(any(), anyDouble())).thenReturn(1L);
|
||||
|
||||
try (BinaryFileDownloader tested = new BinaryFileDownloader(client, writer)) {
|
||||
long size = tested.download(url);
|
||||
assertEquals(1L, size);
|
||||
verify(writer).write(any(InputStream.class));
|
||||
verify(writer).write(any(InputStream.class), anyDouble());
|
||||
}
|
||||
verify(writer).close();
|
||||
}
|
||||
@ -62,7 +63,7 @@ public class BinaryFileDownloaderUnitTest {
|
||||
|
||||
assertThrows(IllegalStateException.class, () -> tested.download(url));
|
||||
|
||||
verify(writer, times(0)).write(any(InputStream.class));
|
||||
verify(writer, times(0)).write(any(InputStream.class), anyDouble());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -28,8 +28,8 @@ public class BinaryFileWriterUnitTest {
|
||||
InputStream inputStream = mock(InputStream.class);
|
||||
when(inputStream.read(any(), anyInt(), anyInt())).thenReturn(10, -1);
|
||||
|
||||
try (BinaryFileWriter tested = new BinaryFileWriter(outputStream)) {
|
||||
long result = tested.write(inputStream);
|
||||
try (BinaryFileWriter tested = new BinaryFileWriter(outputStream, progress -> assertEquals(100.0, progress))) {
|
||||
long result = tested.write(inputStream, 10);
|
||||
|
||||
assertEquals(10, result);
|
||||
verify(outputStream).write(any(), eq(0), eq(10));
|
||||
@ -42,8 +42,8 @@ public class BinaryFileWriterUnitTest {
|
||||
public void givenInputStreamEmpty_whenWrite_thenExpectNotWritten() throws Exception {
|
||||
InputStream inputStream = mock(InputStream.class);
|
||||
|
||||
try (BinaryFileWriter tested = new BinaryFileWriter(outputStream)) {
|
||||
long result = tested.write(inputStream);
|
||||
try (BinaryFileWriter tested = new BinaryFileWriter(outputStream, progress -> assertEquals(100.0, progress))) {
|
||||
long result = tested.write(inputStream, 1);
|
||||
|
||||
assertEquals(0, result);
|
||||
verify(outputStream, times(0)).write(any(), anyInt(), anyInt());
|
||||
|
Loading…
x
Reference in New Issue
Block a user