Repository: jclouds Updated Branches: refs/heads/master 6cf0a6318 -> 89053d9a8
JCLOUDS-1337: Portable storage tiers Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/6158b609 Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/6158b609 Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/6158b609 Branch: refs/heads/master Commit: 6158b60954fe6c75ad3fda08858639af146538c8 Parents: 6cf0a63 Author: Andrew Gaul <[email protected]> Authored: Tue Sep 26 16:08:53 2017 -0700 Committer: Andrew Gaul <[email protected]> Committed: Wed Oct 11 12:04:02 2017 -0700 ---------------------------------------------------------------------- .../jclouds/blobstore/domain/BlobBuilder.java | 3 ++ .../jclouds/blobstore/domain/BlobMetadata.java | 2 + .../blobstore/domain/MutableBlobMetadata.java | 2 + .../java/org/jclouds/blobstore/domain/Tier.java | 34 ++++++++++++++ .../domain/internal/BlobBuilderImpl.java | 14 ++++++ .../domain/internal/BlobMetadataImpl.java | 27 +++++++++-- .../internal/MutableBlobMetadataImpl.java | 19 +++++++- .../internal/BaseBlobIntegrationTest.java | 49 ++++++++++++++++++++ 8 files changed, 144 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/6158b609/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java ---------------------------------------------------------------------- diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java index 5d0bb0f..b5964ce 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java @@ -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} http://git-wip-us.apache.org/repos/asf/jclouds/blob/6158b609/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobMetadata.java ---------------------------------------------------------------------- diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobMetadata.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobMetadata.java index fd88dc4..1b51328 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobMetadata.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobMetadata.java @@ -45,4 +45,6 @@ public interface BlobMetadata extends StorageMetadata { String getContainer(); ContentMetadata getContentMetadata(); + + Tier getTier(); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/6158b609/blobstore/src/main/java/org/jclouds/blobstore/domain/MutableBlobMetadata.java ---------------------------------------------------------------------- diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/MutableBlobMetadata.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/MutableBlobMetadata.java index 5b8dc2a..30fa913 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/domain/MutableBlobMetadata.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/MutableBlobMetadata.java @@ -49,4 +49,6 @@ public interface MutableBlobMetadata extends BlobMetadata, MutableStorageMetadat * @see BlobMetadata#getContainer */ void setContainer(@Nullable String container); + + void setTier(Tier tier); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/6158b609/blobstore/src/main/java/org/jclouds/blobstore/domain/Tier.java ---------------------------------------------------------------------- diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/Tier.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/Tier.java new file mode 100644 index 0000000..8273744 --- /dev/null +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/Tier.java @@ -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; +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/6158b609/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java ---------------------------------------------------------------------- diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java index e819001..0f1ce55 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java @@ -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; @@ -53,6 +55,12 @@ public class BlobBuilderImpl implements BlobBuilder { } @Override + public BlobBuilder tier(Tier tier) { + this.tier = checkNotNull(tier, "tier"); + return this; + } + + @Override public BlobBuilder type(StorageType type) { this.type = type; return this; @@ -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; } @@ -135,6 +144,11 @@ public class BlobBuilderImpl implements BlobBuilder { } @Override + public BlobBuilder tier(Tier tier) { + return builder.tier(tier); + } + + @Override public BlobBuilder type(StorageType type) { return builder.type(type); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/6158b609/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobMetadataImpl.java ---------------------------------------------------------------------- diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobMetadataImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobMetadataImpl.java index 5e7d2f9..bb99911 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobMetadataImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobMetadataImpl.java @@ -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 @@ -83,6 +95,11 @@ public class BlobMetadataImpl extends StorageMetadataImpl implements BlobMetadat } @Override + public Tier getTier() { + return tier; + } + + @Override public boolean equals(Object object) { if (object == this) { return true; @@ -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); } } http://git-wip-us.apache.org/repos/asf/jclouds/blob/6158b609/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/MutableBlobMetadataImpl.java ---------------------------------------------------------------------- diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/MutableBlobMetadataImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/MutableBlobMetadataImpl.java index 5320be5..fe7ae44 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/MutableBlobMetadataImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/MutableBlobMetadataImpl.java @@ -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(); } /** @@ -99,6 +102,16 @@ public class MutableBlobMetadataImpl extends MutableStorageMetadataImpl implemen } @Override + public Tier getTier() { + return tier; + } + + @Override + public void setTier(Tier tier) { + this.tier = tier; + } + + @Override public boolean equals(Object object) { if (object == this) { return true; @@ -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); } } http://git-wip-us.apache.org/repos/asf/jclouds/blob/6158b609/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java ---------------------------------------------------------------------- diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java index d3e6c1b..27657ae 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java @@ -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); }
