Skip to content

Commit

Permalink
Merge pull request #725 from aozarov/master
Browse files Browse the repository at this point in the history
Fix writes with 0 length
  • Loading branch information
mziccard committed Mar 8, 2016
2 parents d3224b3 + 36ebabd commit e70387d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,17 @@ public BaseServiceException(IOException exception, boolean idempotent) {
String debugInfo = null;
if (exception instanceof GoogleJsonResponseException) {
GoogleJsonError jsonError = ((GoogleJsonResponseException) exception).getDetails();
Error error = error(jsonError);
code = error.code;
reason = error.reason;
if (reason != null) {
GoogleJsonError.ErrorInfo errorInfo = jsonError.getErrors().get(0);
location = errorInfo.getLocation();
debugInfo = (String) errorInfo.get("debugInfo");
if (jsonError != null) {
Error error = error(jsonError);
code = error.code;
reason = error.reason;
if (reason != null) {
GoogleJsonError.ErrorInfo errorInfo = jsonError.getErrors().get(0);
location = errorInfo.getLocation();
debugInfo = (String) errorInfo.get("debugInfo");
}
} else {
code = ((GoogleJsonResponseException) exception).getStatusCode();
}
}
this.code = code;
Expand Down Expand Up @@ -207,7 +211,10 @@ protected static Error error(GoogleJsonError error) {

protected static String message(IOException exception) {
if (exception instanceof GoogleJsonResponseException) {
return ((GoogleJsonResponseException) exception).getDetails().getMessage();
GoogleJsonError details = ((GoogleJsonResponseException) exception).getDetails();
if (details != null) {
return details.getMessage();
}
}
return exception.getMessage();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import static com.google.gcloud.spi.StorageRpc.Option.PREFIX;
import static com.google.gcloud.spi.StorageRpc.Option.VERSIONS;
import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
import static javax.servlet.http.HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE;

import com.google.api.client.googleapis.batch.json.JsonBatchCallback;
import com.google.api.client.googleapis.json.GoogleJsonError;
Expand Down Expand Up @@ -453,20 +454,32 @@ public Tuple<String, byte[]> read(StorageObject from, Map<Option, ?> options, lo
String etag = req.getLastResponseHeaders().getETag();
return Tuple.of(etag, output.toByteArray());
} catch (IOException ex) {
throw translate(ex);
StorageException serviceException = translate(ex);
if (serviceException.code() == SC_REQUESTED_RANGE_NOT_SATISFIABLE) {
return Tuple.of(null, new byte[0]);
}
throw serviceException;
}
}

@Override
public void write(String uploadId, byte[] toWrite, int toWriteOffset, long destOffset, int length,
boolean last) {
try {
if (length == 0 && !last) {
return;
}
GenericUrl url = new GenericUrl(uploadId);
HttpRequest httpRequest = storage.getRequestFactory().buildPutRequest(url,
new ByteArrayContent(null, toWrite, toWriteOffset, length));
long limit = destOffset + length;
StringBuilder range = new StringBuilder("bytes ");
range.append(destOffset).append('-').append(limit - 1).append('/');
if (length == 0) {
range.append('*');
} else {
range.append(destOffset).append('-').append(limit - 1);
}
range.append('/');
if (last) {
range.append(limit);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public Tuple<String, byte[]> call() {
return storageRpc.read(storageObject, requestOptions, position, toRead);
}
}, serviceOptions.retryParams(), StorageImpl.EXCEPTION_HANDLER);
if (lastEtag != null && !Objects.equals(result.x(), lastEtag)) {
if (result.y().length > 0 && lastEtag != null && !Objects.equals(result.x(), lastEtag)) {
StringBuilder messageBuilder = new StringBuilder();
messageBuilder.append("Blob ").append(blob).append(" was updated while reading");
throw new StorageException(0, messageBuilder.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
Expand Down Expand Up @@ -823,6 +824,33 @@ public void testReadAndWriteChannels() throws IOException {
assertTrue(storage.delete(BUCKET, blobName));
}

@Test
public void testReadAndWriteChannelsWithDifferentFileSize() throws IOException {
String blobNamePrefix = "test-read-and-write-channels-blob-";
int[] blobSizes = {0, 700, 1024 * 256, 2 * 1024 * 1024, 4 * 1024 * 1024, 4 * 1024 * 1024 + 1};
Random rnd = new Random();
for (int blobSize : blobSizes) {
String blobName = blobNamePrefix + blobSize;
BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build();
byte[] bytes = new byte[blobSize];
rnd.nextBytes(bytes);
try (WriteChannel writer = storage.writer(blob)) {
writer.write(ByteBuffer.wrap(bytes));
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
try (ReadChannel reader = storage.reader(blob.blobId())) {
ByteBuffer buffer = ByteBuffer.allocate(64 * 1024);
while (reader.read(buffer) > 0) {
buffer.flip();
output.write(buffer.array(), 0, buffer.limit());
buffer.clear();
}
}
assertArrayEquals(bytes, output.toByteArray());
assertTrue(storage.delete(BUCKET, blobName));
}
}

@Test
public void testReadAndWriteCaptureChannels() throws IOException {
String blobName = "test-read-and-write-capture-channels-blob";
Expand Down

0 comments on commit e70387d

Please sign in to comment.