Skip to content

Commit a4c4273

Browse files
committed
Merge pull request #380 from mziccard/fix-delete-batch
Update batch delete to return false on not found
2 parents 101048e + 1e7fe54 commit a4c4273

7 files changed

Lines changed: 59 additions & 49 deletions

File tree

gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import static com.google.gcloud.spi.StorageRpc.Option.PREDEFINED_DEFAULT_OBJECT_ACL;
3131
import static com.google.gcloud.spi.StorageRpc.Option.PREFIX;
3232
import static com.google.gcloud.spi.StorageRpc.Option.VERSIONS;
33+
import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
3334

3435
import com.google.api.client.googleapis.batch.json.JsonBatchCallback;
3536
import com.google.api.client.googleapis.json.GoogleJsonError;
@@ -94,7 +95,8 @@ public DefaultStorageRpc(StorageOptions options) {
9495

9596
private static StorageException translate(IOException exception) {
9697
StorageException translated;
97-
if (exception instanceof GoogleJsonResponseException) {
98+
if (exception instanceof GoogleJsonResponseException
99+
&& ((GoogleJsonResponseException) exception).getDetails() != null) {
98100
translated = translate(((GoogleJsonResponseException) exception).getDetails());
99101
} else {
100102
translated = new StorageException(0, exception.getMessage(), false);
@@ -191,7 +193,11 @@ public Bucket get(Bucket bucket, Map<Option, ?> options) {
191193
.setFields(FIELDS.getString(options))
192194
.execute();
193195
} catch (IOException ex) {
194-
throw translate(ex);
196+
StorageException serviceException = translate(ex);
197+
if (serviceException.code() == HTTP_NOT_FOUND) {
198+
return null;
199+
}
200+
throw serviceException;
195201
}
196202
}
197203

@@ -200,7 +206,11 @@ public StorageObject get(StorageObject object, Map<Option, ?> options) {
200206
try {
201207
return getRequest(object, options).execute();
202208
} catch (IOException ex) {
203-
throw translate(ex);
209+
StorageException serviceException = translate(ex);
210+
if (serviceException.code() == HTTP_NOT_FOUND) {
211+
return null;
212+
}
213+
throw serviceException;
204214
}
205215
}
206216

@@ -265,7 +275,7 @@ public boolean delete(Bucket bucket, Map<Option, ?> options) {
265275
return true;
266276
} catch (IOException ex) {
267277
StorageException serviceException = translate(ex);
268-
if (serviceException.code() == 404) {
278+
if (serviceException.code() == HTTP_NOT_FOUND) {
269279
return false;
270280
}
271281
throw serviceException;
@@ -279,7 +289,7 @@ public boolean delete(StorageObject blob, Map<Option, ?> options) {
279289
return true;
280290
} catch (IOException ex) {
281291
StorageException serviceException = translate(ex);
282-
if (serviceException.code() == 404) {
292+
if (serviceException.code() == HTTP_NOT_FOUND) {
283293
return false;
284294
}
285295
throw serviceException;
@@ -368,7 +378,11 @@ public void onSuccess(Void ignore, HttpHeaders responseHeaders) {
368378

369379
@Override
370380
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
371-
deletes.put(tuple.x(), Tuple.<Boolean, StorageException>of(null, translate(e)));
381+
if (e.getCode() == HTTP_NOT_FOUND) {
382+
deletes.put(tuple.x(), Tuple.<Boolean, StorageException>of(Boolean.FALSE, null));
383+
} else {
384+
deletes.put(tuple.x(), Tuple.<Boolean, StorageException>of(null, translate(e)));
385+
}
372386
}
373387
});
374388
}
@@ -397,8 +411,13 @@ public void onSuccess(StorageObject storageObject, HttpHeaders responseHeaders)
397411

398412
@Override
399413
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
400-
gets.put(tuple.x(),
401-
Tuple.<StorageObject, StorageException>of(null, translate(e)));
414+
if (e.getCode() == HTTP_NOT_FOUND) {
415+
gets.put(tuple.x(),
416+
Tuple.<StorageObject, StorageException>of(null, null));
417+
} else {
418+
gets.put(tuple.x(),
419+
Tuple.<StorageObject, StorageException>of(null, translate(e)));
420+
}
402421
}
403422
});
404423
}

gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,18 @@ StorageObject create(StorageObject object, InputStream content, Map<Option, ?> o
227227
Tuple<String, Iterable<StorageObject>> list(String bucket, Map<Option, ?> options)
228228
throws StorageException;
229229

230+
/**
231+
* Returns the requested bucket or {@code null} if not found.
232+
*
233+
* @throws StorageException upon failure
234+
*/
230235
Bucket get(Bucket bucket, Map<Option, ?> options) throws StorageException;
231236

237+
/**
238+
* Returns the requested storage object or {@code null} if not found.
239+
*
240+
* @throws StorageException upon failure
241+
*/
232242
StorageObject get(StorageObject object, Map<Option, ?> options)
233243
throws StorageException;
234244

gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ public CopyWriter copyTo(BlobId targetBlob, BlobSourceOption... options) {
281281
* Deletes this blob.
282282
*
283283
* @param options blob delete options
284-
* @return true if blob was deleted
284+
* @return {@code true} if blob was deleted, {@code false} if it was not found
285285
* @throws StorageException upon failure
286286
*/
287287
public boolean delete(BlobSourceOption... options) {
@@ -422,8 +422,8 @@ public Blob apply(BlobInfo f) {
422422
* @param storage the storage service used to issue the request
423423
* @param blobs the blobs to delete
424424
* @return an immutable list of booleans. If a blob has been deleted the corresponding item in the
425-
* list is {@code true}. If deletion failed or access to the resource was denied the item is
426-
* {@code false}.
425+
* list is {@code true}. If a blob was not found, deletion failed or access to the resource
426+
* was denied the corresponding item is {@code false}.
427427
* @throws StorageException upon failure
428428
*/
429429
public static List<Boolean> delete(Storage storage, BlobId... blobs) {

gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ public Bucket update(BucketInfo bucketInfo, BucketTargetOption... options) {
271271
* Deletes this bucket.
272272
*
273273
* @param options bucket delete options
274-
* @return true if bucket was deleted
274+
* @return {@code true} if bucket was deleted, {@code false} if it was not found
275275
* @throws StorageException upon failure
276276
*/
277277
public boolean delete(BucketSourceOption... options) {

gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,31 +1316,31 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx
13161316
/**
13171317
* Delete the requested bucket.
13181318
*
1319-
* @return true if bucket was deleted
1319+
* @return {@code true} if bucket was deleted, {@code false} if it was not found
13201320
* @throws StorageException upon failure
13211321
*/
13221322
boolean delete(String bucket, BucketSourceOption... options);
13231323

13241324
/**
13251325
* Delete the requested blob.
13261326
*
1327-
* @return true if blob was deleted
1327+
* @return {@code true} if blob was deleted, {@code false} if it was not found
13281328
* @throws StorageException upon failure
13291329
*/
13301330
boolean delete(String bucket, String blob, BlobSourceOption... options);
13311331

13321332
/**
13331333
* Delete the requested blob.
13341334
*
1335-
* @return true if blob was deleted
1335+
* @return {@code true} if blob was deleted, {@code false} if it was not found
13361336
* @throws StorageException upon failure
13371337
*/
13381338
boolean delete(BlobId blob, BlobSourceOption... options);
13391339

13401340
/**
13411341
* Delete the requested blob.
13421342
*
1343-
* @return true if blob was deleted
1343+
* @return {@code true} if blob was deleted, {@code false} if it was not found
13441344
* @throws StorageException upon failure
13451345
*/
13461346
boolean delete(BlobId blob);
@@ -1478,8 +1478,8 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx
14781478
*
14791479
* @param blobIds blobs to delete
14801480
* @return an immutable list of booleans. If a blob has been deleted the corresponding item in the
1481-
* list is {@code true}. If deletion failed or access to the resource was denied the item is
1482-
* {@code false}.
1481+
* list is {@code true}. If a blob was not found, deletion failed or access to the resource
1482+
* was denied the corresponding item is {@code false}.
14831483
* @throws StorageException upon failure
14841484
*/
14851485
List<Boolean> delete(BlobId... blobIds);

gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH;
2929
import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH;
3030
import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH;
31-
import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
3231
import static java.nio.charset.StandardCharsets.UTF_8;
3332

3433
import com.google.api.services.storage.model.StorageObject;
@@ -177,14 +176,7 @@ public BucketInfo get(String bucket, BucketGetOption... options) {
177176
new Callable<com.google.api.services.storage.model.Bucket>() {
178177
@Override
179178
public com.google.api.services.storage.model.Bucket call() {
180-
try {
181-
return storageRpc.get(bucketPb, optionsMap);
182-
} catch (StorageException ex) {
183-
if (ex.code() == HTTP_NOT_FOUND) {
184-
return null;
185-
}
186-
throw ex;
187-
}
179+
return storageRpc.get(bucketPb, optionsMap);
188180
}
189181
}, options().retryParams(), EXCEPTION_HANDLER);
190182
return answer == null ? null : BucketInfo.fromPb(answer);
@@ -206,14 +198,7 @@ public BlobInfo get(BlobId blob, BlobGetOption... options) {
206198
StorageObject storageObject = runWithRetries(new Callable<StorageObject>() {
207199
@Override
208200
public StorageObject call() {
209-
try {
210-
return storageRpc.get(storedObject, optionsMap);
211-
} catch (StorageException ex) {
212-
if (ex.code() == HTTP_NOT_FOUND) {
213-
return null;
214-
}
215-
throw ex;
216-
}
201+
return storageRpc.get(storedObject, optionsMap);
217202
}
218203
}, options().retryParams(), EXCEPTION_HANDLER);
219204
return storageObject == null ? null : BlobInfo.fromPb(storageObject);
@@ -525,28 +510,23 @@ public BatchResponse apply(BatchRequest batchRequest) {
525510
List<BatchResponse.Result<BlobInfo>> updates = transformBatchResult(
526511
toUpdate, response.updates, BlobInfo.FROM_PB_FUNCTION);
527512
List<BatchResponse.Result<BlobInfo>> gets = transformBatchResult(
528-
toGet, response.gets, BlobInfo.FROM_PB_FUNCTION, HTTP_NOT_FOUND);
513+
toGet, response.gets, BlobInfo.FROM_PB_FUNCTION);
529514
return new BatchResponse(deletes, updates, gets);
530515
}
531516

532517
private <I, O extends Serializable> List<BatchResponse.Result<O>> transformBatchResult(
533518
Iterable<Tuple<StorageObject, Map<StorageRpc.Option, ?>>> request,
534-
Map<StorageObject, Tuple<I, StorageException>> results, Function<I, O> transform,
535-
int... nullOnErrorCodes) {
536-
Set nullOnErrorCodesSet = Sets.newHashSet(Ints.asList(nullOnErrorCodes));
519+
Map<StorageObject, Tuple<I, StorageException>> results, Function<I, O> transform) {
537520
List<BatchResponse.Result<O>> response = Lists.newArrayListWithCapacity(results.size());
538521
for (Tuple<StorageObject, ?> tuple : request) {
539522
Tuple<I, StorageException> result = results.get(tuple.x());
540-
if (result.x() != null) {
541-
response.add(BatchResponse.Result.of(transform.apply(result.x())));
523+
I object = result.x();
524+
StorageException exception = result.y();
525+
if (exception != null) {
526+
response.add(new BatchResponse.Result<O>(exception));
542527
} else {
543-
StorageException exception = result.y();
544-
if (nullOnErrorCodesSet.contains(exception.code())) {
545-
//noinspection unchecked
546-
response.add(BatchResponse.Result.<O>empty());
547-
} else {
548-
response.add(new BatchResponse.Result<O>(exception));
549-
}
528+
response.add(object != null ?
529+
BatchResponse.Result.of(transform.apply(object)) : BatchResponse.Result.<O>empty());
550530
}
551531
}
552532
return response;

gcloud-java-storage/src/test/java/com/google/gcloud/storage/ITStorageTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,8 @@ public void testBatchRequestFail() {
644644
assertFalse(batchResponse.gets().get(1).failed());
645645
assertNull(batchResponse.gets().get(1).get());
646646
assertTrue(batchResponse.deletes().get(0).failed());
647-
assertTrue(batchResponse.deletes().get(1).failed());
647+
assertFalse(batchResponse.deletes().get(1).failed());
648+
assertFalse(batchResponse.deletes().get(1).get());
648649
assertTrue(storage.delete(BUCKET, blobName));
649650
}
650651

0 commit comments

Comments
 (0)