-
Notifications
You must be signed in to change notification settings - Fork 149
Expand file tree
/
Copy pathChunkedUploadRequest.java
More file actions
129 lines (111 loc) · 4.42 KB
/
ChunkedUploadRequest.java
File metadata and controls
129 lines (111 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------
package com.microsoft.graph.requests.extensions;
import java.util.List;
import com.microsoft.graph.concurrency.ChunkedUploadResponseHandler;
import com.microsoft.graph.core.ClientException;
import com.microsoft.graph.http.BaseRequest;
import com.microsoft.graph.http.HttpMethod;
import com.microsoft.graph.models.extensions.IGraphServiceClient;
import com.microsoft.graph.options.Option;
/**
* The chunk upload request.
*/
public class ChunkedUploadRequest {
/**
* Content Range header name.
*/
private static final String CONTENT_RANGE_HEADER_NAME = "Content-Range";
/**
* Content Range value format.
*/
private static final String CONTENT_RANGE_FORMAT = "bytes %1$d-%2$d/%3$d";
/**
* The seconds for retry delay.
*/
private static final int RETRY_DELAY = 2 * 1000;
/**
* The chunk data sent to the server.
*/
private final byte[] data;
/**
* The base request.
*/
private final BaseRequest baseRequest;
/**
* The max retry for a single request.
*/
private final int maxRetry;
/**
* The retry counter.
*/
private int retryCount;
/**
* Construct the ChunkedUploadRequest
*
* @param requestUrl The upload URL.
* @param client The Graph client.
* @param options The query options.
* @param chunk The chunk byte array.
* @param chunkSize The chunk array size.
* @param maxRetry The limit on retry.
* @param beginIndex The begin index of this chunk in the input stream.
* @param totalLength The total length of the input stream.
*/
public ChunkedUploadRequest(final String requestUrl,
final IGraphServiceClient client,
final List<? extends Option> options,
final byte[] chunk,
final int chunkSize,
final int maxRetry,
final long beginIndex,
final long totalLength) {
this.data = new byte[chunkSize];
System.arraycopy(chunk, 0, this.data, 0, chunkSize);
this.retryCount = 0;
this.maxRetry = maxRetry;
this.baseRequest = new BaseRequest(requestUrl, client, options, ChunkedUploadResult.class) {
};
this.baseRequest.setHttpMethod(HttpMethod.PUT);
this.baseRequest.addHeader(CONTENT_RANGE_HEADER_NAME,
String.format(
CONTENT_RANGE_FORMAT,
beginIndex,
beginIndex + chunkSize - 1,
totalLength));
}
/**
* Upload a chunk with tries.
*
* @param responseHandler The handler to handle the HTTP response.
* @param <UploadType> The upload item type.
* @return The upload result.
*/
@SuppressWarnings("unchecked")
public <UploadType> ChunkedUploadResult<UploadType> upload(
final ChunkedUploadResponseHandler<UploadType> responseHandler) {
while (this.retryCount < this.maxRetry) {
try {
Thread.sleep(RETRY_DELAY * this.retryCount * this.retryCount);
} catch (final InterruptedException e) {
throw new ClientException("Exception while waiting to retry file upload.", e);
}
ChunkedUploadResult<UploadType> result = null;
try {
result = this.baseRequest
.getClient()
.getHttpProvider()
.send(baseRequest, (Class<ChunkedUploadResult<UploadType>>)(Class<?>) ChunkedUploadResult.class, this.data, responseHandler);
} catch (final ClientException e) {
throw new ClientException("Request failed with error, retry if necessary.", e);
}
if (result != null && result.chunkCompleted()) {
return result;
}
this.retryCount++;
}
return new ChunkedUploadResult<UploadType>(
new ClientException("Upload session failed too many times.", null));
}
}