Skip to content

Commit 6eb78be

Browse files
feat: Support chunk upload session plan API (box/box-openapi#616) (#1979)
1 parent 7312c51 commit 6eb78be

10 files changed

Lines changed: 608 additions & 3 deletions

File tree

.codegen.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "engineHash": "04310d4", "specHash": "be75fa1", "version": "10.16.2" }
1+
{ "engineHash": "04310d4", "specHash": "88cd5aa", "version": "10.16.2" }

docs/chunkeduploads.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ This is a manager for chunked uploads (allowed for files at least 20MB).
1212
- [Remove upload session](#remove-upload-session)
1313
- [List parts by URL](#list-parts-by-url)
1414
- [List parts](#list-parts)
15+
- [Plan upload session by URL](#plan-upload-session-by-url)
16+
- [Plan upload session](#plan-upload-session)
1517
- [Commit upload session by URL](#commit-upload-session-by-url)
1618
- [Commit upload session](#commit-upload-session)
1719
- [Upload big file](#upload-big-file)
@@ -341,6 +343,74 @@ This function returns a value of type `UploadParts`.
341343
Returns a list of parts that have been uploaded.
342344

343345

346+
## Plan upload session by URL
347+
348+
Plan an upload session by checking which parts already exist on the server.
349+
This endpoint allows clients to optimize uploads by skipping parts that
350+
have already been uploaded (cache hits) and only uploading missing parts.
351+
352+
The actual endpoint URL is returned by the [`Create upload session`](e://post-files-upload-sessions)
353+
and [`Get upload session`](e://get-files-upload-sessions-id) endpoints.
354+
355+
This operation is performed by calling function `createFileUploadSessionPlanByUrl`.
356+
357+
See the endpoint docs at
358+
[API Reference](https://developer.box.com/reference/post-files-upload-sessions-id-plan/).
359+
360+
*Currently we don't have an example for calling `createFileUploadSessionPlanByUrl` in integration tests*
361+
362+
### Arguments
363+
364+
- url `String`
365+
- URL of createFileUploadSessionPlan method
366+
- requestBody `UploadSessionPlanRequest`
367+
- Request body of createFileUploadSessionPlan method
368+
- headers `CreateFileUploadSessionPlanByUrlHeaders`
369+
- Headers of createFileUploadSessionPlan method
370+
371+
372+
### Returns
373+
374+
This function returns a value of type `UploadSessionPlanResponse`.
375+
376+
Returns information about which parts already exist (hits)
377+
and which parts need to be uploaded (misses).
378+
379+
380+
## Plan upload session
381+
382+
Plan an upload session by checking which parts already exist on the server.
383+
This endpoint allows clients to optimize uploads by skipping parts that
384+
have already been uploaded (cache hits) and only uploading missing parts.
385+
386+
The actual endpoint URL is returned by the [`Create upload session`](e://post-files-upload-sessions)
387+
and [`Get upload session`](e://get-files-upload-sessions-id) endpoints.
388+
389+
This operation is performed by calling function `createFileUploadSessionPlan`.
390+
391+
See the endpoint docs at
392+
[API Reference](https://developer.box.com/reference/post-files-upload-sessions-id-plan/).
393+
394+
*Currently we don't have an example for calling `createFileUploadSessionPlan` in integration tests*
395+
396+
### Arguments
397+
398+
- uploadSessionId `String`
399+
- The ID of the upload session. Example: "D5E3F7A"
400+
- requestBody `UploadSessionPlanRequest`
401+
- Request body of createFileUploadSessionPlan method
402+
- headers `CreateFileUploadSessionPlanHeaders`
403+
- Headers of createFileUploadSessionPlan method
404+
405+
406+
### Returns
407+
408+
This function returns a value of type `UploadSessionPlanResponse`.
409+
410+
Returns information about which parts already exist (hits)
411+
and which parts need to be uploaded (misses).
412+
413+
344414
## Commit upload session by URL
345415

346416
Close an upload session and create a file from the uploaded chunks.

src/main/java/com/box/sdkgen/managers/chunkeduploads/ChunkedUploadsManager.java

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import com.box.sdkgen.schemas.uploadpart.UploadPart;
2626
import com.box.sdkgen.schemas.uploadparts.UploadParts;
2727
import com.box.sdkgen.schemas.uploadsession.UploadSession;
28+
import com.box.sdkgen.schemas.uploadsessionplanrequest.UploadSessionPlanRequest;
29+
import com.box.sdkgen.schemas.uploadsessionplanresponse.UploadSessionPlanResponse;
2830
import com.box.sdkgen.serialization.json.JsonManager;
2931
import java.io.InputStream;
3032
import java.util.Arrays;
@@ -586,6 +588,121 @@ public UploadParts getFileUploadSessionParts(
586588
return JsonManager.deserialize(response.getData(), UploadParts.class);
587589
}
588590

591+
/**
592+
* Using this method with urls provided in response when creating a new upload session is
593+
* preferred to use over CreateFileUploadSessionPlan method. This allows to always upload your
594+
* content to the closest Box data center and can significantly improve upload speed. Plan an
595+
* upload session by checking which parts already exist on the server. This endpoint allows
596+
* clients to optimize uploads by skipping parts that have already been uploaded (cache hits) and
597+
* only uploading missing parts.
598+
*
599+
* <p>The actual endpoint URL is returned by the [`Create upload
600+
* session`](e://post-files-upload-sessions) and [`Get upload
601+
* session`](e://get-files-upload-sessions-id) endpoints.
602+
*
603+
* @param url URL of createFileUploadSessionPlan method
604+
* @param requestBody Request body of createFileUploadSessionPlan method
605+
*/
606+
public UploadSessionPlanResponse createFileUploadSessionPlanByUrl(
607+
String url, UploadSessionPlanRequest requestBody) {
608+
return createFileUploadSessionPlanByUrl(
609+
url, requestBody, new CreateFileUploadSessionPlanByUrlHeaders());
610+
}
611+
612+
/**
613+
* Using this method with urls provided in response when creating a new upload session is
614+
* preferred to use over CreateFileUploadSessionPlan method. This allows to always upload your
615+
* content to the closest Box data center and can significantly improve upload speed. Plan an
616+
* upload session by checking which parts already exist on the server. This endpoint allows
617+
* clients to optimize uploads by skipping parts that have already been uploaded (cache hits) and
618+
* only uploading missing parts.
619+
*
620+
* <p>The actual endpoint URL is returned by the [`Create upload
621+
* session`](e://post-files-upload-sessions) and [`Get upload
622+
* session`](e://get-files-upload-sessions-id) endpoints.
623+
*
624+
* @param url URL of createFileUploadSessionPlan method
625+
* @param requestBody Request body of createFileUploadSessionPlan method
626+
* @param headers Headers of createFileUploadSessionPlan method
627+
*/
628+
public UploadSessionPlanResponse createFileUploadSessionPlanByUrl(
629+
String url,
630+
UploadSessionPlanRequest requestBody,
631+
CreateFileUploadSessionPlanByUrlHeaders headers) {
632+
Map<String, String> headersMap = prepareParams(mergeMaps(mapOf(), headers.getExtraHeaders()));
633+
FetchResponse response =
634+
this.networkSession
635+
.getNetworkClient()
636+
.fetch(
637+
new FetchOptions.Builder(url, "POST")
638+
.headers(headersMap)
639+
.data(JsonManager.serialize(requestBody))
640+
.contentType("application/json")
641+
.responseFormat(ResponseFormat.JSON)
642+
.auth(this.auth)
643+
.networkSession(this.networkSession)
644+
.build());
645+
return JsonManager.deserialize(response.getData(), UploadSessionPlanResponse.class);
646+
}
647+
648+
/**
649+
* Plan an upload session by checking which parts already exist on the server. This endpoint
650+
* allows clients to optimize uploads by skipping parts that have already been uploaded (cache
651+
* hits) and only uploading missing parts.
652+
*
653+
* <p>The actual endpoint URL is returned by the [`Create upload
654+
* session`](e://post-files-upload-sessions) and [`Get upload
655+
* session`](e://get-files-upload-sessions-id) endpoints.
656+
*
657+
* @param uploadSessionId The ID of the upload session. Example: "D5E3F7A"
658+
* @param requestBody Request body of createFileUploadSessionPlan method
659+
*/
660+
public UploadSessionPlanResponse createFileUploadSessionPlan(
661+
String uploadSessionId, UploadSessionPlanRequest requestBody) {
662+
return createFileUploadSessionPlan(
663+
uploadSessionId, requestBody, new CreateFileUploadSessionPlanHeaders());
664+
}
665+
666+
/**
667+
* Plan an upload session by checking which parts already exist on the server. This endpoint
668+
* allows clients to optimize uploads by skipping parts that have already been uploaded (cache
669+
* hits) and only uploading missing parts.
670+
*
671+
* <p>The actual endpoint URL is returned by the [`Create upload
672+
* session`](e://post-files-upload-sessions) and [`Get upload
673+
* session`](e://get-files-upload-sessions-id) endpoints.
674+
*
675+
* @param uploadSessionId The ID of the upload session. Example: "D5E3F7A"
676+
* @param requestBody Request body of createFileUploadSessionPlan method
677+
* @param headers Headers of createFileUploadSessionPlan method
678+
*/
679+
public UploadSessionPlanResponse createFileUploadSessionPlan(
680+
String uploadSessionId,
681+
UploadSessionPlanRequest requestBody,
682+
CreateFileUploadSessionPlanHeaders headers) {
683+
Map<String, String> headersMap = prepareParams(mergeMaps(mapOf(), headers.getExtraHeaders()));
684+
FetchResponse response =
685+
this.networkSession
686+
.getNetworkClient()
687+
.fetch(
688+
new FetchOptions.Builder(
689+
String.join(
690+
"",
691+
this.networkSession.getBaseUrls().getUploadUrl(),
692+
"/2.0/files/upload_sessions/",
693+
convertToString(uploadSessionId),
694+
"/plan"),
695+
"POST")
696+
.headers(headersMap)
697+
.data(JsonManager.serialize(requestBody))
698+
.contentType("application/json")
699+
.responseFormat(ResponseFormat.JSON)
700+
.auth(this.auth)
701+
.networkSession(this.networkSession)
702+
.build());
703+
return JsonManager.deserialize(response.getData(), UploadSessionPlanResponse.class);
704+
}
705+
589706
/**
590707
* Using this method with urls provided in response when creating a new upload session is
591708
* preferred to use over CreateFileUploadSessionCommit method. This allows to always upload your
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.box.sdkgen.managers.chunkeduploads;
2+
3+
import static com.box.sdkgen.internal.utils.UtilsManager.mapOf;
4+
5+
import java.util.Map;
6+
7+
public class CreateFileUploadSessionPlanByUrlHeaders {
8+
9+
/** Extra headers that will be included in the HTTP request. */
10+
public Map<String, String> extraHeaders;
11+
12+
public CreateFileUploadSessionPlanByUrlHeaders() {
13+
this.extraHeaders = mapOf();
14+
}
15+
16+
protected CreateFileUploadSessionPlanByUrlHeaders(Builder builder) {
17+
this.extraHeaders = builder.extraHeaders;
18+
}
19+
20+
public Map<String, String> getExtraHeaders() {
21+
return extraHeaders;
22+
}
23+
24+
public static class Builder {
25+
26+
protected Map<String, String> extraHeaders;
27+
28+
public Builder() {}
29+
30+
public Builder extraHeaders(Map<String, String> extraHeaders) {
31+
this.extraHeaders = extraHeaders;
32+
return this;
33+
}
34+
35+
public CreateFileUploadSessionPlanByUrlHeaders build() {
36+
if (this.extraHeaders == null) {
37+
this.extraHeaders = mapOf();
38+
}
39+
return new CreateFileUploadSessionPlanByUrlHeaders(this);
40+
}
41+
}
42+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.box.sdkgen.managers.chunkeduploads;
2+
3+
import static com.box.sdkgen.internal.utils.UtilsManager.mapOf;
4+
5+
import java.util.Map;
6+
7+
public class CreateFileUploadSessionPlanHeaders {
8+
9+
/** Extra headers that will be included in the HTTP request. */
10+
public Map<String, String> extraHeaders;
11+
12+
public CreateFileUploadSessionPlanHeaders() {
13+
this.extraHeaders = mapOf();
14+
}
15+
16+
protected CreateFileUploadSessionPlanHeaders(Builder builder) {
17+
this.extraHeaders = builder.extraHeaders;
18+
}
19+
20+
public Map<String, String> getExtraHeaders() {
21+
return extraHeaders;
22+
}
23+
24+
public static class Builder {
25+
26+
protected Map<String, String> extraHeaders;
27+
28+
public Builder() {}
29+
30+
public Builder extraHeaders(Map<String, String> extraHeaders) {
31+
this.extraHeaders = extraHeaders;
32+
return this;
33+
}
34+
35+
public CreateFileUploadSessionPlanHeaders build() {
36+
if (this.extraHeaders == null) {
37+
this.extraHeaders = mapOf();
38+
}
39+
return new CreateFileUploadSessionPlanHeaders(this);
40+
}
41+
}
42+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.box.sdkgen.schemas.uploadpartplan;
2+
3+
import com.box.sdkgen.internal.SerializableObject;
4+
import com.fasterxml.jackson.annotation.JsonFilter;
5+
import com.fasterxml.jackson.annotation.JsonProperty;
6+
import java.util.Objects;
7+
8+
/** Represents a planned upload part with `SHA-512` hash for upload session planning. */
9+
@JsonFilter("nullablePropertyFilter")
10+
public class UploadPartPlan extends SerializableObject {
11+
12+
/**
13+
* The offset of the chunk within the file in bytes. The lower bound of the position of the chunk
14+
* within the file.
15+
*/
16+
protected final long offset;
17+
18+
/** The size of the chunk in bytes. */
19+
protected final long size;
20+
21+
/** The `SHA-512` hash of the chunk. */
22+
protected final String sha512;
23+
24+
public UploadPartPlan(
25+
@JsonProperty("offset") long offset,
26+
@JsonProperty("size") long size,
27+
@JsonProperty("sha512") String sha512) {
28+
super();
29+
this.offset = offset;
30+
this.size = size;
31+
this.sha512 = sha512;
32+
}
33+
34+
public long getOffset() {
35+
return offset;
36+
}
37+
38+
public long getSize() {
39+
return size;
40+
}
41+
42+
public String getSha512() {
43+
return sha512;
44+
}
45+
46+
@Override
47+
public boolean equals(Object o) {
48+
if (this == o) {
49+
return true;
50+
}
51+
if (o == null || getClass() != o.getClass()) {
52+
return false;
53+
}
54+
UploadPartPlan casted = (UploadPartPlan) o;
55+
return Objects.equals(offset, casted.offset)
56+
&& Objects.equals(size, casted.size)
57+
&& Objects.equals(sha512, casted.sha512);
58+
}
59+
60+
@Override
61+
public int hashCode() {
62+
return Objects.hash(offset, size, sha512);
63+
}
64+
65+
@Override
66+
public String toString() {
67+
return "UploadPartPlan{"
68+
+ "offset='"
69+
+ offset
70+
+ '\''
71+
+ ", "
72+
+ "size='"
73+
+ size
74+
+ '\''
75+
+ ", "
76+
+ "sha512='"
77+
+ sha512
78+
+ '\''
79+
+ "}";
80+
}
81+
}

0 commit comments

Comments
 (0)