JCLOUDS-1337: Portable storage tiers

This commit is contained in:
Andrew Gaul 2017-09-26 16:08:53 -07:00
parent 6cf0a63186
commit 6158b60954
8 changed files with 144 additions and 6 deletions

View File

@ -41,6 +41,9 @@ public interface BlobBuilder {
*/
BlobBuilder name(String name);
/** @param tier The storage tier of the {@link Blob}. Typically STANDARD. */
BlobBuilder tier(Tier tier);
/**
* @param type
* overrides default type of {@link StorageType#BLOB}

View File

@ -45,4 +45,6 @@ public interface BlobMetadata extends StorageMetadata {
String getContainer();
ContentMetadata getContentMetadata();
Tier getTier();
}

View File

@ -49,4 +49,6 @@ public interface MutableBlobMetadata extends BlobMetadata, MutableStorageMetadat
* @see BlobMetadata#getContainer
*/
void setContainer(@Nullable String container);
void setTier(Tier tier);
}

View File

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.blobstore.domain;
/**
* Store data with different strategies, ranging from most performant to lowest
* cost. Tiering is best-effort and some providers will map lower tiers to
* higher ones.
*/
public enum Tier {
/** Optimize for access speed. */
STANDARD,
/** Balance access speed against storage cost. */
INFREQUENT,
/**
* Optimize for storage cost. Some providers may require a separate call to
* set the blob to STANDARD tier before access.
*/
ARCHIVE;
}

View File

@ -29,6 +29,7 @@ import java.util.Map;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobBuilder;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.Tier;
import org.jclouds.io.Payload;
import org.jclouds.io.payloads.PhantomPayload;
@ -41,6 +42,7 @@ public class BlobBuilderImpl implements BlobBuilder {
private Payload payload;
private String name;
private Tier tier = Tier.STANDARD;
private Map<String, String> userMetadata = Maps.newLinkedHashMap();
private StorageType type = StorageType.BLOB;
@ -52,6 +54,12 @@ public class BlobBuilderImpl implements BlobBuilder {
return this;
}
@Override
public BlobBuilder tier(Tier tier) {
this.tier = checkNotNull(tier, "tier");
return this;
}
@Override
public BlobBuilder type(StorageType type) {
this.type = type;
@ -117,6 +125,7 @@ public class BlobBuilderImpl implements BlobBuilder {
blob.setPayload(payload);
blob.getMetadata().setUserMetadata(userMetadata);
blob.getMetadata().setType(type);
blob.getMetadata().setTier(tier);
return blob;
}
@ -134,6 +143,11 @@ public class BlobBuilderImpl implements BlobBuilder {
return builder.name(name);
}
@Override
public BlobBuilder tier(Tier tier) {
return builder.tier(tier);
}
@Override
public BlobBuilder type(StorageType type) {
return builder.type(type);

View File

@ -27,6 +27,7 @@ import com.google.common.base.MoreObjects.ToStringHelper;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.Tier;
import org.jclouds.domain.Location;
import org.jclouds.io.ContentMetadata;
import org.jclouds.javax.annotation.Nullable;
@ -39,15 +40,26 @@ public class BlobMetadataImpl extends StorageMetadataImpl implements BlobMetadat
private final URI publicUri;
private final String container;
private final ContentMetadata contentMetadata;
private final Tier tier;
public BlobMetadataImpl(String id, String name, @Nullable Location location, URI uri, String eTag,
@Nullable Date creationDate, @Nullable Date lastModified,
Map<String, String> userMetadata, @Nullable URI publicUri,
@Nullable String container, ContentMetadata contentMetadata, @Nullable Long size) {
@Nullable String container, ContentMetadata contentMetadata, @Nullable Long size,
Tier tier) {
super(StorageType.BLOB, id, name, location, uri, eTag, creationDate, lastModified, userMetadata, size);
this.publicUri = publicUri;
this.container = container;
this.contentMetadata = checkNotNull(contentMetadata, "contentMetadata");
this.tier = checkNotNull(tier, "tier");
}
@Deprecated
public BlobMetadataImpl(String id, String name, @Nullable Location location, URI uri, String eTag,
@Nullable Date creationDate, @Nullable Date lastModified,
Map<String, String> userMetadata, @Nullable URI publicUri,
@Nullable String container, ContentMetadata contentMetadata, @Nullable Long size) {
this(id, name, location, uri, eTag, creationDate, lastModified, userMetadata, publicUri, container, contentMetadata, size, Tier.STANDARD);
}
@Deprecated
@ -82,6 +94,11 @@ public class BlobMetadataImpl extends StorageMetadataImpl implements BlobMetadat
return contentMetadata;
}
@Override
public Tier getTier() {
return tier;
}
@Override
public boolean equals(Object object) {
if (object == this) {
@ -94,12 +111,13 @@ public class BlobMetadataImpl extends StorageMetadataImpl implements BlobMetadat
return super.equals(that) &&
Objects.equal(publicUri, that.publicUri) &&
Objects.equal(container, that.container) &&
Objects.equal(contentMetadata, that.contentMetadata);
Objects.equal(contentMetadata, that.contentMetadata) &&
Objects.equal(tier, that.tier);
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), publicUri, container, contentMetadata);
return Objects.hashCode(super.hashCode(), publicUri, container, contentMetadata, tier);
}
@Override
@ -107,6 +125,7 @@ public class BlobMetadataImpl extends StorageMetadataImpl implements BlobMetadat
return super.string()
.add("publicUri", publicUri)
.add("container", container)
.add("contentMetadata", contentMetadata);
.add("contentMetadata", contentMetadata)
.add("tier", tier);
}
}

View File

@ -24,6 +24,7 @@ import com.google.common.base.MoreObjects.ToStringHelper;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.Tier;
import org.jclouds.http.HttpUtils;
import org.jclouds.io.MutableContentMetadata;
import org.jclouds.io.payloads.BaseMutableContentMetadata;
@ -36,6 +37,7 @@ public class MutableBlobMetadataImpl extends MutableStorageMetadataImpl implemen
private MutableContentMetadata contentMetadata;
private URI publicUri;
private String container;
private Tier tier;
public MutableBlobMetadataImpl() {
this.setType(StorageType.BLOB);
@ -48,6 +50,7 @@ public class MutableBlobMetadataImpl extends MutableStorageMetadataImpl implemen
HttpUtils.copy(from.getContentMetadata(), this.contentMetadata);
this.publicUri = from.getPublicUri();
this.container = from.getContainer();
this.tier = from.getTier() == null ? Tier.STANDARD : from.getTier();
}
/**
@ -98,6 +101,16 @@ public class MutableBlobMetadataImpl extends MutableStorageMetadataImpl implemen
this.container = container;
}
@Override
public Tier getTier() {
return tier;
}
@Override
public void setTier(Tier tier) {
this.tier = tier;
}
@Override
public boolean equals(Object object) {
if (object == this) {
@ -110,7 +123,8 @@ public class MutableBlobMetadataImpl extends MutableStorageMetadataImpl implemen
return super.equals(that) &&
Objects.equal(contentMetadata, that.contentMetadata) &&
Objects.equal(publicUri, that.publicUri) &&
Objects.equal(container, that.container);
Objects.equal(container, that.container) &&
Objects.equal(tier, that.tier);
}
@Override
@ -123,6 +137,7 @@ public class MutableBlobMetadataImpl extends MutableStorageMetadataImpl implemen
return super.string()
.add("publicUri", publicUri)
.add("container", container)
.add("contentMetadata", contentMetadata);
.add("contentMetadata", contentMetadata)
.add("tier", tier);
}
}

View File

@ -59,6 +59,7 @@ import org.jclouds.blobstore.domain.MultipartUpload;
import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.Tier;
import org.jclouds.blobstore.options.CopyOptions;
import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.PutOptions;
@ -744,6 +745,54 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
}
}
@Test(groups = { "integration", "live" })
public void testPutBlobTierStandard() throws Exception {
testPutBlobTierHelper(Tier.STANDARD, new PutOptions());
}
@Test(groups = { "integration", "live" })
public void testPutBlobTierInfrequent() throws Exception {
testPutBlobTierHelper(Tier.INFREQUENT, new PutOptions());
}
@Test(groups = { "integration", "live" })
public void testPutBlobTierArchive() throws Exception {
testPutBlobTierHelper(Tier.ARCHIVE, new PutOptions());
}
@Test(groups = { "integration", "live" })
public void testPutBlobTierStandardMultipart() throws Exception {
testPutBlobTierHelper(Tier.STANDARD, new PutOptions().multipart(true));
}
@Test(groups = { "integration", "live" })
public void testPutBlobTierInfrequentMultipart() throws Exception {
testPutBlobTierHelper(Tier.INFREQUENT, new PutOptions().multipart(true));
}
@Test(groups = { "integration", "live" })
public void testPutBlobTierArchiveMultipart() throws Exception {
testPutBlobTierHelper(Tier.ARCHIVE, new PutOptions().multipart(true));
}
private void testPutBlobTierHelper(Tier tier, PutOptions options) throws Exception {
String blobName = "put-blob-tier-" + tier;
ByteSource payload = createTestInput(1024);
BlobStore blobStore = view.getBlobStore();
String containerName = getContainerName();
try {
Blob blob = blobStore.blobBuilder(blobName)
.payload(payload)
.contentLength(payload.size())
.tier(tier)
.build();
blobStore.putBlob(containerName, blob, options);
assertThat(blobStore.blobMetadata(containerName, blobName).getTier()).isEqualTo(tier);
} finally {
returnContainer(containerName);
}
}
protected void checkUserMetadata(Map<String, String> userMetadata1, Map<String, String> userMetadata2) {
assertThat(userMetadata1).isEqualTo(userMetadata2);
}