Skip to content
This repository was archived by the owner on Dec 6, 2024. It is now read-only.

Commit 985b4b9

Browse files
SynapticloopSynapticloop
authored andcommitted
Merge branch 'large-file-support'
2 parents 2d4b3ea + 6404ba8 commit 985b4b9

31 files changed

+702
-47
lines changed

src/main/java/synapticloop/b2/B2ApiClient.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@
4242
import synapticloop.b2.request.B2ListBucketsRequest;
4343
import synapticloop.b2.request.B2ListFileNamesRequest;
4444
import synapticloop.b2.request.B2ListFileVersionsRequest;
45+
import synapticloop.b2.request.B2RequestProperties;
4546
import synapticloop.b2.request.B2UpdateBucketRequest;
4647
import synapticloop.b2.request.B2UploadFileRequest;
47-
import synapticloop.b2.request.BaseB2Request;
4848
import synapticloop.b2.response.B2AuthorizeAccountResponse;
4949
import synapticloop.b2.response.B2BucketResponse;
5050
import synapticloop.b2.response.B2DeleteFileVersionResponse;
@@ -67,8 +67,21 @@ public class B2ApiClient {
6767

6868
private final CloseableHttpClient client;
6969

70+
/**
71+
* Create a B2ApiClient and authenticate
72+
*
73+
* @param accountId The account id
74+
* @param applicationKey the application key
75+
* @throws B2ApiException if there was an error authenticating the account
76+
*/
77+
public B2ApiClient(String accountId, String applicationKey) throws B2ApiException {
78+
this();
79+
this.b2AuthorizeAccountResponse = authenticate(accountId, applicationKey);
80+
}
81+
7082
/**
7183
* Must authenticate first before API actions are available. Using default HTTP client configuration
84+
*
7285
* @see #authenticate(String, String)
7386
*/
7487
public B2ApiClient() {
@@ -177,7 +190,7 @@ public B2BucketResponse deleteBucket(String bucketId) throws B2ApiException {
177190
*/
178191
public B2BucketResponse deleteBucketFully(String bucketId) throws B2ApiException {
179192
B2ListFilesResponse b2ListFilesResponse = new B2ListFileVersionsRequest(client, b2AuthorizeAccountResponse, bucketId,
180-
BaseB2Request.MAX_FILE_COUNT_RETURN).getResponse();
193+
B2RequestProperties.MAX_FILE_COUNT_RETURN).getResponse();
181194
String nextFileName = b2ListFilesResponse.getNextFileName();
182195
String nextFileId = b2ListFilesResponse.getNextFileId();
183196
while(true) {
@@ -191,7 +204,7 @@ public B2BucketResponse deleteBucketFully(String bucketId) throws B2ApiException
191204
break;
192205
} else {
193206
b2ListFilesResponse = new B2ListFileVersionsRequest(client, b2AuthorizeAccountResponse, bucketId,
194-
BaseB2Request.MAX_FILE_COUNT_RETURN, nextFileName, nextFileId).getResponse();
207+
B2RequestProperties.MAX_FILE_COUNT_RETURN, nextFileName, nextFileId).getResponse();
195208
nextFileName = b2ListFilesResponse.getNextFileName();
196209
nextFileId = b2ListFilesResponse.getNextFileId();
197210
}
@@ -330,7 +343,7 @@ public B2FileResponse uploadFile(String bucketId, String fileName, File file, St
330343
*/
331344

332345
public B2FileResponse uploadFile(String bucketId, String fileName, File file, Map<String, String> fileInfo) throws B2ApiException {
333-
B2GetUploadUrlResponse b2GetUploadUrlResponse = new B2GetUploadUrlRequest(client, b2AuthorizeAccountResponse, bucketId, fileInfo).getResponse();
346+
B2GetUploadUrlResponse b2GetUploadUrlResponse = new B2GetUploadUrlRequest(client, b2AuthorizeAccountResponse, bucketId).getResponse();
334347
return new B2UploadFileRequest(client, b2AuthorizeAccountResponse, b2GetUploadUrlResponse, fileName, file, fileInfo).getResponse();
335348
}
336349

src/main/java/synapticloop/b2/io/HttpMethodReleaseInputStream.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ public class HttpMethodReleaseInputStream extends CountingInputStream {
3131
private HttpResponse response;
3232

3333
/**
34+
* Create a HTTP method release input Stream
35+
*
3436
* @param response The HTTP response to read from
37+
*
3538
* @throws IOException If there is a problem reading from the response
3639
* @throws NullPointerException If the response has no message entity
3740
*/
@@ -54,8 +57,7 @@ public void close() throws IOException {
5457
if(read == response.getEntity().getContentLength()) {
5558
// Fully consumed
5659
super.close();
57-
}
58-
else {
60+
} else {
5961
if(LOGGER.isLoggable(Level.WARNING)) {
6062
LOGGER.warning(String.format("Abort connection for response '{}'", response));
6163
}
@@ -66,8 +68,7 @@ public void close() throws IOException {
6668
// The response proxy will force close the connection.
6769
((CloseableHttpResponse) response).close();
6870
}
69-
}
70-
else {
71+
} else {
7172
// Consume and close
7273
super.close();
7374
}

src/main/java/synapticloop/b2/request/B2AuthorizeAccountRequest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@
3232
* used for account-level operations, and a URL that should be used as the base
3333
* URL for subsequent API calls.</p>
3434
*
35+
* An HTTP basic auth value constructed as follows:
36+
* <ul>
37+
* <li>The B2 account id and B2 application key for the account are combined
38+
* into a string in the format "accountId:applicationKey".</li>
39+
* <li>The combined string is Base64 encoded.</li>
40+
* <li>"Basic " is put before the encoded string.</li>
41+
* </ul>
42+
*
3543
* This is the interaction class for the <strong>b2_authorize_account</strong> api
3644
* calls, this was generated from the backblaze api documentation - which can be
3745
* found here:
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package synapticloop.b2.request;
2+
3+
import java.io.IOException;
4+
5+
import org.apache.http.impl.client.CloseableHttpClient;
6+
import org.apache.http.util.EntityUtils;
7+
8+
import synapticloop.b2.exception.B2ApiException;
9+
import synapticloop.b2.response.B2AuthorizeAccountResponse;
10+
import synapticloop.b2.response.B2FileResponse;
11+
12+
/**
13+
* <p>Cancels the upload of a large file, and deletes all of the parts that have been uploaded.</p>
14+
*
15+
* <p>This will return an error if there is no active upload with the given file ID.</p>
16+
*
17+
* This is the interaction class for the <strong>b2_cancel_large_file</strong> api
18+
* calls, this was generated from the backblaze api documentation - which can be
19+
* found here:
20+
*
21+
* <a href="https://www.backblaze.com/b2/docs/b2_cancel_large_file.html">https://www.backblaze.com/b2/docs/b2_cancel_large_file.html</a>
22+
*
23+
* @author synapticloop
24+
*
25+
*/
26+
27+
public class B2CancelLargeFileRequest extends BaseB2Request {
28+
private static final String B2_CANCEL_LARGE_FILE = BASE_API + "b2_cancel_large_file";
29+
30+
/**
31+
* Create a cancel large file request
32+
*
33+
* @param client The HTTP client to use
34+
* @param b2AuthorizeAccountResponse the authorize account response
35+
* @param fileId The ID returned by B2StartLargeFileRequest.
36+
*
37+
* {@link B2StartLargeFileRequest}
38+
*/
39+
protected B2CancelLargeFileRequest(CloseableHttpClient client, B2AuthorizeAccountResponse b2AuthorizeAccountResponse, String fileId) {
40+
super(client, b2AuthorizeAccountResponse, b2AuthorizeAccountResponse.getApiUrl() + B2_CANCEL_LARGE_FILE);
41+
42+
requestBodyData.put(B2RequestProperties.KEY_FILE_ID, fileId);
43+
}
44+
45+
/**
46+
* Get the file response
47+
*
48+
* @return the B2 File response
49+
*
50+
* @throws B2ApiException if there was an error retrieving the response
51+
*/
52+
public B2FileResponse getResponse() throws B2ApiException {
53+
try {
54+
return(new B2FileResponse(EntityUtils.toString(executePost().getEntity())));
55+
} catch(IOException e) {
56+
throw new B2ApiException(e);
57+
}
58+
}
59+
}

src/main/java/synapticloop/b2/request/B2DeleteBucketRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public class B2DeleteBucketRequest extends BaseB2Request {
4444
*
4545
* @param client Shared HTTP client instance
4646
* @param b2AuthorizeAccountResponse the authorize account response
47-
* @param bucketId the id of the bucket to delete
47+
* @param bucketId The id of the bucket to delete
4848
*/
4949
public B2DeleteBucketRequest(CloseableHttpClient client, B2AuthorizeAccountResponse b2AuthorizeAccountResponse, String bucketId) {
5050

src/main/java/synapticloop/b2/request/B2DeleteFileVersionRequest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,15 @@
2929
/**
3030
* <p>Deletes one version of a file from B2.</p>
3131
*
32-
* <p>If the version you delete is the latest version, and there are older versions, then the most recent older version will become the current version, and be the one that you'll get when downloading by name. See the File Versions page for more details.</p>
32+
* <p>If the version you delete is the latest version, and there are older
33+
* versions, then the most recent older version will become the current
34+
* version, and be the one that you'll get when downloading by name. See
35+
* the <a href="https://www.backblaze.com/b2/docs/file_versions.html">File Versions</a> page for more details.</p>
3336
*
3437
*
3538
* This is the interaction class for the <strong>b2_delete_file_version</strong> api calls, this was
3639
* generated from the backblaze api documentation - which can be found here:
40+
*
3741
* <a href="http://www.backblaze.com/b2/docs/b2_delete_file_version.html">http://www.backblaze.com/b2/docs/b2_delete_file_version.html</a>
3842
*
3943
* @author synapticloop
@@ -46,9 +50,9 @@ public class B2DeleteFileVersionRequest extends BaseB2Request {
4650
*
4751
* @param client Shared HTTP client instance
4852
* @param b2AuthorizeAccountResponse the authorize account response
49-
* @param fileName the name of the file to delete
53+
* @param fileName the name (and path) of the file to delete
5054
* @param fileId The ID of the file, as returned by {@link B2UploadFileRequest},
51-
* {@link B2ListFileNamesRequest}, or {@link B2ListFileVersionsRequest}..
55+
* {@link B2ListFileNamesRequest}, or {@link B2ListFileVersionsRequest}.
5256
*/
5357
public B2DeleteFileVersionRequest(CloseableHttpClient client, B2AuthorizeAccountResponse b2AuthorizeAccountResponse, String fileName, String fileId) {
5458

@@ -59,7 +63,7 @@ public B2DeleteFileVersionRequest(CloseableHttpClient client, B2AuthorizeAccount
5963
}
6064

6165
/**
62-
* Return the http response for the call
66+
* Return the response for the call
6367
*
6468
* @return the delete file version response
6569
*

src/main/java/synapticloop/b2/request/B2DownloadFileByIdRequest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,25 @@
2828
*
2929
* <p>The response contains the following headers, which contain the same information they did when the file was uploaded:</p>
3030
*
31+
* <ul>
32+
* <li>Content-Length</li>
33+
* <li>Content-Type</li>
34+
* <li>X-Bz-File-Id</li>
35+
* <li>X-Bz-File-Name</li>
36+
* <li>X-Bz-Content-Sha1</li>
37+
* <li>X-Bz-Info-*</li>
38+
* </ul>
39+
*
40+
* <p>HEAD requests are also supported, and work just like a GET, except that the
41+
* body of the response is not included. All of the same headers, including
42+
* Content-Length are returned. See the B2HeadFileByIdRequest</p>
43+
*
44+
* <p>If the bucket containing the file is set to require authorization, then you
45+
* must supply the bucket's auth token in the Authorzation header.</p>
46+
*
47+
* <p>Because errors can happen in network transmission, you should check the
48+
* SHA1 of the data you receive against the SHA1 returned in the
49+
* X-Bz-Content-Sha1 header.</p>
3150
*
3251
* This is the interaction class for the <strong>b2_download_file_by_id</strong> api calls, this was
3352
* generated from the backblaze api documentation - which can be found here:

src/main/java/synapticloop/b2/request/B2DownloadFileByNameRequest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,40 @@
3939
*/
4040
public class B2DownloadFileByNameRequest extends BaseB2Request {
4141

42+
/**
43+
* Create a download file by name request
44+
*
45+
* @param client The http client to use
46+
* @param b2AuthorizeAccountResponse the authorize account response
47+
* @param bucketName the name of the bucket
48+
* @param fileName the name and path of the file
49+
*/
4250
public B2DownloadFileByNameRequest(CloseableHttpClient client, B2AuthorizeAccountResponse b2AuthorizeAccountResponse, String bucketName, String fileName) {
4351
super(client,
4452
b2AuthorizeAccountResponse,
4553
b2AuthorizeAccountResponse.getDownloadUrl() + "/file/" + Helper.urlEncode(bucketName) + "/" + Helper.urlEncodeFileName(fileName));
4654
}
4755

56+
/**
57+
* Create a download file by name request with a specified range
58+
*
59+
* A standard byte-range request, which will return just part of the stored file.
60+
*
61+
* The value "bytes=0-99" selects bytes 0 through 99 (inclusive) of the file,
62+
* so it will return the first 100 bytes. Valid byte ranges will cause the
63+
* response to contain a Content-Range header that specifies which bytes
64+
* are returned. Invalid byte ranges will just return the whole file.
65+
*
66+
* Note that the SHA1 checksum returned is still the checksum for the entire
67+
* file, so it cannot be used on the byte range.
68+
*
69+
* @param client The http client to use
70+
* @param b2AuthorizeAccountResponse the authorize account response
71+
* @param bucketName the name of the bucket
72+
* @param fileName the name and path of the file
73+
* @param rangeStart the range start of the partial file contents
74+
* @param rangeEnd the range end of the partial file contents
75+
*/
4876
public B2DownloadFileByNameRequest(CloseableHttpClient client, B2AuthorizeAccountResponse b2AuthorizeAccountResponse, String bucketName, String fileName, long rangeStart, long rangeEnd) {
4977
this(client, b2AuthorizeAccountResponse, bucketName, fileName);
5078
requestHeaders.put(HttpHeaders.RANGE, "bytes=" + rangeStart + "-" + rangeEnd);

src/main/java/synapticloop/b2/request/B2GetFileInfoRequest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ public class B2GetFileInfoRequest extends BaseB2Request {
4343
*
4444
* @param client Shared HTTP client instance
4545
* @param b2AuthorizeAccountResponse the authorize account response
46-
* @param fileId the id for the file
46+
* @param fileId The ID of the file, as returned by b2_upload_file, b2_list_file_names, or b2_list_file_versions.
47+
*
48+
* {@link B2UploadFileRequest}
49+
* {@link B2ListFileNamesRequest}
50+
* {@link B2ListFileVersionsRequest}
4751
*/
4852
public B2GetFileInfoRequest(CloseableHttpClient client, B2AuthorizeAccountResponse b2AuthorizeAccountResponse, String fileId) {
4953
super(client, b2AuthorizeAccountResponse, b2AuthorizeAccountResponse.getApiUrl() + B2_GET_FILE_INFO);

src/main/java/synapticloop/b2/request/B2GetUploadUrlRequest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
*/
1818

1919
import java.io.IOException;
20-
import java.util.Map;
2120

2221
import org.apache.http.impl.client.CloseableHttpClient;
2322
import org.apache.http.util.EntityUtils;
@@ -42,18 +41,19 @@
4241
public class B2GetUploadUrlRequest extends BaseB2Request {
4342
private static final String B2_GET_UPLOAD_URL = BASE_API_VERSION + "b2_get_upload_url";
4443

44+
/**
45+
* Instantiate a get upload URL request
46+
*
47+
* @param client the HTTP client to use
48+
* @param b2AuthorizeAccountResponse the authorize account response
49+
* @param bucketId The ID of the bucket that you want to upload to.
50+
*/
4551
public B2GetUploadUrlRequest(CloseableHttpClient client, B2AuthorizeAccountResponse b2AuthorizeAccountResponse, String bucketId) {
4652
super(client, b2AuthorizeAccountResponse, b2AuthorizeAccountResponse.getApiUrl() + B2_GET_UPLOAD_URL);
4753

4854
requestBodyData.put(B2RequestProperties.KEY_BUCKET_ID, bucketId);
4955
}
5056

51-
public B2GetUploadUrlRequest(CloseableHttpClient client, B2AuthorizeAccountResponse b2AuthorizeAccountResponse, String bucketId, Map<String, String> fileInfo) {
52-
super(client, b2AuthorizeAccountResponse, b2AuthorizeAccountResponse.getApiUrl() + B2_GET_UPLOAD_URL);
53-
54-
requestBodyData.put(B2RequestProperties.KEY_BUCKET_ID, bucketId);
55-
}
56-
5757
/**
5858
* Return the upload url response
5959
*

0 commit comments

Comments
 (0)