Translate Azure errors in AzureBlobStore

This addresses a layering violation and may make AzureBlobStore more
useful to non-S3Proxy users.  References #606.
pull/702/head
Andrew Gaul 2024-10-27 21:16:48 -07:00
rodzic 513283859a
commit 38cf4a9239
2 zmienionych plików z 35 dodań i 25 usunięć

Wyświetl plik

@ -23,7 +23,6 @@ import java.util.concurrent.TimeoutException;
import javax.annotation.Nullable;
import com.azure.storage.blob.models.BlobStorageException;
import com.google.common.net.HttpHeaders;
import jakarta.servlet.http.HttpServletRequest;
@ -31,7 +30,6 @@ import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.gaul.s3proxy.azureblob.AzureBlobStore;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.ContainerNotFoundException;
import org.jclouds.blobstore.KeyNotFoundException;
@ -81,12 +79,6 @@ final class S3ProxyHandlerJetty extends AbstractHandler {
handler.doHandle(baseRequest, request, response, is);
baseRequest.setHandled(true);
} catch (BlobStorageException bse) {
S3ErrorCode code = AzureBlobStore.toS3ErrorCode(bse.getErrorCode());
handler.sendSimpleErrorResponse(request, response, code,
code.getMessage(), Map.of());
baseRequest.setHandled(true);
return;
} catch (ContainerNotFoundException cnfe) {
S3ErrorCode code = S3ErrorCode.NO_SUCH_BUCKET;
handler.sendSimpleErrorResponse(request, response, code,

Wyświetl plik

@ -50,6 +50,7 @@ import com.azure.storage.blob.options.BlobUploadFromUrlOptions;
import com.azure.storage.blob.options.BlockBlobOutputStreamOptions;
import com.azure.storage.blob.sas.BlobSasPermission;
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
import com.azure.storage.blob.specialized.BlobInputStream;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@ -57,9 +58,10 @@ import com.google.common.primitives.Ints;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.ws.rs.core.Response.Status;
import org.gaul.s3proxy.S3ErrorCode;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobAccess;
import org.jclouds.blobstore.domain.BlobMetadata;
@ -84,6 +86,10 @@ import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.io.ContentMetadata;
import org.jclouds.io.ContentMetadataBuilder;
import org.jclouds.io.Payload;
@ -93,6 +99,7 @@ import org.jclouds.providers.ProviderMetadata;
@Singleton
public final class AzureBlobStore extends BaseBlobStore {
private final BlobServiceClient blobServiceClient;
private final String endpoint;
@Inject
AzureBlobStore(BlobStoreContext context, BlobUtils blobUtils,
@ -102,11 +109,12 @@ public final class AzureBlobStore extends BaseBlobStore {
@org.jclouds.location.Provider Supplier<Credentials> creds,
ProviderMetadata provider) {
super(context, blobUtils, defaultLocation, locations, slicer);
this.endpoint = provider.getEndpoint();
var cred = creds.get();
blobServiceClient = new BlobServiceClientBuilder()
.credential(new AzureNamedKeyCredential(
cred.identity, cred.credential))
.endpoint(provider.getEndpoint())
.endpoint(endpoint)
.buildClient();
}
@ -227,7 +235,22 @@ public final class AzureBlobStore extends BaseBlobStore {
.setIfNoneMatch(options.getIfNoneMatch())
.setIfUnmodifiedSince(toOffsetDateTime(
options.getIfUnmodifiedSince()));
var blobStream = client.openInputStream(range, conditions);
BlobInputStream blobStream;
try {
blobStream = client.openInputStream(range, conditions);
} catch (BlobStorageException bse) {
if (bse.getErrorCode() == BlobErrorCode.CONDITION_NOT_MET) {
var response = HttpResponse.builder()
.statusCode(Status.PRECONDITION_FAILED.getStatusCode())
.build();
var command = new HttpCommand(HttpRequest.builder()
.method("GET")
.endpoint(endpoint)
.build());
throw new HttpResponseException(command, response);
}
throw bse;
}
var properties = blobStream.getProperties();
var expires = properties.getExpiresOn();
return new BlobBuilderImpl()
@ -372,7 +395,15 @@ public final class AzureBlobStore extends BaseBlobStore {
public BlobMetadata blobMetadata(String container, String key) {
var client = blobServiceClient.getBlobContainerClient(container)
.getBlobClient(key);
var properties = client.getProperties();
BlobProperties properties;
try {
properties = client.getProperties();
} catch (BlobStorageException bse) {
if (bse.getErrorCode() == BlobErrorCode.BLOB_NOT_FOUND) {
throw new KeyNotFoundException(container, key, "");
}
throw bse;
}
return new BlobMetadataImpl(/*id=*/ null, key, /*location=*/ null,
/*uri=*/ null, properties.getETag(),
toDate(properties.getCreationTime()),
@ -527,19 +558,6 @@ public final class AzureBlobStore extends BaseBlobStore {
throw new UnsupportedOperationException("not yet implemented");
}
// TODO: handle more error codes
public static S3ErrorCode toS3ErrorCode(BlobErrorCode code) {
if (code.equals(BlobErrorCode.BLOB_NOT_FOUND)) {
return S3ErrorCode.NO_SUCH_KEY;
} else if (code.equals(BlobErrorCode.CONTAINER_NOT_FOUND)) {
return S3ErrorCode.NO_SUCH_BUCKET;
} else if (code == BlobErrorCode.CONDITION_NOT_MET) {
return S3ErrorCode.PRECONDITION_FAILED;
} else {
return S3ErrorCode.INTERNAL_ERROR;
}
}
private static OffsetDateTime toOffsetDateTime(@Nullable Date date) {
if (date == null) {
return null;