Fix 2.4.2 upgrade notes formatting refs #19330
[arvados.git] / sdk / java-v2 / src / main / java / org / arvados / client / api / client / CountingFileRequestBody.java
1 /*
2  * Copyright (C) The Arvados Authors. All rights reserved.
3  *
4  * SPDX-License-Identifier: AGPL-3.0 OR Apache-2.0
5  *
6  */
7
8 package org.arvados.client.api.client;
9
10 import okhttp3.MediaType;
11 import okhttp3.RequestBody;
12 import okio.BufferedSink;
13 import okio.Okio;
14 import okio.Source;
15 import org.slf4j.Logger;
16
17 import java.io.File;
18
19 /**
20  * Based on:
21  * {@link} https://gist.github.com/eduardb/dd2dc530afd37108e1ac
22  */
23 public class CountingFileRequestBody extends RequestBody {
24
25     private static final int SEGMENT_SIZE = 2048; // okio.Segment.SIZE
26     private static final MediaType CONTENT_BINARY = MediaType.parse(com.google.common.net.MediaType.OCTET_STREAM.toString());
27
28     private final File file;
29     private final ProgressListener listener;
30
31     CountingFileRequestBody(final File file, final ProgressListener listener) {
32         this.file = file;
33         this.listener = listener;
34     }
35
36     @Override
37     public long contentLength() {
38         return file.length();
39     }
40
41     @Override
42     public MediaType contentType() {
43         return CONTENT_BINARY;
44     }
45
46     @Override
47     public void writeTo(BufferedSink sink) {
48         try (Source source = Okio.source(file)) {
49             long total = 0;
50             long read;
51
52             while ((read = source.read(sink.buffer(), SEGMENT_SIZE)) != -1) {
53                 total += read;
54                 sink.flush();
55                 listener.updateProgress(total);
56
57             }
58         } catch (RuntimeException rethrown) {
59             throw rethrown;
60         } catch (Exception ignored) {
61             //ignore
62         }
63     }
64
65     static class TransferData {
66
67         private final Logger log = org.slf4j.LoggerFactory.getLogger(TransferData.class);
68         private int progressValue;
69         private long totalSize;
70
71         TransferData(long totalSize) {
72             this.progressValue = 0;
73             this.totalSize = totalSize;
74         }
75
76         void updateTransferProgress(long transferred) {
77             float progress = (transferred / (float) totalSize) * 100;
78             if (progressValue != (int) progress) {
79                 progressValue = (int) progress;
80                 log.debug("{} / {} / {}%", transferred, totalSize, progressValue);
81             }
82         }
83     }
84 }