JCLOUDS-1337: GCS putBlob portable storage tiers

This commit is contained in:
Andrew Gaul 2017-10-10 23:08:22 -07:00
parent 61d4be8746
commit 14c41ea133
5 changed files with 60 additions and 11 deletions

View File

@ -66,7 +66,6 @@ import org.jclouds.googlecloudstorage.domain.templates.BucketTemplate;
import org.jclouds.googlecloudstorage.domain.templates.ComposeObjectTemplate; import org.jclouds.googlecloudstorage.domain.templates.ComposeObjectTemplate;
import org.jclouds.googlecloudstorage.domain.templates.ObjectAccessControlsTemplate; import org.jclouds.googlecloudstorage.domain.templates.ObjectAccessControlsTemplate;
import org.jclouds.googlecloudstorage.domain.templates.ObjectTemplate; import org.jclouds.googlecloudstorage.domain.templates.ObjectTemplate;
import org.jclouds.googlecloudstorage.options.InsertObjectOptions;
import org.jclouds.googlecloudstorage.options.ListObjectOptions; import org.jclouds.googlecloudstorage.options.ListObjectOptions;
import org.jclouds.http.HttpResponseException; import org.jclouds.http.HttpResponseException;
import org.jclouds.io.ContentMetadata; import org.jclouds.io.ContentMetadata;
@ -392,6 +391,8 @@ public final class GoogleCloudStorageBlobStore extends BaseBlobStore {
} }
ObjectTemplate destination = blobMetadataToObjectTemplate.apply(mpu.blobMetadata()); ObjectTemplate destination = blobMetadataToObjectTemplate.apply(mpu.blobMetadata());
// unset storage class because the subobjects store this state
destination.storageClass(DomainResourceReferences.StorageClass.STANDARD);
if (mpu.putOptions().getBlobAccess() == BlobAccess.PUBLIC_READ) { if (mpu.putOptions().getBlobAccess() == BlobAccess.PUBLIC_READ) {
ObjectAccessControls controls = ObjectAccessControls.builder() ObjectAccessControls controls = ObjectAccessControls.builder()
.entity("allUsers") .entity("allUsers")
@ -421,10 +422,11 @@ public final class GoogleCloudStorageBlobStore extends BaseBlobStore {
public MultipartPart uploadMultipartPart(MultipartUpload mpu, int partNumber, Payload payload) { public MultipartPart uploadMultipartPart(MultipartUpload mpu, int partNumber, Payload payload) {
String partName = getMPUPartName(mpu, partNumber); String partName = getMPUPartName(mpu, partNumber);
long partSize = payload.getContentMetadata().getContentLength(); long partSize = payload.getContentMetadata().getContentLength();
// TODO: JCLOUDS-1337: use multipartUpload to set storage class ObjectTemplate template = blobMetadataToObjectTemplate.apply(mpu.blobMetadata())
InsertObjectOptions insertOptions = new InsertObjectOptions().name(partName); .name(partName)
GoogleCloudStorageObject object = api.getObjectApi().simpleUpload(mpu.containerName(), .size(partSize);
mpu.blobMetadata().getContentMetadata().getContentType(), partSize, payload, insertOptions); GoogleCloudStorageObject object = api.getObjectApi().multipartUpload(
mpu.containerName(), template, payload);
return MultipartPart.create(partNumber, partSize, object.etag(), object.updated()); return MultipartPart.create(partNumber, partSize, object.etag(), object.updated());
} }

View File

@ -21,6 +21,7 @@ import static com.google.common.io.BaseEncoding.base64;
import java.util.Map; import java.util.Map;
import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.googlecloudstorage.domain.DomainResourceReferences.StorageClass;
import org.jclouds.googlecloudstorage.domain.templates.ObjectTemplate; import org.jclouds.googlecloudstorage.domain.templates.ObjectTemplate;
import org.jclouds.io.ContentMetadata; import org.jclouds.io.ContentMetadata;
@ -47,7 +48,8 @@ public class BlobMetadataToObjectTemplate implements Function<BlobMetadata, Obje
ObjectTemplate template = new ObjectTemplate().contentType(contentType).size(contentLength) ObjectTemplate template = new ObjectTemplate().contentType(contentType).size(contentLength)
.contentEncoding(contentEncoding).contentLanguage(contentLanguage) .contentEncoding(contentEncoding).contentLanguage(contentLanguage)
.contentDisposition(contentDisposition).name(name).customMetadata(userMeta); .contentDisposition(contentDisposition).name(name).customMetadata(userMeta)
.storageClass(StorageClass.fromTier(from.getTier()));
if (md5 != null) { if (md5 != null) {
template.md5Hash(base64().encode(md5.asBytes())); template.md5Hash(base64().encode(md5.asBytes()));
} }

View File

@ -50,6 +50,7 @@ public class ObjectToBlobMetadata implements Function<GoogleCloudStorageObject,
to.setPublicUri(from.mediaLink()); to.setPublicUri(from.mediaLink());
to.setType(StorageType.BLOB); to.setType(StorageType.BLOB);
to.setSize(from.size()); to.setSize(from.size());
to.setTier(from.storageClass().toTier());
return to; return to;
} }

View File

@ -16,6 +16,10 @@
*/ */
package org.jclouds.googlecloudstorage.domain; package org.jclouds.googlecloudstorage.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.blobstore.domain.Tier;
import com.google.common.base.CaseFormat; import com.google.common.base.CaseFormat;
public final class DomainResourceReferences { public final class DomainResourceReferences {
@ -45,11 +49,30 @@ public final class DomainResourceReferences {
} }
public enum StorageClass { public enum StorageClass {
COLDLINE, COLDLINE(Tier.ARCHIVE),
DURABLE_REDUCED_AVAILABILITY, DURABLE_REDUCED_AVAILABILITY(Tier.STANDARD),
MULTI_REGIONAL, MULTI_REGIONAL(Tier.STANDARD),
NEARLINE, NEARLINE(Tier.INFREQUENT),
STANDARD; STANDARD(Tier.STANDARD);
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.NEARLINE;
case ARCHIVE: return StorageClass.COLDLINE;
}
throw new IllegalArgumentException("invalid tier: " + tier);
}
public Tier toTier() {
return tier;
}
} }
public enum Projection { public enum Projection {

View File

@ -17,6 +17,7 @@
package org.jclouds.googlecloudstorage.blobstore.integration; package org.jclouds.googlecloudstorage.blobstore.integration;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Fail.failBecauseExceptionWasNotThrown;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull; import static org.testng.Assert.assertNull;
@ -310,4 +311,24 @@ public class GoogleCloudStorageBlobIntegrationLiveTest extends BaseBlobIntegrati
throw new SkipException("GCS does not support listing multipart uploads", uoe); throw new SkipException("GCS does not support listing multipart uploads", uoe);
} }
} }
@Override
public void testPutBlobTierArchiveMultipart() throws Exception {
try {
super.testPutBlobTierArchiveMultipart();
failBecauseExceptionWasNotThrown(AssertionError.class);
} catch (AssertionError ae) {
throw new SkipException("GCS does not report storage class of composed objects", ae);
}
}
@Override
public void testPutBlobTierInfrequentMultipart() throws Exception {
try {
super.testPutBlobTierInfrequentMultipart();
failBecauseExceptionWasNotThrown(AssertionError.class);
} catch (AssertionError ae) {
throw new SkipException("GCS does not report storage class of composed objects", ae);
}
}
} }