DefaultHost implements Host { @Override @NotNull @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") @Loggable(value = Loggable.DEBUG, ignore = IOException.class) public Resource fetch(@NotNull final URI uri, @NotNull final Range range, @NotNull final Version version) throws IOException { Resource resource = null; final Collection<String> errors = new LinkedList<String>(); final DomainStatsData data = new H2DomainStatsData(); for (final DefaultHost.ObjectName name : this.names(uri)) { try { if (version.list()) { resource = new ObjectVersionListing( this.bucket.client(), this.bucket.bucket(), name.get() ); } else { resource = new DefaultResource( this.bucket.client(), this.bucket.bucket(), name.get(), range, version, data ); } break; } catch (final AmazonServiceException ex) { if (StringUtils.endsWith(name.get(), DefaultHost.SUFFIX) && "NoSuchKey".equals(ex.getErrorCode()) ) { resource = new DirectoryListing( this.bucket.client(), this.bucket.bucket(), StringUtils.removeEnd(name.get(), DefaultHost.SUFFIX) ); break; } else if ("NoSuchBucket".equals(ex.getErrorCode())) { throw new IOException( Logger.format( "The bucket '%s' does not exist.", this.bucket.bucket() ), ex ); } else if (ex.getStatusCode() >= HttpStatus.SC_BAD_REQUEST && ex.getStatusCode() < HttpStatus.SC_INTERNAL_SERVER_ERROR ) { try { final BucketWebsiteConfiguration config = this.bucket.client().getBucketWebsiteConfiguration( this.bucket.bucket() ); if (config != null && config.getErrorDocument() != null) { resource = new DefaultResource( this.bucket.client(), this.bucket.bucket(), config.getErrorDocument(), Range.ENTIRE, Version.LATEST, data ); } } catch (final AmazonClientException exc) { errors.add( String.format("'%s': %s", name, exc.getMessage()) ); } } errors.add(String.format("'%s': %s", name, ex.getMessage())); } catch (final AmazonClientException ex) { errors.add(String.format("'%s': %s", name, ex.getMessage())); } } if (resource == null) { throw new IOException( Logger.format( "failed to fetch %s from '%s' (key=%s): %[list]s", uri, this.bucket.name(), this.bucket.key(), errors ) ); } return resource; } DefaultHost(@NotNull final Bucket bckt);   DefaultHost(
        @NotNull final Bucket bckt,
        @NotNull final Host.CloudWatch cwatch
    ); @Override String toString(); @Override void close(); @Override @NotNull @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") @Loggable(value = Loggable.DEBUG, ignore = IOException.class) Resource fetch(@NotNull final URI uri,
        @NotNull final Range range, @NotNull final Version version); @Override boolean isHidden(@NotNull final URI uri); @Override boolean authorized(@NotNull final String user,
        @NotNull final String password); @Override String syslog(); @Override Stats stats();  }
@Test public void throwsExceptionForNonexistentBucket() throws Exception { final AmazonS3 aws = Mockito.mock(AmazonS3.class); final AmazonServiceException exp = new AmazonServiceException("No such bucket"); exp.setErrorCode("NoSuchBucket"); Mockito.doThrow(exp) .when(aws).getObject(Mockito.any(GetObjectRequest.class)); Mockito.doReturn(new BucketWebsiteConfiguration()) .when(aws).getBucketWebsiteConfiguration(Mockito.anyString()); final String bucket = "nonExistent"; this.thrown.expect(IOException.class); this.thrown.expectMessage( Matchers.allOf( Matchers.not(Matchers.startsWith("failed to fetch /.htpasswd")), Matchers.is( String.format("The bucket '%s' does not exist.", bucket) ) ) ); new DefaultHost( new BucketMocker().withBucket(bucket).withClient(aws).mock(), this.cloudWatch() ).fetch(URI.create("/.htpasswd"), Range.ENTIRE, Version.LATEST); }
@Test(expected = IOException.class) public void throwsExceptionIfNoBucketWebsiteConfiguration() throws Exception { final AmazonS3 aws = Mockito.mock(AmazonS3.class); final AmazonServiceException ex = new AmazonServiceException("The object is not found"); ex.setStatusCode(HttpStatus.SC_NOT_FOUND); Mockito.doThrow(ex).when(aws) .getObject(Mockito.any(GetObjectRequest.class)); new DefaultHost( new BucketMocker().withClient(aws).mock(), this.cloudWatch() ).fetch(URI.create("failed.html"), Range.ENTIRE, Version.LATEST); }