You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ga...@apache.org on 2015/04/03 00:40:47 UTC
[1/4] jclouds git commit: JCLOUDS-651: Add copyBlob to portable
abstraction
Repository: jclouds
Updated Branches:
refs/heads/master 914ad04ae -> 67d731f05
JCLOUDS-651: Add copyBlob to portable abstraction
Some providers optimize this operation with a server-side copy. Add a
fallback implementation which does a client-side copy.
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/3cf8abc2
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/3cf8abc2
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/3cf8abc2
Branch: refs/heads/master
Commit: 3cf8abc22e896f51ed388349252da8b1445c0bfd
Parents: 914ad04
Author: Andrew Gaul <ga...@apache.org>
Authored: Fri Sep 5 17:32:08 2014 -0700
Committer: Andrew Gaul <ga...@apache.org>
Committed: Thu Apr 2 15:36:52 2015 -0700
----------------------------------------------------------------------
.../java/org/jclouds/blobstore/BlobStore.java | 13 ++++
.../blobstore/config/LocalBlobStore.java | 41 +++++++++++
.../blobstore/internal/BaseBlobStore.java | 44 +++++++++++
.../jclouds/blobstore/options/CopyOptions.java | 57 +++++++++++++++
.../blobstore/util/ForwardingBlobStore.java | 7 ++
.../blobstore/util/ReadOnlyBlobStore.java | 7 ++
.../internal/BaseBlobIntegrationTest.java | 77 ++++++++++++++++++++
7 files changed, 246 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds/blob/3cf8abc2/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java
----------------------------------------------------------------------
diff --git a/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java
index bebdb48..f4b26d2 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java
@@ -27,6 +27,7 @@ import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerAccess;
import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
+import org.jclouds.blobstore.options.CopyOptions;
import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
@@ -230,6 +231,18 @@ public interface BlobStore {
String putBlob(String container, Blob blob, PutOptions options);
/**
+ * Copy blob from one container to another. Some providers implement this
+ * more efficiently than corresponding getBlob and putBlob operations.
+ *
+ * Note: options are currently ignored
+ *
+ * @return ETag of new blob
+ * @throws ContainerNotFoundException if either container does not exist
+ */
+ String copyBlob(String fromContainer, String fromName, String toContainer, String toName,
+ CopyOptions options);
+
+ /**
* Retrieves the metadata of a {@code Blob} at location {@code container/name}
*
* @param container
http://git-wip-us.apache.org/repos/asf/jclouds/blob/3cf8abc2/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java
----------------------------------------------------------------------
diff --git a/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java
index 36e883d..2e1b636 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java
@@ -30,7 +30,9 @@ import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursi
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.util.Date;
+import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.regex.Pattern;
@@ -57,6 +59,7 @@ import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
import org.jclouds.blobstore.domain.internal.PageSetImpl;
import org.jclouds.blobstore.domain.internal.StorageMetadataImpl;
+import org.jclouds.blobstore.options.CopyOptions;
import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
@@ -75,11 +78,13 @@ import org.jclouds.io.ContentMetadata;
import org.jclouds.io.ContentMetadataCodec;
import org.jclouds.io.Payload;
import org.jclouds.logging.Logger;
+import org.jclouds.util.Closeables2;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
+import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@@ -493,6 +498,42 @@ public final class LocalBlobStore implements BlobStore {
}
}
+ @Override
+ public String copyBlob(String fromContainer, String fromName, String toContainer, String toName,
+ CopyOptions options) {
+ Blob blob = getBlob(fromContainer, fromName);
+ if (blob == null) {
+ throw new KeyNotFoundException(fromContainer, fromName, "while copying");
+ }
+
+ InputStream is = null;
+ try {
+ is = blob.getPayload().openStream();
+ ContentMetadata metadata = blob.getMetadata().getContentMetadata();
+ BlobBuilder.PayloadBlobBuilder builder = blobBuilder(toName)
+ .payload(is)
+ .contentDisposition(metadata.getContentDisposition())
+ .contentEncoding(metadata.getContentEncoding())
+ .contentLanguage(metadata.getContentLanguage())
+ .contentType(metadata.getContentType());
+ Long contentLength = metadata.getContentLength();
+ if (contentLength != null) {
+ builder.contentLength(contentLength);
+ }
+ Optional<Map<String, String>> userMetadata = options.getUserMetadata();
+ if (userMetadata.isPresent()) {
+ builder.userMetadata(userMetadata.get());
+ } else {
+ builder.userMetadata(blob.getMetadata().getUserMetadata());
+ }
+ return putBlob(toContainer, builder.build());
+ } catch (IOException ioe) {
+ throw Throwables.propagate(ioe);
+ } finally {
+ Closeables2.closeQuietly(is);
+ }
+ }
+
private void copyPayloadHeadersToBlob(Payload payload, Blob blob) {
blob.getAllHeaders().putAll(contentMetadataCodec.toHeaders(payload.getContentMetadata()));
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/3cf8abc2/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java
----------------------------------------------------------------------
diff --git a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java
index 73a01b3..1204e0d 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java
@@ -21,6 +21,9 @@ import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
import static org.jclouds.util.Predicates2.retry;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
@@ -28,17 +31,23 @@ import javax.inject.Inject;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.ContainerNotFoundException;
+import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobBuilder;
import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
+import org.jclouds.blobstore.options.CopyOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location;
+import org.jclouds.io.ContentMetadata;
+import org.jclouds.util.Closeables2;
+import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
+import com.google.common.base.Throwables;
public abstract class BaseBlobStore implements BlobStore {
@@ -231,4 +240,39 @@ public abstract class BaseBlobStore implements BlobStore {
*/
protected abstract boolean deleteAndVerifyContainerGone(String container);
+ @Override
+ public String copyBlob(String fromContainer, String fromName, String toContainer, String toName,
+ CopyOptions options) {
+ Blob blob = getBlob(fromContainer, fromName);
+ if (blob == null) {
+ throw new KeyNotFoundException(fromContainer, fromName, "while copying");
+ }
+
+ InputStream is = null;
+ try {
+ is = blob.getPayload().openStream();
+ ContentMetadata metadata = blob.getMetadata().getContentMetadata();
+ BlobBuilder.PayloadBlobBuilder builder = blobBuilder(toName)
+ .payload(is)
+ .contentDisposition(metadata.getContentDisposition())
+ .contentEncoding(metadata.getContentEncoding())
+ .contentLanguage(metadata.getContentLanguage())
+ .contentType(metadata.getContentType());
+ Long contentLength = metadata.getContentLength();
+ if (contentLength != null) {
+ builder.contentLength(contentLength);
+ }
+ Optional<Map<String, String>> userMetadata = options.getUserMetadata();
+ if (userMetadata.isPresent()) {
+ builder.userMetadata(userMetadata.get());
+ } else {
+ builder.userMetadata(blob.getMetadata().getUserMetadata());
+ }
+ return putBlob(toContainer, builder.build());
+ } catch (IOException ioe) {
+ throw Throwables.propagate(ioe);
+ } finally {
+ Closeables2.closeQuietly(is);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/3cf8abc2/blobstore/src/main/java/org/jclouds/blobstore/options/CopyOptions.java
----------------------------------------------------------------------
diff --git a/blobstore/src/main/java/org/jclouds/blobstore/options/CopyOptions.java b/blobstore/src/main/java/org/jclouds/blobstore/options/CopyOptions.java
new file mode 100644
index 0000000..3b89e98
--- /dev/null
+++ b/blobstore/src/main/java/org/jclouds/blobstore/options/CopyOptions.java
@@ -0,0 +1,57 @@
+/*
+ * 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.options;
+
+import java.util.Map;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+
+public final class CopyOptions {
+ public static final CopyOptions NONE = builder().build();
+
+ private final Optional<Map<String, String>> userMetadata;
+
+ private CopyOptions(Builder builder) {
+ this.userMetadata = Optional.fromNullable(builder.userMetadata);
+ }
+
+ public Optional<Map<String, String>> getUserMetadata() {
+ return userMetadata;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ Map<String, String> userMetadata;
+
+ Builder() {
+ }
+
+ public Builder userMetadata(Map<String, String> userMetadata) {
+ this.userMetadata = ImmutableMap.copyOf(userMetadata);
+ return this;
+ }
+
+ public CopyOptions build() {
+ return new CopyOptions(this);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/3cf8abc2/blobstore/src/main/java/org/jclouds/blobstore/util/ForwardingBlobStore.java
----------------------------------------------------------------------
diff --git a/blobstore/src/main/java/org/jclouds/blobstore/util/ForwardingBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/util/ForwardingBlobStore.java
index 55860ec..60c2d7a 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/util/ForwardingBlobStore.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/util/ForwardingBlobStore.java
@@ -32,6 +32,7 @@ import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerAccess;
import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
+import org.jclouds.blobstore.options.CopyOptions;
import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
@@ -162,6 +163,12 @@ public abstract class ForwardingBlobStore extends ForwardingObject
}
@Override
+ public String copyBlob(String fromContainer, String fromName, String toContainer, String toName,
+ CopyOptions options) {
+ return delegate().copyBlob(fromContainer, fromName, toContainer, toName, options);
+ }
+
+ @Override
public BlobMetadata blobMetadata(String container, String name) {
return delegate().blobMetadata(container, name);
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/3cf8abc2/blobstore/src/main/java/org/jclouds/blobstore/util/ReadOnlyBlobStore.java
----------------------------------------------------------------------
diff --git a/blobstore/src/main/java/org/jclouds/blobstore/util/ReadOnlyBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/util/ReadOnlyBlobStore.java
index dfb4a02..16e481e 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/util/ReadOnlyBlobStore.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/util/ReadOnlyBlobStore.java
@@ -23,6 +23,7 @@ import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobAccess;
import org.jclouds.blobstore.domain.BlobBuilder;
import org.jclouds.blobstore.domain.ContainerAccess;
+import org.jclouds.blobstore.options.CopyOptions;
import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
@@ -107,6 +108,12 @@ public final class ReadOnlyBlobStore extends ForwardingBlobStore {
}
@Override
+ public String copyBlob(String fromContainer, String fromName, String toContainer, String toName,
+ CopyOptions options) {
+ throw new UnsupportedOperationException("Read-only BlobStore");
+ }
+
+ @Override
public void removeBlob(String container, String name) {
throw new UnsupportedOperationException("Read-only BlobStore");
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/3cf8abc2/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 81b3af2..b205e84 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
@@ -57,6 +57,7 @@ import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType;
+import org.jclouds.blobstore.options.CopyOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.crypto.Crypto;
import org.jclouds.encryption.internal.JCECrypto;
@@ -82,6 +83,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.hash.HashCode;
+import com.google.common.io.ByteStreams;
import com.google.common.io.ByteSource;
import com.google.common.io.Files;
import com.google.common.util.concurrent.ListenableFuture;
@@ -729,6 +731,81 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
}
}
+ @Test(groups = { "integration", "live" })
+ public void testCopyBlobCopyMetadata() throws Exception {
+ BlobStore blobStore = view.getBlobStore();
+ String fromName = "source";
+ String toName = "to";
+ ByteSource payload = TestUtils.randomByteSource().slice(0, 1024);
+ Map<String, String> userMetadata = ImmutableMap.of("key1", "value1", "key2", "value2");
+ PayloadBlobBuilder blobBuilder = blobStore
+ .blobBuilder(fromName)
+ .payload(payload)
+ .contentLength(payload.size());
+ addContentMetadata(blobBuilder);
+ blobBuilder.userMetadata(userMetadata);
+ Blob blob = blobBuilder.build();
+
+ String fromContainer = getContainerName();
+ String toContainer = getContainerName();
+ try {
+ blobStore.putBlob(fromContainer, blob);
+ blobStore.copyBlob(fromContainer, fromName, toContainer, toName, CopyOptions.NONE);
+ Blob toBlob = blobStore.getBlob(toContainer, toName);
+ InputStream is = null;
+ try {
+ is = toBlob.getPayload().openStream();
+ assertEquals(ByteStreams.toByteArray(is), payload.read());
+ } finally {
+ Closeables2.closeQuietly(is);
+ }
+ // TODO: Swift does not preserve system metadata
+ //checkContentMetadata(toBlob);
+ assertThat(toBlob.getMetadata().getUserMetadata()).isEqualTo(userMetadata);
+ } finally {
+ returnContainer(toContainer);
+ returnContainer(fromContainer);
+ }
+ }
+
+ @Test(groups = { "integration", "live" })
+ public void testCopyBlobReplaceMetadata() throws Exception {
+ BlobStore blobStore = view.getBlobStore();
+ String fromName = "source";
+ String toName = "to";
+ ByteSource payload = TestUtils.randomByteSource().slice(0, 1024);
+ PayloadBlobBuilder blobBuilder = blobStore
+ .blobBuilder(fromName)
+ .payload(payload)
+ .contentLength(payload.size());
+ addContentMetadata(blobBuilder);
+ Blob blob = blobBuilder.build();
+
+ String fromContainer = getContainerName();
+ String toContainer = getContainerName();
+ try {
+ blobStore.putBlob(fromContainer, blob);
+ Map<String, String> userMetadata = ImmutableMap.of("key1", "value1", "key2", "value2");
+ blobStore.copyBlob(fromContainer, fromName, toContainer, toName,
+ CopyOptions.builder().userMetadata(userMetadata).build());
+ Blob toBlob = blobStore.getBlob(toContainer, toName);
+ InputStream is = null;
+ try {
+ is = toBlob.getPayload().openStream();
+ assertEquals(ByteStreams.toByteArray(is), payload.read());
+ } finally {
+ Closeables2.closeQuietly(is);
+ }
+ // TODO: S3 overrideMetadataWith also overrides system metadata
+ // TODO: Swift does not preserve system metadata
+ //checkContentMetadata(toBlob);
+ assertThat(toBlob.getMetadata().getUserMetadata()).isEqualTo(userMetadata);
+ } finally {
+ returnContainer(toContainer);
+ returnContainer(fromContainer);
+ }
+ }
+
protected void validateMetadata(BlobMetadata metadata) throws IOException {
assert metadata.getContentMetadata().getContentType().startsWith("text/plain") : metadata.getContentMetadata()
.getContentType();
[3/4] jclouds git commit: JCLOUDS-651: Add S3 server-side copyBlob
Posted by ga...@apache.org.
JCLOUDS-651: Add S3 server-side copyBlob
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/b85068ca
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/b85068ca
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/b85068ca
Branch: refs/heads/master
Commit: b85068ca7fa608ffd785cbc6ef3c003ef85deb4d
Parents: 31369ae
Author: Andrew Gaul <ga...@apache.org>
Authored: Fri Sep 5 19:06:16 2014 -0700
Committer: Andrew Gaul <ga...@apache.org>
Committed: Thu Apr 2 15:36:53 2015 -0700
----------------------------------------------------------------------
.../org/jclouds/s3/blobstore/S3BlobStore.java | 22 ++++++++++++++++++++
1 file changed, 22 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b85068ca/apis/s3/src/main/java/org/jclouds/s3/blobstore/S3BlobStore.java
----------------------------------------------------------------------
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 2d6b84a..cd38e52 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
@@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.util.Predicates2.retry;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
@@ -37,6 +38,7 @@ import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.internal.BaseBlobStore;
+import org.jclouds.blobstore.options.CopyOptions;
import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
@@ -57,12 +59,14 @@ import org.jclouds.s3.domain.AccessControlList.GroupGranteeURI;
import org.jclouds.s3.domain.AccessControlList.Permission;
import org.jclouds.s3.domain.BucketMetadata;
import org.jclouds.s3.domain.CannedAccessPolicy;
+import org.jclouds.s3.options.CopyObjectOptions;
import org.jclouds.s3.options.ListBucketOptions;
import org.jclouds.s3.options.PutBucketOptions;
import org.jclouds.s3.options.PutObjectOptions;
import org.jclouds.s3.util.S3Utils;
import com.google.common.base.Function;
+import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.cache.CacheLoader;
@@ -273,6 +277,24 @@ public class S3BlobStore extends BaseBlobStore {
return sync.putObject(container, blob2Object.apply(blob), options);
}
+ @Override
+ public String copyBlob(String fromContainer, String fromName, String toContainer, String toName,
+ CopyOptions options) {
+ CopyObjectOptions s3Options = new CopyObjectOptions();
+
+ // TODO: content disposition
+ // TODO: content encoding
+ // TODO: content language
+ // TODO: content type
+
+ Optional<Map<String, String>> userMetadata = options.getUserMetadata();
+ if (userMetadata.isPresent()) {
+ s3Options.overrideMetadataWith(userMetadata.get());
+ }
+
+ return sync.copyObject(fromContainer, fromName, toContainer, toName, s3Options).getETag();
+ }
+
/**
* This implementation invokes {@link S3Client#deleteObject}
*
[2/4] jclouds git commit: JCLOUDS-651: Add Azure server-side copyBlob
Posted by ga...@apache.org.
JCLOUDS-651: Add Azure server-side copyBlob
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/31369ae5
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/31369ae5
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/31369ae5
Branch: refs/heads/master
Commit: 31369ae59058da5ba0331f79f3576c112e22414f
Parents: 3cf8abc
Author: Andrew Gaul <ga...@apache.org>
Authored: Tue Mar 31 11:36:26 2015 -0700
Committer: Andrew Gaul <ga...@apache.org>
Committed: Thu Apr 2 15:36:53 2015 -0700
----------------------------------------------------------------------
.../azureblob/blobstore/AzureBlobStore.java | 29 ++++++++++++++++++++
1 file changed, 29 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds/blob/31369ae5/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureBlobStore.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureBlobStore.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureBlobStore.java
index 9144700..ccd31b5 100644
--- a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureBlobStore.java
+++ b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureBlobStore.java
@@ -19,7 +19,9 @@ package org.jclouds.azureblob.blobstore;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.azure.storage.options.ListOptions.Builder.includeMetadata;
+import java.net.URI;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
@@ -38,6 +40,7 @@ import org.jclouds.azureblob.blobstore.strategy.MultipartUploadStrategy;
import org.jclouds.azureblob.domain.ContainerProperties;
import org.jclouds.azureblob.domain.ListBlobBlocksResponse;
import org.jclouds.azureblob.domain.PublicAccess;
+import org.jclouds.azureblob.options.CopyBlobOptions;
import org.jclouds.azureblob.options.ListBlobsOptions;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.domain.Blob;
@@ -49,6 +52,7 @@ import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.internal.PageSetImpl;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.internal.BaseBlobStore;
+import org.jclouds.blobstore.options.CopyOptions;
import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
@@ -58,6 +62,7 @@ import org.jclouds.domain.Location;
import org.jclouds.http.options.GetOptions;
import com.google.common.base.Function;
+import com.google.common.base.Optional;
import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
import org.jclouds.io.Payload;
@@ -215,6 +220,30 @@ public class AzureBlobStore extends BaseBlobStore {
return putBlob(container, blob);
}
+ @Override
+ public String copyBlob(String fromContainer, String fromName, String toContainer, String toName,
+ CopyOptions options) {
+ CopyBlobOptions.Builder azureOptions = CopyBlobOptions.builder();
+
+ Optional<Map<String, String>> userMetadata = options.getUserMetadata();
+ if (userMetadata.isPresent()) {
+ azureOptions.overrideUserMetadata(userMetadata.get());
+ }
+
+ URI source = context.getSigner().signGetBlob(fromContainer, fromName).getEndpoint();
+ sync.copyBlob(source, toContainer, toName, azureOptions.build());
+
+ String eTag = sync.getBlobProperties(toContainer, toName).getETag();
+
+ // TODO: Azure does not allow updating system metadata during copy - call SetBlobProperties (not yet implemented)
+ // TODO: content disposition
+ // TODO: content encoding
+ // TODO: content language
+ // TODO: content type
+
+ return eTag;
+ }
+
/**
* This implementation invokes {@link AzureBlobClient#deleteObject}
*
[4/4] jclouds git commit: JCLOUDS-651: Add Swift server-side copyBlob
Posted by ga...@apache.org.
JCLOUDS-651: Add Swift server-side copyBlob
This has some limitations as discussed in JCLOUDS-872.
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/67d731f0
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/67d731f0
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/67d731f0
Branch: refs/heads/master
Commit: 67d731f0543a3f95d164ffb1bc3e37ef6c9361ec
Parents: b85068c
Author: Andrew Gaul <ga...@apache.org>
Authored: Sun Mar 29 21:51:03 2015 -0700
Committer: Andrew Gaul <ga...@apache.org>
Committed: Thu Apr 2 15:36:54 2015 -0700
----------------------------------------------------------------------
.../blobstore/RegionScopedSwiftBlobStore.java | 28 ++++++++++++++++++++
1 file changed, 28 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds/blob/67d731f0/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
index d535569..4516264 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
@@ -25,6 +25,7 @@ import static org.jclouds.location.predicates.LocationPredicates.idEquals;
import static org.jclouds.openstack.swift.v1.options.PutOptions.Builder.metadata;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
@@ -44,6 +45,7 @@ import org.jclouds.blobstore.domain.internal.BlobBuilderImpl;
import org.jclouds.blobstore.domain.internal.BlobImpl;
import org.jclouds.blobstore.domain.internal.PageSetImpl;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
+import org.jclouds.blobstore.options.CopyOptions;
import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
@@ -229,6 +231,32 @@ public class RegionScopedSwiftBlobStore implements BlobStore {
}
@Override
+ public String copyBlob(String fromContainer, String fromName, String toContainer, String toName,
+ CopyOptions options) {
+ ObjectApi objectApi = api.getObjectApi(regionId, toContainer);
+
+ boolean copied = objectApi.copy(toName, fromContainer, fromName);
+ if (!copied) {
+ throw new RuntimeException("could not copy blob");
+ }
+
+ // TODO: content disposition
+ // TODO: content encoding
+ // TODO: content language
+ // TODO: content type
+
+ Optional<Map<String, String>> userMetadata = options.getUserMetadata();
+ if (userMetadata.isPresent()) {
+ boolean updated = objectApi.updateMetadata(toName, userMetadata.get());
+ if (!updated) {
+ throw new RuntimeException("could not copy blob");
+ }
+ }
+
+ return objectApi.getWithoutBody(toName).getETag();
+ }
+
+ @Override
public BlobMetadata blobMetadata(String container, String name) {
SwiftObject object = api.getObjectApi(regionId, container).get(name);
if (object == null) {