diff --git a/apis/s3/src/main/java/org/jclouds/s3/binders/BindObjectMetadataToRequest.java b/apis/s3/src/main/java/org/jclouds/s3/binders/BindObjectMetadataToRequest.java index 84948e13ed..836f20bed3 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/binders/BindObjectMetadataToRequest.java +++ b/apis/s3/src/main/java/org/jclouds/s3/binders/BindObjectMetadataToRequest.java @@ -81,6 +81,11 @@ public class BindObjectMetadataToRequest implements Binder { headers.put("Content-MD5", base64().encode(md.getContentMetadata().getContentMD5())); } + ObjectMetadata.StorageClass storageClass = md.getStorageClass(); + if (storageClass != ObjectMetadata.StorageClass.STANDARD) { + headers.put("x-amz-storage-class", storageClass.toString()); + } + return (R) request.toBuilder().replaceHeaders(headers.build()).build(); } } diff --git a/apis/s3/src/main/java/org/jclouds/s3/binders/BindS3ObjectMetadataToRequest.java b/apis/s3/src/main/java/org/jclouds/s3/binders/BindS3ObjectMetadataToRequest.java index c50405cb44..e611bd90d6 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/binders/BindS3ObjectMetadataToRequest.java +++ b/apis/s3/src/main/java/org/jclouds/s3/binders/BindS3ObjectMetadataToRequest.java @@ -25,6 +25,7 @@ import javax.inject.Singleton; import org.jclouds.blobstore.binders.BindMapToHeadersWithPrefix; import org.jclouds.http.HttpRequest; import org.jclouds.rest.Binder; +import org.jclouds.s3.domain.ObjectMetadata.StorageClass; import org.jclouds.s3.domain.S3Object; @Singleton @@ -48,7 +49,14 @@ public class BindS3ObjectMetadataToRequest implements Binder { "contentLength must be set, streaming not supported"); checkArgument(s3Object.getPayload().getContentMetadata().getContentLength() <= 5L * 1024 * 1024 * 1024, "maximum size for put object is 5GB"); - + + StorageClass storageClass = s3Object.getMetadata().getStorageClass(); + if (storageClass != StorageClass.STANDARD) { + request = (R) request.toBuilder() + .replaceHeader("x-amz-storage-class", storageClass.toString()) + .build(); + } + request = metadataPrefixer.bindToRequest(request, s3Object.getMetadata().getUserMetadata()); return request; diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStore.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStore.java index 195b637202..9b91048d33 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStore.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStore.java @@ -266,6 +266,8 @@ public class S3BlobStore extends BaseBlobStore { if (overrides.getBlobAccess() == BlobAccess.PUBLIC_READ) { options = options.withAcl(CannedAccessPolicy.PUBLIC_READ); } + // TODO: S3 does not allow putObject if Tier.ARCHIVE. Instead, copyBlob + // after putBlob when the former supports tiers. return sync.putObject(container, blob2Object.apply(blob), options); } diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/BlobToObjectMetadata.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/BlobToObjectMetadata.java index cfa97aefde..48bae931f4 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/BlobToObjectMetadata.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/BlobToObjectMetadata.java @@ -26,6 +26,7 @@ import org.jclouds.http.HttpUtils; import org.jclouds.rest.InvocationContext; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.s3.domain.MutableObjectMetadata; +import org.jclouds.s3.domain.ObjectMetadata.StorageClass; import org.jclouds.s3.domain.internal.MutableObjectMetadataImpl; import com.google.common.base.Function; @@ -48,6 +49,7 @@ public class BlobToObjectMetadata implements Function entry : from.getUserMetadata().entrySet()) to.getUserMetadata().put(entry.getKey().toLowerCase(), entry.getValue()); } + to.setStorageClass(StorageClass.fromTier(from.getTier())); return to; } diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/ObjectToBlobMetadata.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/ObjectToBlobMetadata.java index f8bf9bf374..8af059a1c0 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/ObjectToBlobMetadata.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/ObjectToBlobMetadata.java @@ -51,6 +51,7 @@ public class ObjectToBlobMetadata implements Function { public enum StorageClass { - STANDARD, STANDARD_IA, REDUCED_REDUNDANCY + STANDARD(Tier.STANDARD), + STANDARD_IA(Tier.INFREQUENT), + REDUCED_REDUNDANCY(Tier.STANDARD), + GLACIER(Tier.ARCHIVE); + + private final Tier tier; + + private StorageClass(Tier tier) { + this.tier = checkNotNull(tier, "tier"); + } + + public static StorageClass fromTier(Tier tier) { + switch (tier) { + case STANDARD: return StorageClass.STANDARD; + case INFREQUENT: return StorageClass.STANDARD_IA; + case ARCHIVE: return StorageClass.GLACIER; + } + throw new IllegalArgumentException("invalid tier: " + tier); + } + + public Tier toTier() { + return tier; + } } /** diff --git a/apis/s3/src/main/java/org/jclouds/s3/functions/ParseObjectMetadataFromHeaders.java b/apis/s3/src/main/java/org/jclouds/s3/functions/ParseObjectMetadataFromHeaders.java index 71d81f0d64..aadb313238 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/functions/ParseObjectMetadataFromHeaders.java +++ b/apis/s3/src/main/java/org/jclouds/s3/functions/ParseObjectMetadataFromHeaders.java @@ -32,6 +32,7 @@ import org.jclouds.http.HttpResponse; import org.jclouds.rest.InvocationContext; import org.jclouds.s3.blobstore.functions.BlobToObjectMetadata; import org.jclouds.s3.domain.MutableObjectMetadata; +import org.jclouds.s3.domain.ObjectMetadata.StorageClass; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; @@ -75,6 +76,10 @@ public class ParseObjectMetadataFromHeaders implements Function