mirror of https://github.com/apache/jclouds.git
Allows copying an object and modifying metadata (user and object)
This commit is contained in:
parent
c87e2052ac
commit
b5491c4848
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue