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/09 08:21:40 UTC

[10/16] jclouds git commit: Allows copying an object and modifying metadata (user and object)

Allows copying an object and modifying metadata (user and object)


Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/b5491c48
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/b5491c48
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/b5491c48

Branch: refs/heads/1.9.x
Commit: b5491c48483861bf6ca3be007b6d7a44fd11b4f4
Parents: c87e205
Author: Zack Shoylev <za...@rackspace.com>
Authored: Tue Mar 31 17:30:56 2015 -0500
Committer: Andrew Gaul <ga...@apache.org>
Committed: Wed Apr 8 23:13:52 2015 -0700

----------------------------------------------------------------------
 .../swift/v1/binders/BindMetadataToHeaders.java |  6 +++
 .../openstack/swift/v1/features/ObjectApi.java  | 33 ++++++++++++
 .../swift/v1/features/ObjectApiMockTest.java    | 56 ++++++++++++++++++--
 3 files changed, 91 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/b5491c48/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindMetadataToHeaders.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindMetadataToHeaders.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindMetadataToHeaders.java
index 9451934..d27e19d 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindMetadataToHeaders.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindMetadataToHeaders.java
@@ -85,6 +85,12 @@ public class BindMetadataToHeaders implements Binder {
       }
    }
 
+   public static class BindHeaderMetadataToHeaders extends BindMetadataToHeaders {
+      BindHeaderMetadataToHeaders() {
+         super("");
+      }
+   }
+
    public static class BindRemoveObjectMetadataToHeaders extends BindMetadataToHeaders.ForRemoval {
       BindRemoveObjectMetadataToHeaders() {
          super(OBJECT_METADATA_PREFIX);

http://git-wip-us.apache.org/repos/asf/jclouds/blob/b5491c48/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
index 4d4d603..7d89ba3 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
@@ -41,6 +41,7 @@ import org.jclouds.http.options.GetOptions;
 import org.jclouds.io.Payload;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindHeaderMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindObjectMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveObjectMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.binders.SetPayload;
@@ -262,4 +263,36 @@ public interface ObjectApi {
                 @PathParam("sourceContainer") String sourceContainer,
                 @PathParam("sourceObject") String sourceObject);
 
+   /**
+    * Copies an object from one container to another.
+    *
+    * <h3>NOTE</h3>
+    * This is a server side copy.
+    *
+    * @param destinationObject
+    *           the destination object name.
+    * @param sourceContainer
+    *           the source container name.
+    * @param sourceObject
+    *           the source object name.
+    * @param userMetadata
+    *           Freeform metadata for the object, automatically prefixed/escaped
+    * @param objectMetadata
+    *           Unprefixed/unescaped metadata, such as Content-Disposition
+    *
+    * @return {@code true} if the object was successfully copied, {@code false} if not.
+    *
+    * @throws org.jclouds.openstack.swift.v1.CopyObjectException if the source or destination container do not exist.
+    */
+   @Named("object:copy")
+   @PUT
+   @Path("/{destinationObject}")
+   @Headers(keys = OBJECT_COPY_FROM, values = "/{sourceContainer}/{sourceObject}")
+   @Fallback(FalseOnContainerNotFound.class)
+   boolean copy(@PathParam("destinationObject") String destinationObject,
+         @PathParam("sourceContainer") String sourceContainer,
+         @PathParam("sourceObject") String sourceObject,
+         @BinderParam(BindObjectMetadataToHeaders.class) Map<String, String> userMetadata,
+         @BinderParam(BindHeaderMetadataToHeaders.class) Map<String, String> objectMetadata);
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/b5491c48/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
index 87166df..81a856e 100644
--- a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
@@ -39,6 +39,7 @@ import static org.testng.Assert.fail;
 import java.io.IOException;
 import java.net.URI;
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
@@ -193,7 +194,8 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    public void testCreateWithSpacesAndSpecialCharacters() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
-      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201).addHeader("ETag", "d9f5eb4bba4e2f2f046e54611bc8196b")));
+      server.enqueue(addCommonHeaders(
+            new MockResponse().setResponseCode(201).addHeader("ETag", "d9f5eb4bba4e2f2f046e54611bc8196b")));
 
       final String containerName = "container # ! special";
       final String objectName = "object # ! special";
@@ -279,7 +281,8 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
          assertEquals(server.getRequestCount(), 2);
          assertAuthentication(server);
-         assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject");
+         assertRequest(server.takeRequest(), "HEAD",
+               "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject");
       } finally {
          server.shutdown();
       }
@@ -339,7 +342,7 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
          fail("testReplaceTimeout test should have failed with an HttpResponseException.");
       } finally {
-         try { 
+         try {
             server.shutdown();
          } catch (IOException e) {
             // MockWebServer 2.1.0 introduces an active wait for its executor termination.
@@ -469,7 +472,7 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
          assertTrue(api.getObjectApi("DFW", "foo")
-            .copy("bar.txt", "bar", "foo.txt"));
+               .copy("bar.txt", "bar", "foo.txt"));
 
          assertEquals(server.getRequestCount(), 2);
          assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
@@ -498,6 +501,51 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
       }
    }
 
+   public void testCopyObjectWithMetadata() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)
+            .addHeader(SwiftHeaders.OBJECT_COPY_FROM, "/bar/foo.txt")));
+
+      try {
+         SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+         assertTrue(api.getObjectApi("DFW", "foo")
+               .copy("bar.txt", "bar", "foo.txt", ImmutableMap.of("someUserHeader", "someUserMetadataValue"),
+                     ImmutableMap.of("Content-Disposition", "attachment; filename=\"fname.ext\"")));
+
+         assertEquals(server.getRequestCount(), 2);
+         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+
+         RecordedRequest copyRequest = server.takeRequest();
+         assertEquals(copyRequest.getRequestLine(),
+               "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/foo/bar.txt HTTP/1.1");
+
+         List<String> requestHeaders = copyRequest.getHeaders();
+         assertTrue(requestHeaders.contains("X-Object-Meta-someuserheader: someUserMetadataValue"));
+         assertTrue(requestHeaders.contains("content-disposition: attachment; filename=\"fname.ext\""));
+         assertTrue(requestHeaders.contains(SwiftHeaders.OBJECT_COPY_FROM + ": /bar/foo.txt"));
+      } finally {
+         server.shutdown();
+      }
+   }
+
+   @Test(expectedExceptions = CopyObjectException.class)
+   public void testCopyObjectWithMetadataFail() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)
+            .addHeader(SwiftHeaders.OBJECT_COPY_FROM, "/bar/foo.txt")));
+
+      try {
+         SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+         assertTrue(api.getObjectApi("DFW", "foo")
+               .copy("bar.txt", "bar", "foo.txt", ImmutableMap.of("someUserHeader", "someUserMetadataValue"),
+                     ImmutableMap.of("Content-Disposition", "attachment; filename=\"fname.ext\"")));
+      } finally {
+         server.shutdown();
+      }
+   }
+
    private static final Map<String, String> metadata = ImmutableMap.of("ApiName", "swift", "ApiVersion", "v1.1");
 
    static MockResponse objectResponse() {