Moved HP Storage Container Metadata parsing to Swift since it's a standard Swift feature.

Moved HP Storage createContainer(String, CreateContainerOptions) to CommonSwiftClient since it's a standard Swift feature.
Added support for setting Swift Container Metadata.
Added support for deleting Swift Container Metadata.
Added copy object feature to Swift.
Removed unnecessary TODO comment.
Changed DeleteContainerMetadataOptions to just be a List.
Changed CopyObjectOptions to be just be a String. Changed CommonSwiftClient.setContainerMetadata() to use just a Map for metadata. Added ExpectTests.
Changed setContainerMetadata() to use Iterable instead of List for more generic type goodness. Changed copyObject() to use 4 String params instead of 2 String params to be similar to other such methods in jclouds.
This commit is contained in:
Everett Toews 2012-08-30 17:23:57 -05:00
parent 196b5d7c55
commit 73746588f4
22 changed files with 829 additions and 81 deletions

View File

@ -96,6 +96,7 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest<CloudFil
Set<ContainerCDNMetadata> cdnMetadataList = getApi().listCDNContainers();
assertTrue(cdnMetadataList.size() >= 1);
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
final long initialTTL = cdnMetadata.getTTL();
assertTrue(cdnMetadataList.contains(new ContainerCDNMetadata(containerNameWithCDN, true, initialTTL, cdnUri)));

View File

@ -35,10 +35,13 @@ import org.jclouds.blobstore.binders.BindMapToHeadersWithPrefix;
import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.functions.ReturnFalseOnContainerNotFound;
import org.jclouds.blobstore.functions.ReturnFalseOnKeyNotFound;
import org.jclouds.blobstore.functions.ReturnNullOnContainerNotFound;
import org.jclouds.blobstore.functions.ReturnNullOnKeyNotFound;
import org.jclouds.http.functions.ParseETagHeader;
import org.jclouds.http.options.GetOptions;
import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.openstack.swift.binders.BindIterableToHeadersWithContainerDeleteMetadataPrefix;
import org.jclouds.openstack.swift.binders.BindMapToHeadersWithContainerMetadataPrefix;
import org.jclouds.openstack.swift.binders.BindSwiftObjectMetadataToRequest;
import org.jclouds.openstack.swift.domain.AccountMetadata;
import org.jclouds.openstack.swift.domain.ContainerMetadata;
@ -47,14 +50,26 @@ import org.jclouds.openstack.swift.domain.ObjectInfo;
import org.jclouds.openstack.swift.domain.SwiftObject;
import org.jclouds.openstack.swift.functions.ObjectName;
import org.jclouds.openstack.swift.functions.ParseAccountMetadataResponseFromHeaders;
import org.jclouds.openstack.swift.functions.ParseContainerMetadataFromHeaders;
import org.jclouds.openstack.swift.functions.ParseObjectFromHeadersAndHttpContent;
import org.jclouds.openstack.swift.functions.ParseObjectInfoFromHeaders;
import org.jclouds.openstack.swift.functions.ParseObjectInfoListFromJsonResponse;
import org.jclouds.openstack.swift.functions.ReturnTrueOn404FalseOn409;
import org.jclouds.openstack.swift.options.CreateContainerOptions;
import org.jclouds.openstack.swift.options.ListContainerOptions;
import org.jclouds.rest.annotations.*;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.annotations.Beta;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Provides;
@ -89,13 +104,50 @@ public interface CommonSwiftAsyncClient {
@Path("/")
ListenableFuture<? extends Set<ContainerMetadata>> listContainers(ListContainerOptions... options);
/**
* @see CommonSwiftClient#getContainerMetadata
*/
@Beta
@HEAD
@ResponseParser(ParseContainerMetadataFromHeaders.class)
@ExceptionParser(ReturnNullOnContainerNotFound.class)
@Path("/{container}")
ListenableFuture<ContainerMetadata> getContainerMetadata(@PathParam("container") String container);
/**
* @see CommonSwiftClient#setContainerMetadata
*/
@POST
@Path("/{container}")
@ExceptionParser(ReturnFalseOnContainerNotFound.class)
ListenableFuture<Boolean> setContainerMetadata(@PathParam("container") String container,
@BinderParam(BindMapToHeadersWithContainerMetadataPrefix.class) Map<String, String> containerMetadata);
/**
* @see CommonSwiftClient#deleteContainerMetadata
*/
@POST
@Path("/{container}")
@ExceptionParser(ReturnFalseOnContainerNotFound.class)
ListenableFuture<Boolean> deleteContainerMetadata(@PathParam("container") String container,
@BinderParam(BindIterableToHeadersWithContainerDeleteMetadataPrefix.class) Iterable<String> metadataKeys);
/**
* @see CommonSwiftClient#createContainer
*/
@PUT
@Path("/{container}")
ListenableFuture<Boolean> createContainer(@PathParam("container") String container,
CreateContainerOptions... options);
/**
* @see CommonSwiftClient#setObjectInfo
*/
@POST
@Path("/{container}/{name}")
ListenableFuture<Boolean> setObjectInfo(@PathParam("container") String container, @PathParam("name") String name,
@BinderParam(BindMapToHeadersWithPrefix.class) Map<String, String> userMetadata);
ListenableFuture<Boolean> setObjectInfo(@PathParam("container") String container,
@PathParam("name") String name,
@BinderParam(BindMapToHeadersWithPrefix.class) Map<String, String> userMetadata);
/**
* @see CommonSwiftClient#createContainer
@ -120,7 +172,7 @@ public interface CommonSwiftAsyncClient {
@ResponseParser(ParseObjectInfoListFromJsonResponse.class)
@Path("/{container}")
ListenableFuture<PageSet<ObjectInfo>> listObjects(@PathParam("container") String container,
ListContainerOptions... options);
ListContainerOptions... options);
/**
* @see CommonSwiftClient#containerExists
@ -136,9 +188,20 @@ public interface CommonSwiftAsyncClient {
@PUT
@Path("/{container}/{name}")
@ResponseParser(ParseETagHeader.class)
ListenableFuture<String> putObject(
@PathParam("container") String container,
@PathParam("name") @ParamParser(ObjectName.class) @BinderParam(BindSwiftObjectMetadataToRequest.class) SwiftObject object);
ListenableFuture<String> putObject(@PathParam("container") String container,
@PathParam("name") @ParamParser(ObjectName.class) @BinderParam(BindSwiftObjectMetadataToRequest.class) SwiftObject object);
/**
* @see CommonSwiftClient#copyObject
*/
@PUT
@Path("/{destinationContainer}/{destinationObject}")
@Headers(keys = SwiftHeaders.OBJECT_COPY_FROM, values = "/{sourceContainer}/{sourceObject}")
@ExceptionParser(ReturnFalseOnContainerNotFound.class)
ListenableFuture<Boolean> copyObject(@PathParam("sourceContainer") String sourceContainer,
@PathParam("sourceObject") String sourceObject,
@PathParam("destinationContainer") String destinationContainer,
@PathParam("destinationObject") String destinationObject);
/**
* @see CommonSwiftClient#getObject
@ -147,8 +210,9 @@ public interface CommonSwiftAsyncClient {
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
@ExceptionParser(ReturnNullOnKeyNotFound.class)
@Path("/{container}/{name}")
ListenableFuture<SwiftObject> getObject(@PathParam("container") String container, @PathParam("name") String name,
GetOptions... options);
ListenableFuture<SwiftObject> getObject(@PathParam("container") String container,
@PathParam("name") String name,
GetOptions... options);
/**
* @see CommonSwiftClient#getObjectInfo
@ -158,7 +222,7 @@ public interface CommonSwiftAsyncClient {
@ExceptionParser(ReturnNullOnKeyNotFound.class)
@Path("/{container}/{name}")
ListenableFuture<MutableObjectInfoWithMetadata> getObjectInfo(@PathParam("container") String container,
@PathParam("name") String name);
@PathParam("name") String name);
/**
* @see CommonSwiftClient#objectExists
@ -166,7 +230,8 @@ public interface CommonSwiftAsyncClient {
@HEAD
@ExceptionParser(ReturnFalseOnKeyNotFound.class)
@Path("/{container}/{name}")
ListenableFuture<Boolean> objectExists(@PathParam("container") String container, @PathParam("name") String name);
ListenableFuture<Boolean> objectExists(@PathParam("container") String container,
@PathParam("name") String name);
/**
* @see CommonSwiftClient#removeObject
@ -174,13 +239,14 @@ public interface CommonSwiftAsyncClient {
@DELETE
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@Path("/{container}/{name}")
ListenableFuture<Void> removeObject(@PathParam("container") String container, @PathParam("name") String name);
ListenableFuture<Void> removeObject(@PathParam("container") String container,
@PathParam("name") String name);
@PUT
@Path("/{container}/{name}")
@ResponseParser(ParseETagHeader.class)
@Headers(keys = "X-Object-Manifest", values="{container}/{name}")
ListenableFuture<String> putObjectManifest(@PathParam("container") String container,
@PathParam("name") String name);
@PathParam("name") String name);
}

View File

@ -31,6 +31,7 @@ import org.jclouds.openstack.swift.domain.ContainerMetadata;
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
import org.jclouds.openstack.swift.domain.ObjectInfo;
import org.jclouds.openstack.swift.domain.SwiftObject;
import org.jclouds.openstack.swift.options.CreateContainerOptions;
import org.jclouds.openstack.swift.options.ListContainerOptions;
import com.google.inject.Provides;
@ -87,24 +88,38 @@ public interface CommonSwiftClient {
*/
Set<ContainerMetadata> listContainers(ListContainerOptions... options);
boolean setObjectInfo(String container, String name, Map<String, String> userMetadata);
ContainerMetadata getContainerMetadata(String container);
boolean setContainerMetadata(String container, Map<String, String> containerMetadata);
boolean deleteContainerMetadata(String container, Iterable<String> metadataKeys);
boolean createContainer(String container);
boolean createContainer(String container, CreateContainerOptions... options);
boolean deleteContainerIfEmpty(String container);
PageSet<ObjectInfo> listObjects(String container, ListContainerOptions... options);
boolean containerExists(String container);
@Timeout(duration = 5 * 1024 * 1024 / 128, timeUnit = TimeUnit.SECONDS)
String putObject(String container, SwiftObject object);
PageSet<ObjectInfo> listObjects(String container, ListContainerOptions... options);
@Timeout(duration = 5 * 1024 * 1024 / 512, timeUnit = TimeUnit.SECONDS)
SwiftObject getObject(String container, String name, GetOptions... options);
boolean setObjectInfo(String container, String name, Map<String, String> userMetadata);
MutableObjectInfoWithMetadata getObjectInfo(String container, String name);
@Timeout(duration = 5 * 1024 * 1024 / 128, timeUnit = TimeUnit.SECONDS)
String putObject(String container, SwiftObject object);
/**
* @return True If the object was copied
* @throws CopyObjectException If the object was not copied
*/
boolean copyObject(String sourceContainer, String sourceObject, String destinationContainer, String destinationObject);
void removeObject(String container, String name);
/**

View File

@ -0,0 +1,59 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.openstack.swift;
import org.jclouds.rest.ResourceNotFoundException;
/**
* Thrown when an object cannot be copied.
*
* @author Everett Toews
*/
public class CopyObjectException extends ResourceNotFoundException {
private String sourcePath;
private String destinationPath;
public CopyObjectException() {
super();
}
public CopyObjectException(String sourcePath, String destinationPath, String message) {
super(String.format("Either the source path %s or the destination path %s was not found. " +
"(message: %s)", sourcePath, destinationPath, message));
this.sourcePath = sourcePath;
this.destinationPath = destinationPath;
}
public CopyObjectException(Exception from) {
super(from);
}
public String getSourcePath() {
return sourcePath;
}
public String getDestinationPath() {
return destinationPath;
}
/** The serialVersionUID */
private static final long serialVersionUID = -2272965726680721281L;
}

View File

@ -0,0 +1,72 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.openstack.swift.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Singleton;
import org.jclouds.http.HttpRequest;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
import org.jclouds.rest.Binder;
import com.google.common.base.Function;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Iterables;
/**
* @author Everett Toews
*/
@Singleton
public class BindIterableToHeadersWithContainerDeleteMetadataPrefix implements Binder {
private final Function<String, String> FN;
public BindIterableToHeadersWithContainerDeleteMetadataPrefix() {
FN = new Function<String, String>() {
@Override
public String apply(String element) {
String inLowercase = element.toLowerCase();
return (inLowercase.startsWith(SwiftHeaders.CONTAINER_DELETE_METADATA_PREFIX)) ? inLowercase : SwiftHeaders.CONTAINER_DELETE_METADATA_PREFIX + inLowercase;
}
@Override
public String toString() {
return "prefix: " + SwiftHeaders.CONTAINER_DELETE_METADATA_PREFIX;
}
};
}
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
checkArgument(checkNotNull(input, "input") instanceof Iterable<?>, "this binder is only valid for Iterable!");
checkNotNull(request, "request");
Iterable<String> metadataKeys = Iterables.transform((Iterable<String>) input, FN);
HashMultimap<String, String> headers = HashMultimap.create();
for (String metadataKey: metadataKeys) {
headers.put(metadataKey, "");
}
return (R) request.toBuilder().replaceHeaders(headers).build();
}
}

View File

@ -0,0 +1,11 @@
package org.jclouds.openstack.swift.binders;
import org.jclouds.blobstore.binders.BindMapToHeadersWithPrefix;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
public class BindMapToHeadersWithContainerMetadataPrefix extends BindMapToHeadersWithPrefix {
public BindMapToHeadersWithContainerMetadataPrefix() {
super(SwiftHeaders.CONTAINER_METADATA_PREFIX);
}
}

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.objectstorage.functions;
package org.jclouds.openstack.swift.functions;
import static com.google.common.base.Preconditions.checkArgument;

View File

@ -32,6 +32,8 @@ import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.logging.Logger;
import org.jclouds.openstack.swift.CopyObjectException;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
import org.jclouds.rest.AuthorizationException;
/**
@ -61,10 +63,21 @@ public class ParseSwiftErrorFromHttpResponse implements HttpErrorHandler {
exception = new AuthorizationException(exception.getMessage(), exception);
break;
case 404:
if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
String sourcePath = command.getCurrentRequest().getFirstHeaderOrNull(SwiftHeaders.OBJECT_COPY_FROM);
Exception oldException = exception;
if (sourcePath != null) {
String path = command.getCurrentRequest().getEndpoint().getPath();
int startOfDestinationPath = path.lastIndexOf("/", path.lastIndexOf("/")-1);
String destinationPath = path.substring(startOfDestinationPath);
exception = new CopyObjectException(sourcePath, destinationPath, message);
exception.initCause(oldException);
}
else if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
String path = command.getCurrentRequest().getEndpoint().getPath();
Matcher matcher = CONTAINER_PATH.matcher(path);
Exception oldException = exception;
if (matcher.find()) {
exception = new ContainerNotFoundException(matcher.group(1), message);
exception.initCause(oldException);

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.objectstorage.options;
package org.jclouds.openstack.swift.options;
import java.util.Map;
import java.util.Map.Entry;
@ -61,17 +61,11 @@ public class CreateContainerOptions extends BaseHttpRequestOptions {
public static class Builder {
/**
* @see org.jclouds.hpcloud.objectstorage.options.CreateContainerOptions#withPublicAccess
*/
public static CreateContainerOptions withPublicAccess() {
CreateContainerOptions options = new CreateContainerOptions();
return options.withPublicAccess();
}
/**
* @see org.jclouds.hpcloud.objectstorage.options.CreateContainerOptions#withMetadata(Multimap<String, String>)
*/
public static CreateContainerOptions withMetadata(Map<String, String> metadata) {
CreateContainerOptions options = new CreateContainerOptions();
return (CreateContainerOptions) options.withMetadata(metadata);

View File

@ -29,7 +29,9 @@ public interface SwiftHeaders {
public static final String CONTAINER_BYTES_USED = "X-Container-Bytes-Used";
public static final String CONTAINER_OBJECT_COUNT = "X-Container-Object-Count";
public static final String CONTAINER_METADATA_PREFIX = "X-Container-Meta-";
public static final String CONTAINER_DELETE_METADATA_PREFIX = "X-Remove-Container-Meta-";
public static final String USER_METADATA_PREFIX = "X-Object-Meta-";
public static final String OBJECT_COPY_FROM = "X-Copy-From";
public static final String CONTAINER_READ = "X-Container-Read";
public static final String CONTAINER_WRITE = "X-Container-Write";

View File

@ -20,8 +20,10 @@ package org.jclouds.openstack.swift;
import static org.jclouds.openstack.swift.options.ListContainerOptions.Builder.underPath;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@ -274,6 +276,64 @@ public abstract class CommonSwiftClientLiveTest<C extends CommonSwiftClient> ext
}
}
@Test
public void testCopyObjectOperations() throws Exception {
String sourceContainer = getContainerName();
String sourceObject = "original.txt";
String sourcePath = "/" + sourceContainer + "/" + sourceObject;
String badSource = "badsource";
String destinationContainer = getContainerName();
String destinationObject = "copy.txt";
String destinationPath = "/" + destinationContainer + "/" + destinationObject;
String badDestination = "baddestination";
String data = "Hello World";
SwiftObject sourceSwiftObject = newSwiftObject(data, sourceObject);
getApi().putObject(sourceContainer, sourceSwiftObject);
// test that not giving a destination name *doesn't* copy source name to the destination container with
// the source name but copy still returns success :(
assertTrue(getApi().copyObject(sourceContainer, sourceObject, destinationContainer, ""));
assertTrue(!getApi().objectExists(destinationContainer, sourceObject));
// test copy works
assertTrue(getApi().copyObject(sourceContainer, sourceObject, destinationContainer, destinationObject));
assertTrue(getApi().objectExists(destinationContainer, destinationObject));
SwiftObject destinationSwiftObject = getApi().getObject(destinationContainer, destinationObject);
assertEquals(Strings2.toString(destinationSwiftObject.getPayload()), data);
// test exception thrown on bad destination container
try {
assertFalse(getApi().copyObject(sourceContainer, sourceObject, badDestination, destinationObject));
fail("Expected CopyObjectException");
}
catch (CopyObjectException e) {
assertEquals(e.getSourcePath(), sourcePath);
assertEquals(e.getDestinationPath(), "/" + badDestination + "/" + destinationObject);
}
// test exception thrown on bad source container
try {
assertFalse(getApi().copyObject(badSource, sourceObject, destinationContainer, destinationObject));
fail("Expected CopyObjectException");
}
catch (CopyObjectException e) {
assertEquals(e.getSourcePath(), "/" + badSource + "/" + sourceObject);
assertEquals(e.getDestinationPath(), destinationPath);
}
// test exception thrown on bad source name
try {
assertFalse(getApi().copyObject(sourceContainer, badSource, destinationContainer, destinationObject));
fail("Expected CopyObjectException");
}
catch (CopyObjectException e) {
assertEquals(e.getSourcePath(), "/" + sourceContainer + "/" + badSource);
assertEquals(e.getDestinationPath(), destinationPath);
}
}
protected void testGetObjectContentType(SwiftObject getBlob) {
String contentType = getBlob.getPayload().getContentMetadata().getContentType();
assert contentType.startsWith("text/plain") || "application/x-www-form-urlencoded".equals(contentType): contentType;

View File

@ -23,9 +23,14 @@ import static org.testng.Assert.assertTrue;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.openstack.swift.internal.BaseSwiftExpectTest;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
*
* @author Adrian Cole
@ -33,7 +38,8 @@ import org.testng.annotations.Test;
@Test(testName = "SwiftClientExpectTest")
public class SwiftClientExpectTest extends BaseSwiftExpectTest<SwiftClient> {
public void testContainerExistsWhenResponseIs2xxReturnsTrue() throws Exception {
@Test
public void testContainerExistsWhenResponseIs2xxReturnsTrue() {
HttpRequest headContainer = HttpRequest.builder()
.method("HEAD")
.endpoint(swiftEndpointWithHostReplaced + "/foo")
@ -47,7 +53,8 @@ public class SwiftClientExpectTest extends BaseSwiftExpectTest<SwiftClient> {
assertTrue(clientWhenContainerExists.containerExists("foo"));
}
public void testContainerExistsWhenResponseIs404ReturnsFalse() throws Exception {
@Test
public void testContainerExistsWhenResponseIs404ReturnsFalse() {
HttpRequest headContainer = HttpRequest.builder()
.method("HEAD")
.endpoint(swiftEndpointWithHostReplaced + "/foo")
@ -59,7 +66,150 @@ public class SwiftClientExpectTest extends BaseSwiftExpectTest<SwiftClient> {
authResponse, headContainer, headContainerResponse);
assertFalse(clientWhenContainerDoesntExist.containerExists("foo"));
}
@Test
public void testSetContainerMetadataWhenResponseIs2xxReturnsTrue() {
HttpRequest setContainerMetadataRequest = HttpRequest.builder()
.method("POST")
.endpoint(swiftEndpointWithHostReplaced + "/foo")
.addHeader(SwiftHeaders.CONTAINER_METADATA_PREFIX + "key", "value")
.addHeader("X-Auth-Token", authToken).build();
HttpResponse setContainerMetadataResponse = HttpResponse.builder().statusCode(204).build();
SwiftClient clientSetContainerMetadata = requestsSendResponses(authRequest,
authResponse, setContainerMetadataRequest, setContainerMetadataResponse);
assertTrue(clientSetContainerMetadata.setContainerMetadata("foo", ImmutableMap.<String, String> of("key", "value")));
}
@Test(expectedExceptions = HttpResponseException.class)
public void testSetContainerMetadataWhenResponseIs400ThrowsException() {
HttpRequest setContainerMetadataRequest = HttpRequest.builder()
.method("POST")
.endpoint(swiftEndpointWithHostReplaced + "/foo")
.addHeader(SwiftHeaders.CONTAINER_METADATA_PREFIX, "value")
.addHeader("X-Auth-Token", authToken).build();
HttpResponse setContainerMetadataResponse = HttpResponse.builder()
.statusCode(400)
.message("Metadata name cannot be empty").build();
SwiftClient clientSetContainerMetadata = requestsSendResponses(authRequest,
authResponse, setContainerMetadataRequest, setContainerMetadataResponse);
clientSetContainerMetadata.setContainerMetadata("foo", ImmutableMap.<String, String> of("", "value"));
}
@Test
public void testSetContainerMetadataWhenResponseIs404ReturnsFalse() {
HttpRequest setContainerMetadataRequest = HttpRequest.builder()
.method("POST")
.endpoint(swiftEndpointWithHostReplaced + "/foo")
.addHeader(SwiftHeaders.CONTAINER_METADATA_PREFIX + "key", "value")
.addHeader("X-Auth-Token", authToken).build();
HttpResponse setContainerMetadataResponse = HttpResponse.builder()
.statusCode(404).build();
SwiftClient clientSetContainerMetadata = requestsSendResponses(authRequest,
authResponse, setContainerMetadataRequest, setContainerMetadataResponse);
assertFalse(clientSetContainerMetadata.setContainerMetadata("foo", ImmutableMap.<String, String> of("key", "value")));
}
@Test
public void testDeleteContainerMetadataWhenResponseIs2xxReturnsTrue() {
HttpRequest deleteContainerMetadataRequest = HttpRequest.builder()
.method("POST")
.endpoint(swiftEndpointWithHostReplaced + "/foo")
.addHeader(SwiftHeaders.CONTAINER_DELETE_METADATA_PREFIX + "bar", "")
.addHeader("X-Auth-Token", authToken).build();
HttpResponse deleteContainerMetadataResponse = HttpResponse.builder().statusCode(204).build();
SwiftClient clientDeleteContainerMetadata = requestsSendResponses(authRequest,
authResponse, deleteContainerMetadataRequest, deleteContainerMetadataResponse);
assertTrue(clientDeleteContainerMetadata.deleteContainerMetadata("foo", ImmutableList.<String> of("bar")));
}
@Test
public void testDeleteContainerMetadataEmptyWhenResponseIs2xxReturnsTrue() {
HttpRequest deleteContainerMetadataRequest = HttpRequest.builder()
.method("POST")
.endpoint(swiftEndpointWithHostReplaced + "/foo")
.addHeader(SwiftHeaders.CONTAINER_DELETE_METADATA_PREFIX, "")
.addHeader("X-Auth-Token", authToken).build();
HttpResponse deleteContainerMetadataResponse = HttpResponse.builder().statusCode(204).build();
SwiftClient clientDeleteContainerMetadata = requestsSendResponses(authRequest,
authResponse, deleteContainerMetadataRequest, deleteContainerMetadataResponse);
assertTrue(clientDeleteContainerMetadata.deleteContainerMetadata("foo", ImmutableList.<String> of("")));
}
@Test
public void testDeleteContainerMetadataWhenResponseIs404ReturnsFalse() {
HttpRequest deleteContainerMetadataRequest = HttpRequest.builder()
.method("POST")
.endpoint(swiftEndpointWithHostReplaced + "/foo")
.addHeader(SwiftHeaders.CONTAINER_DELETE_METADATA_PREFIX + "bar", "")
.addHeader("X-Auth-Token", authToken).build();
HttpResponse deleteContainerMetadataResponse = HttpResponse.builder().statusCode(404).build();
SwiftClient clientDeleteContainerMetadata = requestsSendResponses(authRequest,
authResponse, deleteContainerMetadataRequest, deleteContainerMetadataResponse);
assertFalse(clientDeleteContainerMetadata.deleteContainerMetadata("foo", ImmutableList.<String> of("bar")));
}
@Test
public void testCopyObjectWhenResponseIs2xxReturnsTrue() {
String sourceContainer = "bar";
String sourceObject = "foo.txt";
String sourcePath = "/" + sourceContainer + "/" + sourceObject;
String destinationContainer = "foo";
String destinationObject = "bar.txt";
String destinationPath = "/" + destinationContainer + "/" + destinationObject;
HttpRequest copyObjectRequest = HttpRequest.builder()
.method("PUT")
.endpoint(swiftEndpointWithHostReplaced + destinationPath)
.addHeader(SwiftHeaders.OBJECT_COPY_FROM, sourcePath)
.addHeader("X-Auth-Token", authToken).build();
HttpResponse copyObjectResponse = HttpResponse.builder().statusCode(201).build();
SwiftClient clientCopyObject = requestsSendResponses(authRequest,
authResponse, copyObjectRequest, copyObjectResponse);
assertTrue(clientCopyObject.copyObject(sourceContainer, sourceObject, destinationContainer, destinationObject));
}
@Test(expectedExceptions = CopyObjectException.class)
public void testCopyObjectWhenResponseIs404ThrowsException() {
String sourceContainer = "bar";
String sourceObject = "foo.txt";
String sourcePath = "/" + sourceContainer + "/" + sourceObject;
String destinationContainer = "foo";
String destinationObject = "bar.txt";
String destinationPath = "/" + destinationContainer + "/" + destinationObject;
HttpRequest copyObjectRequest = HttpRequest.builder()
.method("PUT")
.endpoint(swiftEndpointWithHostReplaced + destinationPath)
.addHeader(SwiftHeaders.OBJECT_COPY_FROM, sourcePath)
.addHeader("X-Auth-Token", authToken).build();
HttpResponse copyObjectResponse = HttpResponse.builder().statusCode(404).build();
SwiftClient clientCopyObject = requestsSendResponses(authRequest,
authResponse, copyObjectRequest, copyObjectResponse);
assertTrue(clientCopyObject.copyObject(sourceContainer, sourceObject, destinationContainer, destinationObject));
}
}

View File

@ -0,0 +1,77 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.openstack.swift.binders;
import static org.testng.Assert.assertEquals;
import java.util.List;
import org.jclouds.http.HttpRequest;
import org.jclouds.openstack.swift.CommonSwiftClientTest;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* Tests behavior of {@code BindIterableToHeadersWithContainerDeleteMetadataPrefix}
*
* @author Everett Toews
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "BindIterableToHeadersWithContainerDeleteMetadataPrefixTest")
public class BindIterableToHeadersWithContainerDeleteMetadataPrefixTest extends CommonSwiftClientTest {
@Test
public void testMetadataKeysBind() {
List<String> metadataKeys = ImmutableList.of("foo", "bar");
HttpRequest request = HttpRequest.builder().method("PUT").endpoint("http://localhost").build();
BindIterableToHeadersWithContainerDeleteMetadataPrefix binder =
injector.getInstance(BindIterableToHeadersWithContainerDeleteMetadataPrefix.class);
HttpRequest actualRequest = binder.bindToRequest(request, metadataKeys);
HttpRequest expectedRequest = HttpRequest.builder()
.method("PUT")
.endpoint("http://localhost")
.addHeader(SwiftHeaders.CONTAINER_DELETE_METADATA_PREFIX + "foo", "")
.addHeader(SwiftHeaders.CONTAINER_DELETE_METADATA_PREFIX + "bar", "")
.build();
assertEquals(actualRequest, expectedRequest);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNullListIsBad() {
HttpRequest request = HttpRequest.builder().method("PUT").endpoint("http://localhost").build();
BindIterableToHeadersWithContainerDeleteMetadataPrefix binder =
injector.getInstance(BindIterableToHeadersWithContainerDeleteMetadataPrefix.class);
binder.bindToRequest(request, null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNullRequestIsBad() {
List<String> metadataKeys = ImmutableList.of("foo", "bar");
BindIterableToHeadersWithContainerDeleteMetadataPrefix binder =
injector.getInstance(BindIterableToHeadersWithContainerDeleteMetadataPrefix.class);
binder.bindToRequest(null, metadataKeys);
}
}

View File

@ -0,0 +1,77 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.openstack.swift.binders;
import static org.testng.Assert.assertEquals;
import java.util.List;
import org.jclouds.http.HttpRequest;
import org.jclouds.openstack.swift.CommonSwiftClientTest;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* Tests behavior of {@code BindListToHeadersWithContainerDeleteMetadataPrefix}
*
* @author Everett Toews
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "BindListToHeadersWithContainerDeleteMetadataPrefixTest")
public class BindMapToHeadersWithContainerMetadataPrefixTest extends CommonSwiftClientTest {
@Test
public void testMetadataKeysBind() {
List<String> metadataKeys = ImmutableList.of("foo", "bar");
HttpRequest request = HttpRequest.builder().method("PUT").endpoint("http://localhost").build();
BindIterableToHeadersWithContainerDeleteMetadataPrefix binder =
injector.getInstance(BindIterableToHeadersWithContainerDeleteMetadataPrefix.class);
HttpRequest actualRequest = binder.bindToRequest(request, metadataKeys);
HttpRequest expectedRequest = HttpRequest.builder()
.method("PUT")
.endpoint("http://localhost")
.addHeader(SwiftHeaders.CONTAINER_DELETE_METADATA_PREFIX + "foo", "")
.addHeader(SwiftHeaders.CONTAINER_DELETE_METADATA_PREFIX + "bar", "")
.build();
assertEquals(actualRequest, expectedRequest);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNullListIsBad() {
HttpRequest request = HttpRequest.builder().method("PUT").endpoint("http://localhost").build();
BindIterableToHeadersWithContainerDeleteMetadataPrefix binder =
injector.getInstance(BindIterableToHeadersWithContainerDeleteMetadataPrefix.class);
binder.bindToRequest(request, null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNullRequestIsBad() {
List<String> metadataKeys = ImmutableList.of("foo", "bar");
BindIterableToHeadersWithContainerDeleteMetadataPrefix binder =
injector.getInstance(BindIterableToHeadersWithContainerDeleteMetadataPrefix.class);
binder.bindToRequest(null, metadataKeys);
}
}

View File

@ -18,15 +18,28 @@
*/
package org.jclouds.openstack.swift.blobstore.integration;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.Properties;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
import org.jclouds.openstack.swift.CommonSwiftClient;
import org.jclouds.openstack.swift.domain.ContainerMetadata;
import org.jclouds.openstack.swift.options.CreateContainerOptions;
import org.jclouds.rest.RestContext;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
* @author James Murty
* @author Adrian Cole
* @author Everett Toews
*/
@Test(groups = "live")
public class SwiftContainerIntegrationLiveTest extends BaseContainerIntegrationTest {
@ -40,4 +53,53 @@ public class SwiftContainerIntegrationLiveTest extends BaseContainerIntegrationT
public SwiftContainerIntegrationLiveTest() {
provider = System.getProperty("test.swift.provider", "swift");
}
@Test(groups = "live")
public void testSetGetContainerMetadata() throws InterruptedException {
BlobStore blobStore = view.getBlobStore();
RestContext<CommonSwiftClient, CommonSwiftAsyncClient> swift = blobStore.getContext().unwrap();
String containerName = getContainerName();
assertTrue(swift.getApi().createContainer(containerName));
ImmutableMap<String, String> metadata = ImmutableMap.<String, String> of(
"key1", "value1",
"key2", "value2");
assertTrue(swift.getApi().setContainerMetadata(containerName, metadata));
ContainerMetadata containerMetadata = swift.getApi().getContainerMetadata(containerName);
assertEquals(containerMetadata.getMetadata().get("key1"), "value1");
assertEquals(containerMetadata.getMetadata().get("key2"), "value2");
}
@Test(groups = "live")
public void testCreateDeleteContainerMetadata() throws InterruptedException {
BlobStore blobStore = view.getBlobStore();
RestContext<CommonSwiftClient, CommonSwiftAsyncClient> swift = blobStore.getContext().unwrap();
String containerName = getContainerName();
CreateContainerOptions options = CreateContainerOptions.Builder
.withPublicAccess()
.withMetadata(ImmutableMap.<String, String> of(
"key1", "value1",
"key2", "value2",
"key3", "value3"));
assertTrue(swift.getApi().createContainer(containerName, options));
ContainerMetadata containerMetadata = swift.getApi().getContainerMetadata(containerName);
assertEquals(containerMetadata.getMetadata().size(), 3);
assertEquals(containerMetadata.getMetadata().get("key1"), "value1");
assertEquals(containerMetadata.getMetadata().get("key2"), "value2");
assertEquals(containerMetadata.getMetadata().get("key3"), "value3");
assertTrue(swift.getApi().deleteContainerMetadata(containerName, ImmutableList.<String> of("key2","key3")));
containerMetadata = swift.getApi().getContainerMetadata(containerName);
assertEquals(containerMetadata.getMetadata().size(), 1);
assertEquals(containerMetadata.getMetadata().get("key1"), "value1");
}
}

View File

@ -46,5 +46,4 @@ public class SwiftContainerLiveTest extends BaseContainerLiveTest {
public void testPublicAccess() throws MalformedURLException, InterruptedException, IOException {
super.testPublicAccess();
}
}

View File

@ -0,0 +1,77 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.openstack.swift.functions;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import org.jclouds.http.HttpResponse;
import org.jclouds.openstack.swift.domain.ContainerMetadata;
import org.jclouds.openstack.swift.functions.ParseContainerMetadataFromHeaders;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* Tests behavior of {@code ParseContainerMetadataFromHeaders}
*
* @author Everett Toews
*/
@Test(groups = "unit")
public class ParseContainerMetadataFromHeadersTest {
Injector i = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
}
});
public void testParseContainerMetadataHeaders() {
ParseContainerMetadataFromHeaders parser = i.getInstance(ParseContainerMetadataFromHeaders.class);
GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(ImmutableList.<Object> of("container", "key")).atLeastOnce();
expect(request.getEndpoint()).andReturn(URI.create("http://localhost/test")).atLeastOnce();
replay(request);
parser.setContext(request);
HttpResponse response = HttpResponse.builder().statusCode(204).message("No Content").payload("")
.addHeader(SwiftHeaders.CONTAINER_BYTES_USED, "42")
.addHeader(SwiftHeaders.CONTAINER_OBJECT_COUNT, "1")
.addHeader(SwiftHeaders.CONTAINER_METADATA_PREFIX + "label1", "test1")
.addHeader(SwiftHeaders.CONTAINER_METADATA_PREFIX + "label2", "test2").build();
response.getPayload().getContentMetadata().setContentType("text/plain");
ContainerMetadata containerMetadata = parser.apply(response);
assertEquals(containerMetadata.getBytes(), 42);
assertEquals(containerMetadata.getCount(), 1);
assertEquals(containerMetadata.getMetadata().get("label1"), "test1");
assertEquals(containerMetadata.getMetadata().get("label2"), "test2");
}
}

View File

@ -31,9 +31,14 @@ import org.jclouds.blobstore.ContainerNotFoundException;
import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequest.Builder;
import org.jclouds.http.HttpResponse;
import org.jclouds.openstack.swift.CopyObjectException;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
import org.testng.annotations.Test;
import com.google.common.base.Strings;
/**
*
* @author Adrian Cole
@ -41,6 +46,13 @@ import org.testng.annotations.Test;
@Test(groups = { "unit" })
public class ParseSwiftErrorFromHttpResponseTest {
@Test
public void test404SetsCopyObjectException() {
assertCodeMakes("HEAD",
URI.create("http://host/v1/MossoCloudFS_7064cdb1d49d4dcba3c899ac33e8409d/adriancole-blobstore1/key"), 404,
"Not Found", "text/plain", "", "/bad/source/path", CopyObjectException.class);
}
@Test
public void test404SetsKeyNotFoundExceptionMosso() {
assertCodeMakes("HEAD",
@ -76,24 +88,34 @@ public class ParseSwiftErrorFromHttpResponseTest {
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
String content, Class<? extends Exception> expected) {
ParseSwiftErrorFromHttpResponse function = new ParseSwiftErrorFromHttpResponse();
HttpCommand command = createMock(HttpCommand.class);
HttpRequest request = HttpRequest.builder().method(method).endpoint(uri).build();
HttpResponse response = HttpResponse.builder().statusCode(statusCode).message(message).payload(content).build();
response.getPayload().getContentMetadata().setContentType(contentType);
expect(command.getCurrentRequest()).andReturn(request).atLeastOnce();
command.setException(classEq(expected));
replay(command);
function.handleError(command, response);
verify(command);
assertCodeMakes(method, uri, statusCode, message, contentType, content, "", expected);
}
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
String content, String copyObjectSourcePath, Class<? extends Exception> expected) {
ParseSwiftErrorFromHttpResponse function = new ParseSwiftErrorFromHttpResponse();
HttpCommand command = createMock(HttpCommand.class);
Builder<?> requestBuilder = HttpRequest.builder().method(method).endpoint(uri);
if (!Strings.isNullOrEmpty(copyObjectSourcePath)) {
requestBuilder.addHeader(SwiftHeaders.OBJECT_COPY_FROM, copyObjectSourcePath);
}
HttpRequest request = requestBuilder.build();
HttpResponse response = HttpResponse.builder().statusCode(statusCode).message(message).payload(content).build();
response.getPayload().getContentMetadata().setContentType(contentType);
expect(command.getCurrentRequest()).andReturn(request).atLeastOnce();
command.setException(classEq(expected));
replay(command);
function.handleError(command, response);
verify(command);
}
public static Exception classEq(final Class<? extends Exception> in) {
reportMatcher(new IArgumentMatcher() {

View File

@ -53,6 +53,7 @@ import org.jclouds.openstack.swift.domain.ContainerMetadata;
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
import org.jclouds.openstack.swift.domain.ObjectInfo;
import org.jclouds.openstack.swift.domain.SwiftObject;
import org.jclouds.openstack.swift.options.CreateContainerOptions;
import com.google.common.base.Function;
import com.google.common.base.Throwables;
@ -160,12 +161,33 @@ public class StubSwiftAsyncClient implements CommonSwiftAsyncClient {
})));
}
@Override
public ListenableFuture<ContainerMetadata> getContainerMetadata(String container) {
throw new UnsupportedOperationException();
}
public ListenableFuture<Boolean> setContainerMetadata(String container, Map<String, String> containerMetadata) {
throw new UnsupportedOperationException();
}
public ListenableFuture<Boolean> deleteContainerMetadata(String container, Iterable<String> metadataKeys) {
throw new UnsupportedOperationException();
}
public ListenableFuture<Boolean> createContainer(String container, CreateContainerOptions... options) {
throw new UnsupportedOperationException();
}
public ListenableFuture<PageSet<ObjectInfo>> listObjects(String container,
org.jclouds.openstack.swift.options.ListContainerOptions... optionsList) {
ListContainerOptions options = container2ContainerListOptions.apply(optionsList);
return Futures.compose(blobStore.list(container, options), resource2ObjectList, service);
}
public ListenableFuture<Boolean> copyObject(String sourceContainer, String sourceObject, String destinationContainer, String destinationObject) {
throw new UnsupportedOperationException();
}
public ListenableFuture<String> putObject(String container, SwiftObject object) {
return blobStore.putBlob(container, object2Blob.apply(object));
}
@ -195,5 +217,4 @@ public class StubSwiftAsyncClient implements CommonSwiftAsyncClient {
public ListenableFuture<Boolean> objectExists(String bucketName, String key) {
return blobStore.blobExists(bucketName, key);
}
}

View File

@ -16,10 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.hpcloud.objectstorage.options;
package org.jclouds.openstack.swift.options;
import static org.testng.Assert.assertEquals;
import org.jclouds.openstack.swift.options.CreateContainerOptions;
import org.jclouds.openstack.swift.reference.SwiftHeaders;
import org.testng.annotations.Test;

View File

@ -23,16 +23,11 @@ import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.blobstore.functions.ReturnNullOnContainerNotFound;
import org.jclouds.hpcloud.objectstorage.extensions.HPCloudCDNAsyncClient;
import org.jclouds.hpcloud.objectstorage.functions.ParseContainerMetadataFromHeaders;
import org.jclouds.hpcloud.objectstorage.options.CreateContainerOptions;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
import org.jclouds.openstack.swift.Storage;
@ -44,10 +39,8 @@ import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SkipEncoding;
import com.google.common.annotations.Beta;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.ListenableFuture;
@ -69,24 +62,6 @@ import com.google.common.util.concurrent.ListenableFuture;
@Endpoint(Storage.class)
public interface HPCloudObjectStorageAsyncClient extends CommonSwiftAsyncClient {
/**
* @see HPCloudObjectStorageClient#getCDNMetadata(String)
*/
@Beta
@HEAD
@ResponseParser(ParseContainerMetadataFromHeaders.class)
@ExceptionParser(ReturnNullOnContainerNotFound.class)
@Path("/{container}")
ListenableFuture<ContainerMetadata> getContainerMetadata(@PathParam("container") String container);
/**
* @see HPCloudObjectStorageClient#createContainer
*/
@PUT
@Path("/{container}")
ListenableFuture<Boolean> createContainer(@PathParam("container") String container,
CreateContainerOptions... options);
/**
* @see org.jclouds.openstack.swift.CommonSwiftClient#listContainers
*/

View File

@ -22,9 +22,7 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.hpcloud.objectstorage.extensions.HPCloudCDNClient;
import org.jclouds.hpcloud.objectstorage.options.CreateContainerOptions;
import org.jclouds.openstack.swift.CommonSwiftClient;
import org.jclouds.openstack.swift.domain.ContainerMetadata;
import org.jclouds.rest.annotations.Delegate;
import com.google.common.base.Optional;
@ -46,10 +44,6 @@ import com.google.common.util.concurrent.ListenableFuture;
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
public interface HPCloudObjectStorageClient extends CommonSwiftClient {
boolean createContainer(String container, CreateContainerOptions... options);
ContainerMetadata getContainerMetadata(String container);
/**
* Provides synchronous access to CDN features.
*/