/** * @param exs StorageException to test * @return true if exs is a retryable error, otherwise false */ @VisibleForTesting boolean isRetryable(final StorageException exs) { if (exs.isRetryable()) { return true; } for (int code : config.retryableHttpCodes()) { if (exs.getCode() == code) { return true; } } return false; }
/** * Records a reopen attempt for the given StorageException, sleeping for an amount of time * dependent on the attempt number. Throws a StorageException if we've exhausted all reopens. * * @param exs The StorageException error that prompted this reopen attempt. */ private void handleReopenForStorageException(final StorageException exs) throws StorageException { reopens++; if (reopens > maxReopens) { throw new StorageException( exs.getCode(), "All " + maxReopens + " reopens failed. Waited a total of " + totalWaitTime + " ms between attempts", exs); } sleepForAttempt(reopens); }
/** * Records a retry attempt for the given StorageException, sleeping for an amount of time * dependent on the attempt number. Throws a StorageException if we've exhausted all retries. * * @param exs The StorageException error that prompted this retry attempt. */ private void handleRetryForStorageException(final StorageException exs) throws StorageException { retries++; if (retries > maxRetries) { throw new StorageException( exs.getCode(), "All " + maxRetries + " retries failed. Waited a total of " + totalWaitTime + " ms between attempts", exs); } sleepForAttempt(retries); }
/** * @param bucketName the name of the bucket to check * @return whether requester pays is enabled for that bucket */ public boolean requesterPays(String bucketName) { initStorage(); try { // instead of true/false, this method returns true/null. Boolean isRP = storage.get(bucketName).requesterPays(); return isRP != null && isRP.booleanValue(); } catch (StorageException ex) { if (ex.getCode() == 400 && ex.getMessage().contains("Bucket is requester pays")) { return true; } throw ex; } }
if (e.getCode() == 409) { try { Thread.sleep(500);
private void assertIsRequesterPaysException(String message, StorageException ex) { Assert.assertEquals(message, ex.getCode(), 400); Assert.assertTrue( message, ex.getMessage().contains("Bucket is requester pays bucket but no user project provided")); }
private IOException asIoException(StorageException oops) { // RPC API can only throw StorageException, but CloudStorageFileSystemProvider // can only throw IOException. Square peg, round hole. // TODO(#810): Research if other codes should be translated similarly. if (oops.getCode() == 404) { return new NoSuchFileException(oops.getReason()); } Throwable cause = oops.getCause(); try { if (cause instanceof FileAlreadyExistsException) { throw new FileAlreadyExistsException(((FileAlreadyExistsException) cause).getReason()); } // fallback if (cause != null && cause instanceof IOException) { return (IOException) cause; } } catch (IOException okEx) { return okEx; } return new IOException(oops.getMessage(), oops); } }
@Override public StorageObject get(StorageObject object, Map<Option, ?> options) { Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_GET_OBJECT); Scope scope = tracer.withSpan(span); try { return getCall(object, options).execute(); } catch (IOException ex) { span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage())); StorageException serviceException = translate(ex); if (serviceException.getCode() == HTTP_NOT_FOUND) { return null; } throw serviceException; } finally { scope.close(); span.end(); } }
@Override public boolean delete(StorageObject blob, Map<Option, ?> options) { Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_DELETE_OBJECT); Scope scope = tracer.withSpan(span); try { deleteCall(blob, options).execute(); return true; } catch (IOException ex) { span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage())); StorageException serviceException = translate(ex); if (serviceException.getCode() == HTTP_NOT_FOUND) { return false; } throw serviceException; } finally { scope.close(); span.end(); } }
@Override public ObjectAccessControl getDefaultAcl(String bucket, String entity) { Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_GET_OBJECT_DEFAULT_ACL); Scope scope = tracer.withSpan(span); try { return storage.defaultObjectAccessControls().get(bucket, entity).execute(); } catch (IOException ex) { span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage())); StorageException serviceException = translate(ex); if (serviceException.getCode() == HTTP_NOT_FOUND) { return null; } throw serviceException; } finally { scope.close(); span.end(); } }
@Override public boolean deleteDefaultAcl(String bucket, String entity) { Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_DELETE_OBJECT_DEFAULT_ACL); Scope scope = tracer.withSpan(span); try { storage.defaultObjectAccessControls().delete(bucket, entity).execute(); return true; } catch (IOException ex) { span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage())); StorageException serviceException = translate(ex); if (serviceException.getCode() == HTTP_NOT_FOUND) { return false; } throw serviceException; } finally { scope.close(); span.end(); } }
@Override public boolean deleteNotification(String bucket, String notification) { Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_DELETE_NOTIFICATION); Scope scope = tracer.withSpan(span); try { storage.notifications().delete(bucket, notification).execute(); return true; } catch (IOException ex) { span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage())); StorageException serviceException = translate(ex); if (serviceException.getCode() == HTTP_NOT_FOUND) { return false; } throw serviceException; } finally { scope.close(); span.end(); } }
span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage())); StorageException serviceException = translate(ex); if (serviceException.getCode() == HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE) { return Tuple.of(null, new byte[0]);
@Override public ObjectAccessControl getAcl(String bucket, String object, Long generation, String entity) { Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_GET_OBJECT_ACL); Scope scope = tracer.withSpan(span); try { return storage .objectAccessControls() .get(bucket, object, entity) .setGeneration(generation) .execute(); } catch (IOException ex) { span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage())); StorageException serviceException = translate(ex); if (serviceException.getCode() == HTTP_NOT_FOUND) { return null; } throw serviceException; } finally { scope.close(); span.end(); } }
@Override public boolean deleteAcl(String bucket, String object, Long generation, String entity) { Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_DELETE_OBJECT_ACL); Scope scope = tracer.withSpan(span); try { storage .objectAccessControls() .delete(bucket, object, entity) .setGeneration(generation) .execute(); return true; } catch (IOException ex) { span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage())); StorageException serviceException = translate(ex); if (serviceException.getCode() == HTTP_NOT_FOUND) { return false; } throw serviceException; } finally { scope.close(); span.end(); } }
@Override public BucketAccessControl getAcl(String bucket, String entity, Map<Option, ?> options) { Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_GET_BUCKET_ACL); Scope scope = tracer.withSpan(span); try { return storage .bucketAccessControls() .get(bucket, entity) .setUserProject(Option.USER_PROJECT.getString(options)) .execute(); } catch (IOException ex) { span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage())); StorageException serviceException = translate(ex); if (serviceException.getCode() == HTTP_NOT_FOUND) { return null; } throw serviceException; } finally { scope.close(); span.end(); } }
@Override public boolean deleteAcl(String bucket, String entity, Map<Option, ?> options) { Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_DELETE_BUCKET_ACL); Scope scope = tracer.withSpan(span); try { storage .bucketAccessControls() .delete(bucket, entity) .setUserProject(Option.USER_PROJECT.getString(options)) .execute(); return true; } catch (IOException ex) { span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage())); StorageException serviceException = translate(ex); if (serviceException.getCode() == HTTP_NOT_FOUND) { return false; } throw serviceException; } finally { scope.close(); span.end(); } }
@Override public boolean delete(Bucket bucket, Map<Option, ?> options) { Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_DELETE_BUCKET); Scope scope = tracer.withSpan(span); try { storage .buckets() .delete(bucket.getName()) .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) .setUserProject(Option.USER_PROJECT.getString(options)) .execute(); return true; } catch (IOException ex) { span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage())); StorageException serviceException = translate(ex); if (serviceException.getCode() == HTTP_NOT_FOUND) { return false; } throw serviceException; } finally { scope.close(); span.end(); } }
@Override public Bucket get(Bucket bucket, Map<Option, ?> options) { Span span = startSpan(HttpStorageRpcSpans.SPAN_NAME_GET_BUCKET); Scope scope = tracer.withSpan(span); try { return storage .buckets() .get(bucket.getName()) .setProjection(DEFAULT_PROJECTION) .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) .setFields(Option.FIELDS.getString(options)) .setUserProject(Option.USER_PROJECT.getString(options)) .execute(); } catch (IOException ex) { span.setStatus(Status.UNKNOWN.withDescription(ex.getMessage())); StorageException serviceException = translate(ex); if (serviceException.getCode() == HTTP_NOT_FOUND) { return null; } throw serviceException; } finally { scope.close(); span.end(); } }
@Test public void testStorageException() { StorageException exception = new StorageException(500, "message"); assertEquals(500, exception.getCode()); assertEquals("message", exception.getMessage()); assertNull(exception.getReason()); assertEquals(502, exception.getCode()); assertEquals("message", exception.getMessage()); assertNull(exception.getReason()); assertEquals(503, exception.getCode()); assertEquals("message", exception.getMessage()); assertNull(exception.getReason()); assertEquals(504, exception.getCode()); assertEquals("message", exception.getMessage()); assertNull(exception.getReason()); assertEquals(429, exception.getCode()); assertEquals("message", exception.getMessage()); assertNull(exception.getReason()); assertEquals(408, exception.getCode()); assertEquals("message", exception.getMessage()); assertNull(exception.getReason()); assertEquals(400, exception.getCode()); assertEquals("message", exception.getMessage()); assertNull(exception.getReason());