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

Commit 32d0991

Browse files
SynapticloopSynapticloop
authored andcommitted
added ranges to the methods, updated documentation
1 parent 0a189b6 commit 32d0991

File tree

7 files changed

+456
-78
lines changed

7 files changed

+456
-78
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ group = 'synapticloop'
1111
archivesBaseName = 'backblaze-b2-java-api'
1212
description = """An api for backblaze b2 storage in java"""
1313

14-
version = 'v1.0.2'
14+
version = 'v1.1.0'
1515

1616
description = """backblaze-b2-java-api"""
1717

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

Lines changed: 279 additions & 38 deletions
Large diffs are not rendered by default.

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,49 @@
2020
public class B2DownloadFileByIdRequest extends BaseB2Request {
2121
private static final String B2_DOWNLOAD_FILE_BY_ID = BASE_API_VERSION + "b2_download_file_by_id";
2222

23+
/**
24+
* Create a download file by ID request to download the complete file
25+
*
26+
* @param b2AuthorizeAccountResponse The authorize account response
27+
* @param fileId the unique id of the file
28+
*/
2329
public B2DownloadFileByIdRequest(B2AuthorizeAccountResponse b2AuthorizeAccountResponse, String fileId) {
2430
super(b2AuthorizeAccountResponse);
2531
url = b2AuthorizeAccountResponse.getDownloadUrl() + B2_DOWNLOAD_FILE_BY_ID;
2632
parameters.put(KEY_FILE_ID, fileId);
2733
}
2834

35+
/**
36+
* Create a download file by ID request to download the range of bytes
37+
* between rangeStart and rangeEnd (inclusive)
38+
*
39+
* A standard byte-range request, which will return just part of the stored file.
40+
*
41+
* The value "bytes=0-99" selects bytes 0 through 99 (inclusive) of the file,
42+
* so it will return the first 100 bytes. Valid byte ranges will cause the
43+
* response to contain a Content-Range header that specifies which bytes are
44+
* returned. Invalid byte ranges will just return the whole file.
45+
*
46+
* Note that the SHA1 checksum returned is still the checksum for the entire
47+
* file, so it cannot be used on the byte range.
48+
*
49+
* @param b2AuthorizeAccountResponse The authorize account response
50+
* @param fileId the unique id of the file
51+
* @param rangeStart the start of the range
52+
* @param rangeEnd the end of the range
53+
*/
54+
public B2DownloadFileByIdRequest(B2AuthorizeAccountResponse b2AuthorizeAccountResponse, String fileId, long rangeStart, long rangeEnd) {
55+
this(b2AuthorizeAccountResponse, fileId);
56+
unencodedHeaders.put(KEY_RANGE, "bytes=" + rangeStart + "-" + rangeEnd);
57+
}
58+
59+
/**
60+
* Execute the request and return the response
61+
*
62+
* @return The download file response
63+
*
64+
* @throws B2ApiException If there was an error with the call
65+
*/
2966
public B2DownloadFileResponse getResponse() throws B2ApiException {
3067
return(new B2DownloadFileResponse(executeGetWithData()));
3168
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public B2DownloadFileByNameRequest(B2AuthorizeAccountResponse b2AuthorizeAccount
2626
url = b2AuthorizeAccountResponse.getDownloadUrl() + "/file/" + Helper.urlEncode(bucketName) + "/" + Helper.urlEncode(fileName);
2727
}
2828

29+
public B2DownloadFileByNameRequest(B2AuthorizeAccountResponse b2AuthorizeAccountResponse, String bucketName, String fileName, long rangeStart, long rangeEnd) {
30+
this(b2AuthorizeAccountResponse, bucketName, fileName);
31+
unencodedHeaders.put(KEY_RANGE, "bytes=" + rangeStart + "-" + rangeEnd);
32+
}
33+
2934
public B2DownloadFileResponse getResponse() throws B2ApiException {
3035
return(new B2DownloadFileResponse(executeGetWithData()));
3136
}

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

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import synapticloop.b2.util.Helper;
3131

3232
public class BaseB2Request {
33-
private static final Logger LOG = LoggerFactory.getLogger(BaseB2Request.class);
33+
private static final Logger LOGGER = LoggerFactory.getLogger(BaseB2Request.class);
3434

3535
protected static final String BASE_API_HOST = "https://api.backblaze.com";
3636
protected static final String BASE_API_VERSION = "/b2api/v1/";
@@ -53,6 +53,7 @@ public class BaseB2Request {
5353
protected static final String KEY_FILE_ID = "fileId";
5454
protected static final String KEY_FILE_NAME = "fileName";
5555
protected static final String KEY_MAX_FILE_COUNT = "maxFileCount";
56+
protected static final String KEY_RANGE = "Range";
5657
protected static final String KEY_START_FILE_ID = "startFileId";
5758
protected static final String KEY_START_FILE_NAME = "startFileName";
5859

@@ -100,15 +101,15 @@ protected CloseableHttpResponse executeHead() throws B2ApiException {
100101
try {
101102
URI uri = getUri();
102103

103-
LOG.debug("HEAD request to URL '{}'", uri.toString());
104+
LOGGER.debug("HEAD request to URL '{}'", uri.toString());
104105

105106
HttpHead httpHead = new HttpHead(uri);
106107
setHeaders(httpHead);
107108

108109
CloseableHttpResponse httpResponse = closeableHttpClient.execute(httpHead);
109110
int statusCode = httpResponse.getStatusLine().getStatusCode();
110111

111-
LOG.debug("Received status code of: {}, for HEAD request to url '{}'", statusCode, uri);
112+
LOGGER.debug("Received status code of: {}, for HEAD request to url '{}'", statusCode, uri);
112113

113114
if(statusCode != 200) {
114115
throw new B2ApiException("Received non 'OK' status code of " + statusCode + " for request.");
@@ -121,7 +122,7 @@ protected CloseableHttpResponse executeHead() throws B2ApiException {
121122
}
122123

123124
/**
124-
* Execute a GET request
125+
* Execute a GET request, returning the string representation of the response
125126
*
126127
* @return The response from the GET request
127128
*
@@ -136,16 +137,17 @@ protected String executeGet() throws B2ApiException {
136137
HttpGet httpGet = new HttpGet(uri);
137138
setHeaders(httpGet);
138139

139-
LOG.debug("GET request to URL '{}'", url);
140+
LOGGER.debug("GET request to URL '{}'", url);
140141

141142

142143
CloseableHttpResponse httpResponse = closeableHttpClient.execute(httpGet);
143144
int statusCode = httpResponse.getStatusLine().getStatusCode();
144145
String response = EntityUtils.toString(httpResponse.getEntity());
145146

146-
LOG.debug("Received status code of: {}, for GET request to url '{}'", statusCode, url);
147+
LOGGER.debug("Received status code of: {}, for GET request to url '{}'", statusCode, url);
147148

148-
if(statusCode != 200) {
149+
// you will either get an OK or a partial content
150+
if(statusCode != 200 && statusCode != 206) {
149151
throw new B2ApiException(response);
150152
} else {
151153
return(response);
@@ -156,23 +158,32 @@ protected String executeGet() throws B2ApiException {
156158
}
157159

158160

161+
/**
162+
* Execute a GET request, returning the data stream from the response.
163+
*
164+
* @return the response from the get request
165+
*
166+
* @throws B2ApiException if there was an error with the call, most notably
167+
* a non OK status code (i.e. not 200)
168+
*/
159169
protected CloseableHttpResponse executeGetWithData() throws B2ApiException {
160170
CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
161171

162172
try {
163173
URI uri = getUri();
164174

165-
LOG.debug("GET request to URL '{}'", uri.toString());
175+
LOGGER.debug("GET request to URL '{}'", uri.toString());
166176

167177
HttpGet httpGet = new HttpGet(uri);
168178
setHeaders(httpGet);
169179

170180
CloseableHttpResponse httpResponse = closeableHttpClient.execute(httpGet);
171181
int statusCode = httpResponse.getStatusLine().getStatusCode();
172182

173-
LOG.debug("Received status code of: {}, for GET request to url '{}'", statusCode, url);
183+
LOGGER.debug("Received status code of: {}, for GET request to url '{}'", statusCode, url);
174184

175-
if(statusCode != 200) {
185+
// you will either get an OK or a partial content
186+
if(statusCode != 200 && statusCode != 206) {
176187
throw new B2ApiException("Received non 'OK' status code of " + statusCode + " for request.");
177188
} else {
178189
return(httpResponse);
@@ -182,21 +193,29 @@ protected CloseableHttpResponse executeGetWithData() throws B2ApiException {
182193
}
183194
}
184195

196+
/**
197+
* Execute a POST request returning the response data as a String
198+
*
199+
* @return the response data as a string
200+
*
201+
* @throws B2ApiException if there was an error with the call, most notably
202+
* a non OK status code (i.e. not 200)
203+
*/
185204
protected String executePost() throws B2ApiException {
186205
CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
187206
String postData = convertPostData();
188207
HttpPost httpPost = new HttpPost(url);
189208

190209
setHeaders(httpPost);
191210

192-
LOG.debug("POST request to URL '{}', with data of '{}'", url, postData);
211+
LOGGER.debug("POST request to URL '{}', with data of '{}'", url, postData);
193212

194213
try {
195214
httpPost.setEntity(new StringEntity(postData));
196215
CloseableHttpResponse httpResponse = closeableHttpClient.execute(httpPost);
197216
int statusCode = httpResponse.getStatusLine().getStatusCode();
198217

199-
LOG.debug("Received status code of: {}, for POST request to url '{}'", statusCode, url);
218+
LOGGER.debug("Received status code of: {}, for POST request to url '{}'", statusCode, url);
200219

201220
String response = EntityUtils.toString(httpResponse.getEntity());
202221

@@ -215,21 +234,31 @@ protected String executePost() throws B2ApiException {
215234
}
216235
}
217236

237+
/**
238+
* Execute a POST request with the contents of a file.
239+
*
240+
* @param file the file to post
241+
*
242+
* @return the string representation of the response
243+
*
244+
* @throws B2ApiException if there was an error with the call, most notably
245+
* a non OK status code (i.e. not 200)
246+
*/
218247
protected String executePost(File file) throws B2ApiException {
219248
CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
220249
HttpPost httpPost = new HttpPost(url);
221250

222251
setHeaders(httpPost);
223252

224-
LOG.debug("POST request to URL '{}', with file", url);
253+
LOGGER.debug("POST request to URL '{}', with file", url);
225254

226255
try {
227256
httpPost.setEntity(new FileEntity(file));
228257
CloseableHttpResponse httpResponse = closeableHttpClient.execute(httpPost);
229258
int statusCode = httpResponse.getStatusLine().getStatusCode();
230259
String response = EntityUtils.toString(httpResponse.getEntity());
231260

232-
LOG.debug("Received status code of: {}, for POST request to url '{}'", statusCode, url);
261+
LOGGER.debug("Received status code of: {}, for POST request to url '{}'", statusCode, url);
233262

234263
if(statusCode != 200) {
235264
throw new B2ApiException(response);
@@ -298,7 +327,8 @@ private URI getUri() throws URISyntaxException {
298327
/**
299328
* Set the headers safely, go through the headers Map and add them to the http
300329
* request with properly encode values. If they already exist on the http
301-
* request, it will be ignored.
330+
* request, it will be ignored. Then go through the unencodedHeaders Map and
331+
* add them to the http request with no encoding done on the header values.
302332
*
303333
* To over-ride what headers are set, this should be done in the constructor
304334
* of the base request object.
@@ -309,14 +339,15 @@ private void setHeaders(HttpRequestBase httpRequestBase) {
309339
Set<String> headerKeySet = headers.keySet();
310340
for (String headerKey : headerKeySet) {
311341
if(!httpRequestBase.containsHeader(headerKey)) {
312-
LOG.trace("Setting header '" + headerKey + "'.");
342+
LOGGER.trace("Setting header (encoded) '" + headerKey + "'.");
313343
httpRequestBase.setHeader(headerKey, Helper.urlEncode(headers.get(headerKey)));
314344
}
315345
}
346+
316347
headerKeySet = unencodedHeaders.keySet();
317348
for (String headerKey : headerKeySet) {
318349
if(!httpRequestBase.containsHeader(headerKey)) {
319-
LOG.trace("Setting unencoded header '" + headerKey + "'.");
350+
LOGGER.trace("Setting header (un-encoded) '" + headerKey + "'.");
320351
httpRequestBase.setHeader(headerKey, unencodedHeaders.get(headerKey));
321352
}
322353
}

0 commit comments

Comments
 (0)