mirror of https://github.com/apache/jclouds.git
Issue 75: Added GET with options for object
git-svn-id: http://jclouds.googlecode.com/svn/trunk@1820 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
3c0547c7df
commit
427ccfa963
|
@ -66,7 +66,7 @@ public class GetOptions extends BaseHttpRequestOptions {
|
|||
Multimap<String, String> headers = super.buildRequestHeaders();
|
||||
String range = getRange();
|
||||
if (range != null)
|
||||
headers.put("Content-Range", this.getRange());
|
||||
headers.put("Range", this.getRange());
|
||||
return headers;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ import javax.ws.rs.Path;
|
|||
import javax.ws.rs.PathParam;
|
||||
|
||||
import org.jclouds.http.functions.ParseETagHeader;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.rackspace.cloudfiles.binders.CFObjectBinder;
|
||||
import org.jclouds.rackspace.cloudfiles.binders.UserMetadataBinder;
|
||||
import org.jclouds.rackspace.cloudfiles.domain.AccountMetadata;
|
||||
|
@ -86,13 +87,7 @@ public interface CloudFilesConnection {
|
|||
@ResponseParser(ParseContainerListFromGsonResponse.class)
|
||||
@Query(key = "format", value = "json")
|
||||
@Path("/")
|
||||
List<ContainerMetadata> listOwnedContainers();
|
||||
|
||||
@GET
|
||||
@ResponseParser(ParseContainerListFromGsonResponse.class)
|
||||
@Query(key = "format", value = "json")
|
||||
@Path("/")
|
||||
List<ContainerMetadata> listOwnedContainers(ListContainerOptions options);
|
||||
List<ContainerMetadata> listOwnedContainers(ListContainerOptions ... options);
|
||||
|
||||
@PUT
|
||||
@Path("{container}")
|
||||
|
@ -124,9 +119,7 @@ public interface CloudFilesConnection {
|
|||
@ExceptionParser(ReturnS3ObjectNotFoundOn404.class)
|
||||
@Path("{container}/{key}")
|
||||
Future<CFObject> getObject(@PathParam("container") String container,
|
||||
@PathParam("key") String key);
|
||||
|
||||
// TODO: GET object with options
|
||||
@PathParam("key") String key, GetOptions ... options);
|
||||
|
||||
@POST
|
||||
@ResponseParser(ReturnTrueOn202FalseOtherwise.class)
|
||||
|
|
|
@ -118,9 +118,10 @@ public class ParseObjectMetadataFromHeaders implements Function<HttpResponse, CF
|
|||
private void addUserMetadataTo(HttpResponse from, Metadata metadata) {
|
||||
for (Entry<String, String> header : from.getHeaders().entries()) {
|
||||
if (header.getKey() != null
|
||||
&& header.getKey().startsWith(CloudFilesHeaders.USER_METADATA_PREFIX))
|
||||
&& header.getKey().toLowerCase().startsWith(
|
||||
CloudFilesHeaders.USER_METADATA_PREFIX.toLowerCase()))
|
||||
{
|
||||
metadata.getUserMetadata().put(header.getKey(), header.getValue());
|
||||
metadata.getUserMetadata().put(header.getKey().toLowerCase(), header.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import org.apache.commons.io.IOUtils;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.rackspace.cloudfiles.domain.AccountMetadata;
|
||||
import org.jclouds.rackspace.cloudfiles.domain.CFObject;
|
||||
|
@ -78,13 +79,30 @@ public class CloudFilesConnectionLiveTest {
|
|||
long initialContainerCount = response.size();
|
||||
assertTrue(initialContainerCount >= 0);
|
||||
|
||||
String[] containerNames = new String[] { bucketPrefix + ".testListOwnedContainers1",
|
||||
// Create test containers
|
||||
String[] containerNames = new String[] {
|
||||
bucketPrefix + ".testListOwnedContainers1",
|
||||
bucketPrefix + ".testListOwnedContainers2" };
|
||||
assertTrue(connection.putContainer(containerNames[0]));
|
||||
assertTrue(connection.putContainer(containerNames[1]));
|
||||
|
||||
// Test default listing
|
||||
response = connection.listOwnedContainers();
|
||||
assertEquals(response.size(), initialContainerCount + 2);
|
||||
|
||||
// Test listing with options
|
||||
response = connection.listOwnedContainers(ListContainerOptions.Builder
|
||||
.afterMarker(containerNames[0].substring(0, containerNames[0].length() - 1))
|
||||
.maxResults(1));
|
||||
assertEquals(response.size(), 1);
|
||||
assertEquals(response.get(0).getName(), containerNames[0]);
|
||||
|
||||
response = connection.listOwnedContainers(ListContainerOptions.Builder
|
||||
.afterMarker(containerNames[0]).maxResults(1));
|
||||
assertEquals(response.size(), 1);
|
||||
assertEquals(response.get(0).getName(), containerNames[1]);
|
||||
|
||||
// Cleanup and test containers have been removed
|
||||
assertTrue(connection.deleteContainerIfEmpty(containerNames[0]));
|
||||
assertTrue(connection.deleteContainerIfEmpty(containerNames[1]));
|
||||
response = connection.listOwnedContainers();
|
||||
|
@ -160,7 +178,7 @@ public class CloudFilesConnectionLiveTest {
|
|||
object.generateETag();
|
||||
object.getMetadata().setContentType("text/plain");
|
||||
object.getMetadata().getUserMetadata().put(
|
||||
CloudFilesHeaders.USER_METADATA_PREFIX + "metadata", "metadata-value");
|
||||
CloudFilesHeaders.USER_METADATA_PREFIX + "Metadata", "metadata-value");
|
||||
byte[] md5 = connection.putObject(containerName, object).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(HttpUtils.toHexString(md5),
|
||||
HttpUtils.toHexString(object.getMetadata().getETag()));
|
||||
|
@ -178,13 +196,13 @@ public class CloudFilesConnectionLiveTest {
|
|||
assertEquals(metadata.getUserMetadata().entries().size(), 1);
|
||||
// Notice the quirk where CF changes the case of returned metadata names
|
||||
assertEquals(Iterables.getLast(metadata.getUserMetadata().get(
|
||||
CloudFilesHeaders.USER_METADATA_PREFIX + "Metadata")),
|
||||
(CloudFilesHeaders.USER_METADATA_PREFIX + "Metadata").toLowerCase())),
|
||||
"metadata-value");
|
||||
|
||||
// Test POST to update object's metadata
|
||||
Multimap<String, String> userMetadata = HashMultimap.create();
|
||||
userMetadata.put(CloudFilesHeaders.USER_METADATA_PREFIX + "new-metadata-1", "value-1");
|
||||
userMetadata.put(CloudFilesHeaders.USER_METADATA_PREFIX + "new-metadata-2", "value-2");
|
||||
userMetadata.put(CloudFilesHeaders.USER_METADATA_PREFIX + "New-Metadata-1", "value-1");
|
||||
userMetadata.put(CloudFilesHeaders.USER_METADATA_PREFIX + "New-Metadata-2", "value-2");
|
||||
assertTrue(connection.setObjectMetadata(containerName, object.getKey(), userMetadata));
|
||||
|
||||
// Test GET of missing object
|
||||
|
@ -193,18 +211,18 @@ public class CloudFilesConnectionLiveTest {
|
|||
assertEquals(getObject, CFObject.NOT_FOUND);
|
||||
|
||||
// Test GET of object (including updated metadata)
|
||||
getObject = connection.getObject(containerName, object.getKey()).get(10, TimeUnit.SECONDS);
|
||||
getObject = connection.getObject(containerName, object.getKey()).get(120, TimeUnit.SECONDS);
|
||||
assertEquals(IOUtils.toString((InputStream)getObject.getData()), data);
|
||||
assertEquals(getObject.getKey(), object.getKey());
|
||||
assertEquals(getObject.getContentLength(), data.length());
|
||||
assertEquals(getObject.getMetadata().getContentType(), "text/plain");
|
||||
assertEquals(getObject.getMetadata().getETag(), object.getMetadata().getETag());
|
||||
assertEquals(getObject.getMetadata().getUserMetadata().entries().size(), 2);
|
||||
// Notice the quirk where CF changes the case of sreturned metadata names
|
||||
// Notice the quirk where CF changes the case of returned metadata names
|
||||
assertEquals(Iterables.getLast(getObject.getMetadata().getUserMetadata().get(
|
||||
CloudFilesHeaders.USER_METADATA_PREFIX + "New-Metadata-1")), "value-1");
|
||||
(CloudFilesHeaders.USER_METADATA_PREFIX + "New-Metadata-1").toLowerCase())), "value-1");
|
||||
assertEquals(Iterables.getLast(getObject.getMetadata().getUserMetadata().get(
|
||||
CloudFilesHeaders.USER_METADATA_PREFIX + "New-Metadata-2")), "value-2");
|
||||
(CloudFilesHeaders.USER_METADATA_PREFIX + "New-Metadata-2").toLowerCase())), "value-2");
|
||||
|
||||
// Test PUT with invalid ETag (as if object's data was corrupted in transit)
|
||||
String correctEtag = HttpUtils.toHexString(object.getMetadata().getETag());
|
||||
|
@ -222,7 +240,24 @@ public class CloudFilesConnectionLiveTest {
|
|||
object = new CFObject("chunked-object", bais);
|
||||
md5 = connection.putObject(containerName, object).get(10, TimeUnit.SECONDS);
|
||||
assertEquals(HttpUtils.toHexString(md5), correctEtag);
|
||||
// TODO: Get and confirm data
|
||||
|
||||
// Test GET with options
|
||||
// Non-matching ETag
|
||||
try {
|
||||
connection.getObject(containerName, object.getKey(),
|
||||
GetOptions.Builder.ifETagDoesntMatch(md5)).get(120, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
assertEquals(e.getCause().getClass(), HttpResponseException.class);
|
||||
assertEquals(((HttpResponseException) e.getCause()).getResponse().getStatusCode(), 304);
|
||||
}
|
||||
// Matching ETag
|
||||
getObject = connection.getObject(containerName, object.getKey(),
|
||||
GetOptions.Builder.ifETagMatches(md5)).get(120, TimeUnit.SECONDS);
|
||||
assertEquals(getObject.getMetadata().getETag(), md5);
|
||||
// Range
|
||||
getObject = connection.getObject(containerName, object.getKey(),
|
||||
GetOptions.Builder.startAt(8)).get(120, TimeUnit.SECONDS);
|
||||
assertEquals(IOUtils.toString((InputStream)getObject.getData()), data.substring(8));
|
||||
|
||||
assertTrue(connection.deleteObject(containerName, "object"));
|
||||
assertTrue(connection.deleteObject(containerName, "chunked-object"));
|
||||
|
|
Loading…
Reference in New Issue