JCLOUDS-1594: Allow overriding S3 signer

Previously s3 always used v2 and aws-s3 always used v4.  Now s3
defaults to v2 and can override to v4.  Note that this does not change
BlobRequestSigner.
This commit is contained in:
Andrew Gaul 2021-12-31 19:53:04 +09:00 committed by Andrew Gaul
parent c95ddff020
commit 468b126dd8
8 changed files with 35 additions and 16 deletions

View File

@ -26,6 +26,7 @@ import static org.jclouds.reflect.Reflection2.typeToken;
import static org.jclouds.s3.reference.S3Constants.PROPERTY_JCLOUDS_S3_CHUNKED_SIZE;
import static org.jclouds.s3.reference.S3Constants.PROPERTY_S3_SERVICE_PATH;
import static org.jclouds.s3.reference.S3Constants.PROPERTY_S3_VIRTUAL_HOST_BUCKETS;
import static org.jclouds.s3.reference.S3Constants.PROPERTY_SIGNER_VERSION;
import java.net.URI;
import java.util.Properties;
@ -81,6 +82,7 @@ public class S3ApiMetadata extends BaseHttpApiMetadata {
properties.setProperty(PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX, "/");
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, String.format("x-${%s}-meta-", PROPERTY_HEADER_TAG));
properties.setProperty(PROPERTY_IDEMPOTENT_METHODS, "DELETE,GET,HEAD,OPTIONS,POST,PUT");
properties.setProperty(PROPERTY_SIGNER_VERSION, "2");
// Chunk size must be at least 8 KB. We recommend a chunk size of a least 64 KB for better performance.
properties.setProperty(PROPERTY_JCLOUDS_S3_CHUNKED_SIZE, String.valueOf(64 * 1024));

View File

@ -49,9 +49,11 @@ import org.jclouds.s3.blobstore.functions.BucketsToStorageMetadata;
import org.jclouds.s3.domain.BucketMetadata;
import org.jclouds.s3.filters.RequestAuthorizeSignature;
import org.jclouds.s3.filters.RequestAuthorizeSignatureV2;
import org.jclouds.s3.filters.RequestAuthorizeSignatureV4;
import org.jclouds.s3.functions.GetRegionForBucket;
import org.jclouds.s3.handlers.ParseS3ErrorFromXmlContent;
import org.jclouds.s3.handlers.S3RedirectionRetryHandler;
import org.jclouds.s3.reference.S3Constants;
import com.google.common.base.Function;
import com.google.common.base.Optional;
@ -61,8 +63,8 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
/**
@ -169,7 +171,6 @@ public class S3HttpApiModule<S extends S3Client> extends AWSHttpApiModule<S> {
super.configure();
install(new S3ObjectModule());
install(new S3ParserModule());
bindRequestSigner();
bind(new TypeLiteral<Function<String, Optional<String>>>() {
}).annotatedWith(Bucket.class).to(GetRegionForBucket.class);
bind(new TypeLiteral<Function<Set<BucketMetadata>, PageSet<? extends StorageMetadata>>>() {
@ -183,8 +184,21 @@ public class S3HttpApiModule<S extends S3Client> extends AWSHttpApiModule<S> {
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseS3ErrorFromXmlContent.class);
}
protected void bindRequestSigner() {
bind(RequestAuthorizeSignature.class).to(RequestAuthorizeSignatureV2.class).in(Scopes.SINGLETON);
@Provides
@Singleton
protected final RequestAuthorizeSignature provideRequestAuthorizeSignature(Injector i, @Named(S3Constants.PROPERTY_SIGNER_VERSION) int version) {
return providesRequestAuthorizeSignature(i, version);
}
protected RequestAuthorizeSignature providesRequestAuthorizeSignature(Injector i, int version) {
switch (version) {
case 2:
return i.getInstance(RequestAuthorizeSignatureV2.class);
case 4:
return i.getInstance(RequestAuthorizeSignatureV4.class);
default:
throw new IllegalStateException("version must be 2 or 4, was: " + version);
}
}
@Provides

View File

@ -32,6 +32,7 @@ public final class S3Constants {
public static final String PROPERTY_S3_SERVICE_PATH = "jclouds.s3.service-path";
public static final String PROPERTY_S3_VIRTUAL_HOST_BUCKETS = "jclouds.s3.virtual-host-buckets";
public static final String PROPERTY_JCLOUDS_S3_CHUNKED_SIZE = "jclouds.s3.chunked.size";
public static final String PROPERTY_SIGNER_VERSION = "jclouds.s3.signer-version";
public static final String TEMPORARY_SIGNATURE_PARAM = "Signature";

View File

@ -18,6 +18,7 @@ package org.jclouds.aws.s3;
import static org.jclouds.reflect.Reflection2.typeToken;
import static org.jclouds.s3.reference.S3Constants.PROPERTY_S3_VIRTUAL_HOST_BUCKETS;
import static org.jclouds.s3.reference.S3Constants.PROPERTY_SIGNER_VERSION;
import java.util.Properties;
@ -50,6 +51,7 @@ public class AWSS3ApiMetadata extends S3ApiMetadata {
public static Properties defaultProperties() {
Properties properties = S3ApiMetadata.defaultProperties();
properties.setProperty(PROPERTY_S3_VIRTUAL_HOST_BUCKETS, "true");
properties.setProperty(PROPERTY_SIGNER_VERSION, "4");
return properties;
}

View File

@ -32,8 +32,8 @@ import org.jclouds.s3.predicates.validators.BucketNameValidator;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.Scopes;
/**
* Configures the S3 connection.
@ -57,8 +57,8 @@ public class AWSS3HttpApiModule extends S3HttpApiModule<AWSS3Client> {
}
@Override
protected void bindRequestSigner() {
bind(RequestAuthorizeSignature.class).to(AWSRequestAuthorizeSignatureV4.class).in(Scopes.SINGLETON);
protected RequestAuthorizeSignature providesRequestAuthorizeSignature(Injector i, int version) {
return i.getInstance(AWSRequestAuthorizeSignatureV4.class);
}
@Singleton

View File

@ -52,8 +52,8 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.reflect.Invokable;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Scopes;
// NOTE:without testName, this will not call @Before* and fail w/NPE during
// surefire
@ -197,8 +197,8 @@ public class AWSS3ClientTest extends S3ClientTest<AWSS3Client> {
// subclass expects v2 signatures
@Override
protected void bindRequestSigner() {
bind(RequestAuthorizeSignature.class).to(AWSRequestAuthorizeSignature.class).in(Scopes.SINGLETON);
protected RequestAuthorizeSignature providesRequestAuthorizeSignature(Injector i, int version) {
return i.getInstance(AWSRequestAuthorizeSignature.class);
}
}

View File

@ -48,8 +48,8 @@ import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.HttpHeaders;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Scopes;
@Test(groups = "unit", testName = "AWSS3BlobSignerV4ExpectTest")
public class AWSS3BlobSignerV4ExpectTest extends S3BlobSignerExpectTest {
@ -174,8 +174,8 @@ public class AWSS3BlobSignerV4ExpectTest extends S3BlobSignerExpectTest {
}
@Override
protected void bindRequestSigner() {
bind(RequestAuthorizeSignature.class).to(AWSRequestAuthorizeSignatureV4.class).in(Scopes.SINGLETON);
protected RequestAuthorizeSignature providesRequestAuthorizeSignature(Injector i, int version) {
return i.getInstance(AWSRequestAuthorizeSignatureV4.class);
}
@Override

View File

@ -27,8 +27,8 @@ import org.jclouds.rest.internal.BaseRestApiExpectTest;
import org.jclouds.s3.filters.RequestAuthorizeSignature;
import com.google.common.base.Supplier;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Scopes;
/**
* Base class for writing Expect tests for AWS-S3
@ -56,8 +56,8 @@ public class BaseAWSS3ClientExpectTest extends BaseRestApiExpectTest<AWSS3Client
// subclass expects v2 signatures
@Override
protected void bindRequestSigner() {
bind(RequestAuthorizeSignature.class).to(AWSRequestAuthorizeSignature.class).in(Scopes.SINGLETON);
protected RequestAuthorizeSignature providesRequestAuthorizeSignature(Injector i, int version) {
return i.getInstance(AWSRequestAuthorizeSignature.class);
}
}