Issue 73: normalizing names of objects; break metadata into interfaces so that they can be implemented differently

git-svn-id: http://jclouds.googlecode.com/svn/trunk@1986 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-10-19 01:14:25 +00:00
parent ff9abb6884
commit ee6ffff298
75 changed files with 860 additions and 509 deletions

View File

@ -49,7 +49,7 @@ import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
import org.jclouds.aws.s3.xml.ListBucketHandler;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.functions.BlobKey;
import org.jclouds.blobstore.functions.BlobName;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
import org.jclouds.http.functions.ParseETagHeader;
@ -181,7 +181,7 @@ public interface S3BlobStore extends BlobStore<BucketMetadata, ObjectMetadata, S
@ResponseParser(ParseETagHeader.class)
Future<String> putBlob(
@HostPrefixParam String bucketName,
@PathParam("key") @ParamParser(BlobKey.class) @BinderParam(BindS3ObjectToEntity.class) S3Object object);
@PathParam("key") @ParamParser(BlobName.class) @BinderParam(BindS3ObjectToEntity.class) S3Object object);
@PUT
@Path("/")

View File

@ -55,7 +55,7 @@ import org.jclouds.aws.s3.xml.CopyObjectHandler;
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
import org.jclouds.aws.s3.xml.ListBucketHandler;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.functions.BlobKey;
import org.jclouds.blobstore.functions.BlobName;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.functions.ThrowContainerNotFoundOn404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
@ -206,7 +206,7 @@ public interface S3Connection {
@ResponseParser(ParseETagHeader.class)
Future<String> putObject(
@HostPrefixParam String bucketName,
@PathParam("key") @ParamParser(BlobKey.class) @BinderParam(BindS3ObjectToEntity.class) S3Object object,
@PathParam("key") @ParamParser(BlobName.class) @BinderParam(BindS3ObjectToEntity.class) S3Object object,
PutObjectOptions... options);
/**

View File

@ -31,11 +31,11 @@ import javax.inject.Named;
import javax.ws.rs.core.HttpHeaders;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.blobstore.binders.BindBlobToEntity;
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.HttpRequest;
public class BindS3ObjectToEntity extends BindBlobToEntity {
public class BindS3ObjectToEntity extends BindBlobToEntityAndUserMetadataToHeadersWithPrefix {
@Inject
public BindS3ObjectToEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
super(metadataPrefix);

View File

@ -23,7 +23,7 @@
*/
package org.jclouds.aws.s3.domain;
import org.jclouds.blobstore.domain.ContainerMetadata;
import org.jclouds.blobstore.internal.ContainerMetadataImpl;
import org.joda.time.DateTime;
/**
@ -31,7 +31,7 @@ import org.joda.time.DateTime;
*
* @author Adrian Cole
*/
public class BucketMetadata extends ContainerMetadata {
public class BucketMetadata extends ContainerMetadataImpl {
protected DateTime creationDate;
public DateTime getCreationDate() {

View File

@ -25,7 +25,7 @@ package org.jclouds.aws.s3.domain;
import java.io.Serializable;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.internal.BlobMetadataImpl;
/**
* /** Amazon S3 is designed to store objects. Objects are stored in {@link S3BucketListing buckets}
@ -38,7 +38,7 @@ import org.jclouds.blobstore.domain.BlobMetadata;
*
* @see <a href= "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingMetadata.html" />
*/
public class ObjectMetadata extends BlobMetadata implements Serializable {
public class ObjectMetadata extends BlobMetadataImpl implements Serializable {
/** The serialVersionUID */
private static final long serialVersionUID = -4415449798024051115L;
@ -51,7 +51,7 @@ public class ObjectMetadata extends BlobMetadata implements Serializable {
dataDisposition).append(", owner=").append(owner).append(", storageClass=").append(
storageClass).append(", allHeaders=").append(allHeaders).append(", dataEncoding=")
.append(dataEncoding).append(", dataType=").append(dataType).append(", eTag=")
.append(eTag).append(", key=").append(key).append(", lastModified=").append(
.append(eTag).append(", key=").append(name).append(", lastModified=").append(
lastModified).append(", size=").append(size).append(", userMetadata=")
.append(userMetadata).append("]");
return builder.toString();
@ -186,7 +186,7 @@ public class ObjectMetadata extends BlobMetadata implements Serializable {
}
public int compareTo(ObjectMetadata o) {
return (this == o) ? 0 : getKey().compareTo(o.getKey());
return (this == o) ? 0 : getName().compareTo(o.getName());
}
public void setContentEncoding(String dataEncoding) {

View File

@ -25,7 +25,7 @@ package org.jclouds.aws.s3.domain;
import javax.inject.Inject;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.internal.BlobImpl;
/**
* Amazon S3 is designed to store objects. Objects are stored in {@link S3Bucket buckets} and
@ -37,7 +37,7 @@ import org.jclouds.blobstore.domain.Blob;
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?UsingObjects.html"
* />
*/
public class S3Object extends Blob<ObjectMetadata> {
public class S3Object extends BlobImpl<ObjectMetadata> {
public S3Object(ObjectMetadata metadata, Object data) {
super(metadata, data);

View File

@ -121,7 +121,7 @@ public class StubS3Connection extends StubBlobStore<BucketMetadata, ObjectMetada
ObjectMetadata lastMarkerMetadata = Iterables.find(contents,
new Predicate<ObjectMetadata>() {
public boolean apply(ObjectMetadata metadata) {
return metadata.getKey().equals(finalMarker);
return metadata.getName().equals(finalMarker);
}
});
contents = contents.tailSet(lastMarkerMetadata);
@ -133,7 +133,7 @@ public class StubS3Connection extends StubBlobStore<BucketMetadata, ObjectMetada
contents = Sets.newTreeSet(Iterables.filter(contents,
new Predicate<ObjectMetadata>() {
public boolean apply(ObjectMetadata o) {
return (o != null && o.getKey().startsWith(prefix));
return (o != null && o.getName().startsWith(prefix));
}
}));
}
@ -161,7 +161,7 @@ public class StubS3Connection extends StubBlobStore<BucketMetadata, ObjectMetada
if (!contentsSlice.contains(contents.last())) {
// Partial listing
truncated = true;
marker = contentsSlice.last().getKey();
marker = contentsSlice.last().getName();
} else {
marker = null;
}
@ -229,7 +229,7 @@ public class StubS3Connection extends StubBlobStore<BucketMetadata, ObjectMetada
final PutObjectOptions options = (nullableOptions == null) ? new PutObjectOptions()
: nullableOptions;
if (options.getAcl() != null)
keyToAcl.put(bucketName + "/" + object.getKey(), options.getAcl());
keyToAcl.put(bucketName + "/" + object.getName(), options.getAcl());
return super.putBlob(bucketName, object);
}

View File

@ -132,7 +132,7 @@ public class S3ParserTest extends PerformanceTest {
assert container.getBucketName().equals("adrianjbosstest");
assert container.size() == 1;
ObjectMetadata object = container.iterator().next();
assert object.getKey().equals("3366");
assert object.getName().equals("3366");
DateTime expected = new DateTime("2009-03-12T02:00:13.000Z");
assert object.getLastModified().equals(expected) : String.format(
"expected %1$s, but got %1$s", expected, object.getLastModified());

View File

@ -96,7 +96,7 @@ public class Util {
}
public static S3Object convertObjectHead(org.jclouds.aws.s3.domain.ObjectMetadata jcObjectMD) {
S3Object jsObject = new S3Object(jcObjectMD.getKey());
S3Object jsObject = new S3Object(jcObjectMD.getName());
if (jcObjectMD.getOwner() != null) {
jsObject.setOwner(new S3Owner(jcObjectMD.getOwner().getId(), jcObjectMD.getOwner()
.getDisplayName()));

View File

@ -51,9 +51,9 @@ import org.jclouds.azure.storage.domain.BoundedSortedSet;
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
import org.jclouds.blobstore.binders.BindBlobToEntity;
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
import org.jclouds.blobstore.binders.BindMapToHeadersWithPrefix;
import org.jclouds.blobstore.functions.BlobKey;
import org.jclouds.blobstore.functions.BlobName;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
import org.jclouds.http.functions.ParseETagHeader;
@ -271,7 +271,7 @@ public interface AzureBlobConnection {
@Path("{container}/{key}")
@ResponseParser(ParseETagHeader.class)
Future<String> putBlob(@PathParam("container") String container,
@PathParam("key") @ParamParser(BlobKey.class) @BinderParam(BindBlobToEntity.class) Blob object);
@PathParam("key") @ParamParser(BlobName.class) @BinderParam(BindBlobToEntityAndUserMetadataToHeadersWithPrefix.class) Blob object);
/**
* The Get Blob operation reads or downloads a blob from the system, including its metadata and

View File

@ -50,7 +50,7 @@ import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.functions.BlobKey;
import org.jclouds.blobstore.functions.BlobName;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
import org.jclouds.http.functions.ParseETagHeader;
@ -149,7 +149,7 @@ public interface AzureBlobStore extends BlobStore<ContainerMetadata, BlobMetadat
@ResponseParser(ParseETagHeader.class)
Future<String> putBlob(
@PathParam("container") String container,
@PathParam("key") @ParamParser(BlobKey.class) @BinderParam(GenerateMD5AndBindBlobToEntity.class) Blob object);
@PathParam("key") @ParamParser(BlobName.class) @BinderParam(GenerateMD5AndBindBlobToEntity.class) Blob object);
@GET
@ResponseParser(ParseBlobFromHeadersAndHttpContent.class)

View File

@ -34,7 +34,7 @@ import org.jclouds.azure.storage.blob.domain.BlobMetadata;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.HttpRequest;
public class BindBlobToEntity extends org.jclouds.blobstore.binders.BindBlobToEntity {
public class BindBlobToEntity extends org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix {
@Inject
public BindBlobToEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
super(metadataPrefix);

View File

@ -47,7 +47,7 @@ public class GenerateMD5AndBindBlobToEntity extends BindBlobToEntity {
try {
object.generateMD5();
} catch (IOException e) {
throw new RuntimeException("Could not generate MD5 for " + object.getKey(), e);
throw new RuntimeException("Could not generate MD5 for " + object.getName(), e);
}
}
super.bindToRequest(request, entity);

View File

@ -23,10 +23,12 @@
*/
package org.jclouds.azure.storage.blob.domain;
import org.jclouds.blobstore.internal.BlobImpl;
/**
* @author Adrian Cole
*/
public class Blob extends org.jclouds.blobstore.domain.Blob<BlobMetadata> {
public class Blob extends BlobImpl<BlobMetadata> {
public Blob(BlobMetadata metadata, BlobMetadata data) {
super(metadata, data);

View File

@ -27,6 +27,7 @@ import java.net.URI;
import javax.inject.Inject;
import org.jclouds.blobstore.internal.BlobMetadataImpl;
import org.joda.time.DateTime;
import com.google.inject.internal.Nullable;
@ -36,7 +37,7 @@ import com.google.inject.internal.Nullable;
* @author Adrian Cole
*
*/
public class BlobMetadata extends org.jclouds.blobstore.domain.BlobMetadata {
public class BlobMetadata extends BlobMetadataImpl {
/** The serialVersionUID */
private static final long serialVersionUID = 1L;
private URI url;

View File

@ -36,7 +36,7 @@ import com.google.common.collect.Multimap;
* @author Adrian Cole
*
*/
public class ContainerMetadata extends org.jclouds.blobstore.domain.ContainerMetadata {
public class ContainerMetadata extends org.jclouds.blobstore.internal.ContainerMetadataImpl {
private URI url;
private DateTime lastModified;
private byte[] eTag;

View File

@ -53,8 +53,8 @@ public class AddMD5ToListBlobsResponse extends ContainerNameEnumerationResultsHa
ListBlobsResponse response = super.getResult();
checkNotNull(response.getContainerUrl(), "containerUrl");
for (BlobMetadata md : response) {
checkNotNull(md.getKey(), "key");
md.setContentMD5(util.getMD5(response.getContainerUrl(), md.getKey()));
checkNotNull(md.getName(), "key");
md.setContentMD5(util.getMD5(response.getContainerUrl(), md.getName()));
}
return response;
}

View File

@ -251,8 +251,8 @@ public class AzureBlobConnectionLiveTest {
}
// Test HEAD of object
BlobMetadata metadata = connection.getBlobProperties(privateContainer, object.getKey());
// TODO assertEquals(metadata.getKey(), object.getKey());
BlobMetadata metadata = connection.getBlobProperties(privateContainer, object.getName());
// TODO assertEquals(metadata.getName(), object.getName());
// we can't check this while hacking around lack of content-md5, as GET of the first byte will
// show incorrect length 1, the returned size, as opposed to the real length. This is an ok
// tradeoff, as a container list will contain the correct size of the objects in an
@ -271,7 +271,7 @@ public class AzureBlobConnectionLiveTest {
// Multimap<String, String> userMetadata = HashMultimap.create();
// userMetadata.put("New-Metadata-1", "value-1");
// userMetadata.put("New-Metadata-2", "value-2");
// assertTrue(connection.setObjectMetadata(privateContainer, object.getKey(), userMetadata));
// assertTrue(connection.setObjectMetadata(privateContainer, object.getName(), userMetadata));
// Test GET of missing object
try {
@ -281,10 +281,10 @@ public class AzureBlobConnectionLiveTest {
e.printStackTrace();
}
// Test GET of object (including updated metadata)
Blob getBlob = connection.getBlob(privateContainer, object.getKey()).get(120,
Blob getBlob = connection.getBlob(privateContainer, object.getName()).get(120,
TimeUnit.SECONDS);
assertEquals(IOUtils.toString((InputStream) getBlob.getData()), data);
// TODO assertEquals(getBlob.getKey(), object.getKey());
// TODO assertEquals(getBlob.getName(), object.getName());
assertEquals(getBlob.getContentLength(), data.length());
assertEquals(getBlob.getMetadata().getContentType(), "text/plain");
assertEquals(HttpUtils.toHexString(md5), HttpUtils.toHexString(getBlob.getMetadata()
@ -323,7 +323,7 @@ public class AzureBlobConnectionLiveTest {
// Test GET with options
// Non-matching ETag
try {
connection.getBlob(privateContainer, object.getKey(),
connection.getBlob(privateContainer, object.getName(),
GetOptions.Builder.ifETagDoesntMatch(newEtag)).get(120, TimeUnit.SECONDS);
} catch (Exception e) {
assertEquals(e.getCause().getClass(), HttpResponseException.class);
@ -331,7 +331,7 @@ public class AzureBlobConnectionLiveTest {
}
// Matching ETag
getBlob = connection.getBlob(privateContainer, object.getKey(),
getBlob = connection.getBlob(privateContainer, object.getName(),
GetOptions.Builder.ifETagMatches(newEtag)).get(120, TimeUnit.SECONDS);
assertEquals(getBlob.getMetadata().getETag(), newEtag);
@ -339,7 +339,7 @@ public class AzureBlobConnectionLiveTest {
// doesn't work per
// http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/479fa63f-51df-4b66-96b5-33ae362747b6
// getBlob = connection
// .getBlob(privateContainer, object.getKey(), GetOptions.Builder.startAt(8)).get(120,
// .getBlob(privateContainer, object.getName(), GetOptions.Builder.startAt(8)).get(120,
// TimeUnit.SECONDS);
// assertEquals(IOUtils.toString((InputStream) getBlob.getData()), data.substring(8));

View File

@ -122,7 +122,7 @@ public class AddMD5ToListBlobsResponseTest extends BaseHandlerTest {
), null, null, 4, "newblob2.txt", null, "myfolder/");
BoundedSortedSet<ListBlobsResponse> result = (BoundedSortedSet<ListBlobsResponse>) factory
.create(injector.getInstance(ContainerNameEnumerationResultsHandler.class))
.create(injector.getInstance(AddMD5ToListBlobsResponse.class))
.parse(is);
assertEquals(result, list);

View File

@ -66,7 +66,7 @@ public class BlobStoreContextImpl<S, C extends ContainerMetadata, M extends Blob
public B newBlob(String key) {
Object object = blobProvider.get();
B blob = (B) object;
blob.getMetadata().setKey(key);
blob.getMetadata().setName(key);
return blob;
}

View File

@ -24,10 +24,7 @@
package org.jclouds.blobstore.binders;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.core.HttpHeaders;
import org.jclouds.blobstore.domain.Blob;
@ -36,20 +33,10 @@ import org.jclouds.http.HttpUtils;
import org.jclouds.rest.Binder;
public class BindBlobToEntity implements Binder {
private final String metadataPrefix;
@Inject
public BindBlobToEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
this.metadataPrefix = metadataPrefix;
}
public void bindToRequest(HttpRequest request, Object entity) {
Blob<?> object = (Blob<?>) entity;
for (String key : object.getMetadata().getUserMetadata().keySet()) {
request.getHeaders().put(key.startsWith(metadataPrefix) ? key : metadataPrefix + key,
object.getMetadata().getUserMetadata().get(key));
}
request.setEntity(checkNotNull(object.getData(), "object.getContent()"));
request.getHeaders()
.put(

View File

@ -0,0 +1,52 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* 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.binders;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.HttpRequest;
public class BindBlobToEntityAndUserMetadataToHeadersWithPrefix extends BindBlobToEntity {
private final String metadataPrefix;
@Inject
public BindBlobToEntityAndUserMetadataToHeadersWithPrefix(
@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
this.metadataPrefix = metadataPrefix;
}
public void bindToRequest(HttpRequest request, Object entity) {
Blob<?> object = (Blob<?>) entity;
for (String key : object.getMetadata().getUserMetadata().keySet()) {
request.getHeaders().put(key.startsWith(metadataPrefix) ? key : metadataPrefix + key,
object.getMetadata().getUserMetadata().get(key));
}
super.bindToRequest(request, entity);
}
}

View File

@ -52,7 +52,7 @@ public class BindBlobToMultipartForm implements Binder {
public void bindToRequest(HttpRequest request, Object entity) {
Blob<?> object = (Blob<?>) entity;
Key key = BlobStoreUtils.parseKey(new Key("junk", object.getKey()));
Key key = BlobStoreUtils.parseKey(new Key("junk", object.getName()));
Multimap<String, String> partHeaders = ImmutableMultimap.of("Content-Disposition", String
.format("form-data; name=\"%s\"; filename=\"%s\"", key.getKey(), key.getKey()),
HttpHeaders.CONTENT_TYPE, checkNotNull(object.getMetadata().getContentType(),

View File

@ -23,17 +23,12 @@
*/
package org.jclouds.blobstore.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.awt.Container;
import java.io.IOException;
import java.io.InputStream;
import javax.inject.Inject;
import org.jclouds.blobstore.internal.BlobImpl;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.HttpUtils.MD5InputStreamResult;
import com.google.inject.ImplementedBy;
/**
* Value type for an HTTP Blob service. Blobs are stored in {@link Container containers} and consist
@ -43,81 +38,13 @@ import org.jclouds.http.HttpUtils.MD5InputStreamResult;
*
* @author Adrian Cole
*/
public class Blob<M extends BlobMetadata> implements Comparable<Blob<M>> {
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Blob<M> other = (Blob<M>) obj;
if (contentLength != other.contentLength)
return false;
if (contentRange == null) {
if (other.contentRange != null)
return false;
} else if (!contentRange.equals(other.contentRange))
return false;
if (data == null) {
if (other.data != null)
return false;
} else if (!data.equals(other.data))
return false;
if (getMetadata() == null) {
if (other.getMetadata() != null)
return false;
} else if (!getMetadata().equals(other.getMetadata()))
return false;
return true;
}
@Override
public String toString() {
return "Blob [contentLength=" + contentLength + ", contentRange=" + contentRange + ", data="
+ data + ", metadata=" + getMetadata() + "]";
}
protected Object data;
private M metadata;
protected long contentLength = -1;
protected String contentRange;
@SuppressWarnings("unchecked")
public Blob(String key) {
// TODO: why are we getting a generic warning here?
this((M) new BlobMetadata(key));
}
@SuppressWarnings("unchecked")
@Inject
public Blob() {
this((M) new BlobMetadata());
}
public Blob(M metadata) {
this.setMetadata(metadata);
}
public Blob(M metadata, Object data) {
this(metadata);
setData(data);
}
public Blob(String key, Object data) {
this(key);
setData(data);
}
@ImplementedBy(BlobImpl.class)
public interface Blob<M extends BlobMetadata> {
/**
* @see BlobMetadata#getKey()
* @see BlobMetadata#getName()
*/
public String getKey() {
return getMetadata().getKey();
}
String getName();
/**
* Sets entity for the request or the content from the response. If size isn't set, this will
@ -127,11 +54,7 @@ public class Blob<M extends BlobMetadata> implements Comparable<Blob<M>> {
* typically InputStream for downloads, or File, byte [], String, or InputStream for
* uploads.
*/
public void setData(Object data) {
this.data = checkNotNull(data, "data");
if (getMetadata().getSize() == -1)
this.getMetadata().setSize(HttpUtils.calculateSize(data));
}
void setData(Object data);
/**
* generate an MD5 Hash for the current data.
@ -143,46 +66,19 @@ public class Blob<M extends BlobMetadata> implements Comparable<Blob<M>> {
* @throws IOException
* if there is a problem generating the hash.
*/
public void generateMD5() throws IOException {
checkState(data != null, "data");
if (data instanceof InputStream) {
MD5InputStreamResult result = HttpUtils.generateMD5Result((InputStream) data);
getMetadata().setSize(result.length);
getMetadata().setContentMD5(result.eTag);
setData(result.data);
} else {
getMetadata().setContentMD5(HttpUtils.md5(data));
}
}
void generateMD5() throws IOException;
/**
* @return InputStream, if downloading, or whatever was set during {@link #setData(Object)}
*/
public Object getData() {
return data;
}
Object getData();
/**
* @return System and User metadata relevant to this object.
*/
public M getMetadata() {
return metadata;
}
M getMetadata();
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (contentLength ^ (contentLength >>> 32));
result = prime * result + ((contentRange == null) ? 0 : contentRange.hashCode());
result = prime * result + ((data == null) ? 0 : data.hashCode());
result = prime * result + ((getMetadata() == null) ? 0 : getMetadata().hashCode());
return result;
}
public void setContentLength(long contentLength) {
this.contentLength = contentLength;
}
void setContentLength(long contentLength);
/**
* Returns the total size of the downloaded object, or the chunk that's available.
@ -194,13 +90,9 @@ public class Blob<M extends BlobMetadata> implements Comparable<Blob<M>> {
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
* @see GetObjectOptions
*/
public long getContentLength() {
return contentLength;
}
long getContentLength();
public void setContentRange(String contentRange) {
this.contentRange = contentRange;
}
void setContentRange(String contentRange);
/**
* If this is not-null, {@link #getContentLength() } will the size of chunk of the Value available
@ -209,16 +101,8 @@ public class Blob<M extends BlobMetadata> implements Comparable<Blob<M>> {
* @see org.jclouds.http.HttpHeaders#CONTENT_RANGE
* @see GetObjectOptions
*/
public String getContentRange() {
return contentRange;
}
String getContentRange();
public void setMetadata(M metadata) {
this.metadata = metadata;
}
public int compareTo(Blob<M> o) {
return (this == o) ? 0 : getKey().compareTo(o.getKey());
}
void setMetadata(M metadata);
}

View File

@ -23,120 +23,23 @@
*/
package org.jclouds.blobstore.domain;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.Serializable;
import java.util.Map;
import javax.inject.Inject;
import javax.ws.rs.core.MediaType;
import org.jclouds.blobstore.internal.BlobMetadataImpl;
import org.joda.time.DateTime;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.inject.ImplementedBy;
/**
* System and user Metadata for the {@link Blob}.
*
* @author Adrian Cole
*/
public class BlobMetadata implements Comparable<BlobMetadata>, Serializable {
/** The serialVersionUID */
private static final long serialVersionUID = -5932618957134612231L;
@ImplementedBy(BlobMetadataImpl.class)
public interface BlobMetadata {
protected String key;
protected String eTag;
protected volatile long size = -1;
private byte[] contentMD5;
protected Multimap<String, String> allHeaders = HashMultimap.create();
protected Map<String, String> userMetadata = Maps.newHashMap();
protected DateTime lastModified;
protected String dataType = MediaType.APPLICATION_OCTET_STREAM;
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("BlobMetadata [key=").append(key).append(", eTag=").append(eTag).append(
", lastModified=").append(lastModified).append(", size=").append(size).append(
", dataType=").append(dataType).append(", userMetadata=").append(userMetadata)
.append("]");
return builder.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((dataType == null) ? 0 : dataType.hashCode());
result = prime * result + ((eTag == null) ? 0 : eTag.hashCode());
result = prime * result + ((key == null) ? 0 : key.hashCode());
result = prime * result + ((lastModified == null) ? 0 : lastModified.hashCode());
result = prime * result + (int) (size ^ (size >>> 32));
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BlobMetadata other = (BlobMetadata) obj;
if (dataType == null) {
if (other.dataType != null)
return false;
} else if (!dataType.equals(other.dataType))
return false;
if (eTag == null) {
if (other.eTag != null)
return false;
} else if (!eTag.equals(other.eTag))
return false;
if (key == null) {
if (other.key != null)
return false;
} else if (!key.equals(other.key))
return false;
if (lastModified == null) {
if (other.lastModified != null)
return false;
} else if (!lastModified.equals(other.lastModified))
return false;
if (size != other.size)
return false;
if (userMetadata == null) {
if (other.userMetadata != null)
return false;
} else if (!userMetadata.equals(other.userMetadata))
return false;
return true;
}
@Inject
public BlobMetadata() {
super();
}
/**
* @param key
* @see #getKey()
*/
public BlobMetadata(String key) {
setKey(key);
}
public void setKey(String key) {
checkNotNull(key, "key");
checkArgument(!key.startsWith("/"), "keys cannot start with /");
this.key = key;
}
void setName(String key);
/**
* The key is the handle that you assign to an object that allows you retrieve it later. A key is
@ -145,30 +48,20 @@ public class BlobMetadata implements Comparable<BlobMetadata>, Serializable {
*
* @see <a href= "http://docs.amazonwebservices.com/AmazonHTTP/2006-03-01/UsingKeys.html" />
*/
public String getKey() {
return key;
}
String getName();
public DateTime getLastModified() {
return lastModified;
}
DateTime getLastModified();
public void setLastModified(DateTime lastModified) {
this.lastModified = lastModified;
}
void setLastModified(DateTime lastModified);
/**
* The size of the object, in bytes.
*
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.13." />
*/
public long getSize() {
return size;
}
long getSize();
public void setSize(long size) {
this.size = size;
}
void setSize(long size);
/**
* A standard MIME type describing the format of the contents. If none is provided, the default
@ -176,65 +69,28 @@ public class BlobMetadata implements Comparable<BlobMetadata>, Serializable {
*
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.17." />
*/
public String getContentType() {
return dataType;
}
String getContentType();
public void setContentType(String dataType) {
this.dataType = dataType;
}
void setContentType(String dataType);
public void setContentMD5(byte[] contentMD5) {
if (contentMD5 != null) {
this.contentMD5 = new byte[contentMD5.length];
System.arraycopy(contentMD5, 0, this.contentMD5, 0, contentMD5.length);
}
}
void setContentMD5(byte[] contentMD5);
public byte[] getContentMD5() {
if (contentMD5 != null) {
byte[] retval = new byte[contentMD5.length];
System.arraycopy(this.contentMD5, 0, retval, 0, contentMD5.length);
return retval;
} else {
return null;
}
}
byte[] getContentMD5();
public void setETag(String eTag) {
this.eTag = eTag;
}
void setETag(String eTag);
/**
* @return the eTag value stored in the Etag header returned by HTTP.
*/
public String getETag() {
return eTag;
}
String getETag();
public void setUserMetadata(Map<String, String> userMetadata) {
this.userMetadata = userMetadata;
}
void setUserMetadata(Map<String, String> userMetadata);
/**
* Any key-value pairs associated with the object.
*/
public Map<String, String> getUserMetadata() {
return userMetadata;
}
Map<String, String> getUserMetadata();
public void setAllHeaders(Multimap<String, String> allHeaders) {
this.allHeaders = allHeaders;
}
Multimap<String, String> getAllHeaders();
/**
* @return all http response headers associated with this Value
*/
public Multimap<String, String> getAllHeaders() {
return allHeaders;
}
public int compareTo(BlobMetadata o) {
return (this == o) ? 0 : getKey().compareTo(o.getKey());
}
}

View File

@ -23,62 +23,20 @@
*/
package org.jclouds.blobstore.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.blobstore.internal.ContainerMetadataImpl;
import com.google.inject.ImplementedBy;
/**
* System metadata of the Container
*
* @author Adrian Cole
*/
public class ContainerMetadata implements Comparable<ContainerMetadata> {
@ImplementedBy(ContainerMetadataImpl.class)
public interface ContainerMetadata {
protected String name;
void setName(String name);
/**
* @see #getName()
*/
public ContainerMetadata(String name) {
this.name = checkNotNull(name, "name");
}
String getName();
public ContainerMetadata() {
super();
}
public void setName(String name) {
this.name = checkNotNull(name, "name");
}
public String getName() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ContainerMetadata other = (ContainerMetadata) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public int compareTo(ContainerMetadata o) {
return (this == o) ? 0 : getName().compareTo(o.getName());
}
}

View File

@ -28,11 +28,11 @@ import org.jclouds.blobstore.domain.BlobMetadata;
import com.google.common.base.Function;
public class BlobKey implements Function<Object, String> {
public class BlobName implements Function<Object, String> {
@SuppressWarnings("unchecked")
public String apply(Object from) {
return ((Blob<BlobMetadata>) from).getKey();
return ((Blob<BlobMetadata>) from).getName();
}
}

View File

@ -52,7 +52,7 @@ public class ParseContentTypeFromHeaders<M extends BlobMetadata> implements
public M apply(HttpResponse from) {
String objectKey = getKeyFor(from);
M to = metadataFactory.get();
to.setKey(objectKey);
to.setName(objectKey);
addAllHeadersTo(from, to);
setContentTypeOrThrowException(from, to);
return to;

View File

@ -140,7 +140,7 @@ public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMet
public Set<String> keySet() {
Set<String> keys = Sets.newHashSet();
for (BlobMetadata object : getAllBlobMetadata.execute(connection, containerName))
keys.add(object.getKey());
keys.add(object.getName());
return keys;
}

View File

@ -0,0 +1,226 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* 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.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.io.IOException;
import java.io.InputStream;
import javax.inject.Inject;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerMetadata;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.HttpUtils.MD5InputStreamResult;
/**
* Value type for an HTTP Blob service. Blobs are stored in {@link ContainerMetadata containers} and consist
* of a {@link org.jclouds.blobstore.domain.Value#getData() value}, a {@link Blob#getKey key and
*
* @link Blob.Metadata#getUserMetadata() metadata}
*
* @author Adrian Cole
*/
public class BlobImpl<M extends BlobMetadata> implements Blob<M>, Comparable<Blob<M>> {
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BlobImpl<M> other = (BlobImpl<M>) obj;
if (contentLength != other.contentLength)
return false;
if (contentRange == null) {
if (other.contentRange != null)
return false;
} else if (!contentRange.equals(other.contentRange))
return false;
if (data == null) {
if (other.data != null)
return false;
} else if (!data.equals(other.data))
return false;
if (getMetadata() == null) {
if (other.getMetadata() != null)
return false;
} else if (!getMetadata().equals(other.getMetadata()))
return false;
return true;
}
@Override
public String toString() {
return "Blob [contentLength=" + contentLength + ", contentRange=" + contentRange + ", data="
+ data + ", metadata=" + getMetadata() + "]";
}
protected Object data;
private M metadata;
protected long contentLength = -1;
protected String contentRange;
@SuppressWarnings("unchecked")
public BlobImpl(String key) {
// TODO: why are we getting a generic warning here?
this((M) new BlobMetadataImpl(key));
}
@SuppressWarnings("unchecked")
@Inject
public BlobImpl() {
this((M) new BlobMetadataImpl());
}
public BlobImpl(M metadata) {
this.setMetadata(metadata);
}
public BlobImpl(M metadata, Object data) {
this(metadata);
setData(data);
}
public BlobImpl(String key, Object data) {
this(key);
setData(data);
}
/**
* @see BlobMetadata#getName()
*/
public String getName() {
return getMetadata().getName();
}
/**
* Sets entity for the request or the content from the response. If size isn't set, this will
* attempt to discover it.
*
* @param data
* typically InputStream for downloads, or File, byte [], String, or InputStream for
* uploads.
*/
public void setData(Object data) {
this.data = checkNotNull(data, "data");
if (getMetadata().getSize() == -1)
this.getMetadata().setSize(HttpUtils.calculateSize(data));
}
/**
* generate an MD5 Hash for the current data.
* <p/>
* <h2>Note</h2>
* <p/>
* If this is an InputStream, it will be converted to a byte array first.
*
* @throws IOException
* if there is a problem generating the hash.
*/
public void generateMD5() throws IOException {
checkState(data != null, "data");
if (data instanceof InputStream) {
MD5InputStreamResult result = HttpUtils.generateMD5Result((InputStream) data);
getMetadata().setSize(result.length);
getMetadata().setContentMD5(result.eTag);
setData(result.data);
} else {
getMetadata().setContentMD5(HttpUtils.md5(data));
}
}
/**
* @return InputStream, if downloading, or whatever was set during {@link #setData(Object)}
*/
public Object getData() {
return data;
}
/**
* @return System and User metadata relevant to this object.
*/
public M getMetadata() {
return metadata;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (contentLength ^ (contentLength >>> 32));
result = prime * result + ((contentRange == null) ? 0 : contentRange.hashCode());
result = prime * result + ((data == null) ? 0 : data.hashCode());
result = prime * result + ((getMetadata() == null) ? 0 : getMetadata().hashCode());
return result;
}
public void setContentLength(long contentLength) {
this.contentLength = contentLength;
}
/**
* Returns the total size of the downloaded object, or the chunk that's available.
* <p/>
* Chunking is only used when org.jclouds.http.GetOptions is called with options like tail,
* range, or startAt.
*
* @return the length in bytes that can be be obtained from {@link #getData()}
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
* @see GetObjectOptions
*/
public long getContentLength() {
return contentLength;
}
public void setContentRange(String contentRange) {
this.contentRange = contentRange;
}
/**
* If this is not-null, {@link #getContentLength() } will the size of chunk of the Value available
* via {@link #getData()}
*
* @see org.jclouds.http.HttpHeaders#CONTENT_RANGE
* @see GetObjectOptions
*/
public String getContentRange() {
return contentRange;
}
public void setMetadata(M metadata) {
this.metadata = metadata;
}
public int compareTo(Blob<M> o) {
return (this == o) ? 0 : getName().compareTo(o.getName());
}
}

View File

@ -79,7 +79,7 @@ public class BlobMapImpl<C extends ContainerMetadata, M extends BlobMetadata, B
public Set<java.util.Map.Entry<String, B>> entrySet() {
Set<Map.Entry<String, B>> entrySet = new HashSet<Map.Entry<String, B>>();
for (B value : values()) {
Map.Entry<String, B> entry = new Entry(value.getKey(), value);
Map.Entry<String, B> entry = new Entry(value.getName(), value);
entrySet.add(entry);
}
return entrySet;

View File

@ -0,0 +1,247 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* 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.internal;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Map;
import javax.inject.Inject;
import javax.ws.rs.core.MediaType;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.joda.time.DateTime;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
/**
* System and user Metadata for the {@link Blob}.
*
* @author Adrian Cole
*/
public class BlobMetadataImpl implements Serializable, BlobMetadata, Comparable<BlobMetadata> {
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BlobMetadataImpl other = (BlobMetadataImpl) obj;
if (!Arrays.equals(contentMD5, other.contentMD5))
return false;
if (dataType == null) {
if (other.dataType != null)
return false;
} else if (!dataType.equals(other.dataType))
return false;
if (eTag == null) {
if (other.eTag != null)
return false;
} else if (!eTag.equals(other.eTag))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (lastModified == null) {
if (other.lastModified != null)
return false;
} else if (!lastModified.equals(other.lastModified))
return false;
if (size != other.size)
return false;
if (userMetadata == null) {
if (other.userMetadata != null)
return false;
} else if (!userMetadata.equals(other.userMetadata))
return false;
return true;
}
/** The serialVersionUID */
private static final long serialVersionUID = -5932618957134612231L;
protected String name;
protected String eTag;
protected volatile long size = -1;
private byte[] contentMD5;
protected Multimap<String, String> allHeaders = HashMultimap.create();
protected Map<String, String> userMetadata = Maps.newHashMap();
protected DateTime lastModified;
protected String dataType = MediaType.APPLICATION_OCTET_STREAM;
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("BlobMetadata [name=").append(name).append(", eTag=").append(eTag).append(
", lastModified=").append(lastModified).append(", size=").append(size).append(
", dataType=").append(dataType).append(", userMetadata=").append(userMetadata)
.append("]");
return builder.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(contentMD5);
result = prime * result + ((dataType == null) ? 0 : dataType.hashCode());
result = prime * result + ((eTag == null) ? 0 : eTag.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((lastModified == null) ? 0 : lastModified.hashCode());
result = prime * result + (int) (size ^ (size >>> 32));
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
return result;
}
@Inject
public BlobMetadataImpl() {
super();
}
/**
* @param name
* @see #getKey()
*/
public BlobMetadataImpl(String name) {
setName(name);
}
public void setName(String name) {
checkNotNull(name, "name");
checkArgument(!name.startsWith("/"), "names cannot start with /");
this.name = name;
}
/**
* The name is the handle that you assign to an object that allows you retrieve it later. A name
* is a sequence of Unicode characters whose UTF-8 encoding is at most 1024 bytes long. Each
* object in a bucket must have a unique name.
*
* @see <a href= "http://docs.amazonwebservices.com/AmazonHTTP/2006-03-01/UsingKeys.html" />
*/
public String getName() {
return name;
}
public DateTime getLastModified() {
return lastModified;
}
public void setLastModified(DateTime lastModified) {
this.lastModified = lastModified;
}
/**
* The size of the object, in bytes.
*
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.13." />
*/
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
/**
* A standard MIME type describing the format of the contents. If none is provided, the default
* is binary/octet-stream.
*
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.17." />
*/
public String getContentType() {
return dataType;
}
public void setContentType(String dataType) {
this.dataType = dataType;
}
public void setContentMD5(byte[] contentMD5) {
if (contentMD5 != null) {
this.contentMD5 = new byte[contentMD5.length];
System.arraycopy(contentMD5, 0, this.contentMD5, 0, contentMD5.length);
}
}
public byte[] getContentMD5() {
if (contentMD5 != null) {
byte[] retval = new byte[contentMD5.length];
System.arraycopy(this.contentMD5, 0, retval, 0, contentMD5.length);
return retval;
} else {
return null;
}
}
public void setETag(String eTag) {
this.eTag = eTag;
}
/**
* @return the eTag value stored in the Etag header returned by HTTP.
*/
public String getETag() {
return eTag;
}
public void setUserMetadata(Map<String, String> userMetadata) {
this.userMetadata = userMetadata;
}
/**
* Any key-value pairs associated with the object.
*/
public Map<String, String> getUserMetadata() {
return userMetadata;
}
public void setAllHeaders(Multimap<String, String> allHeaders) {
this.allHeaders = allHeaders;
}
/**
* @return all http response headers associated with this Value
*/
public Multimap<String, String> getAllHeaders() {
return allHeaders;
}
public int compareTo(BlobMetadata o) {
return (this == o) ? 0 : getName().compareTo(o.getName());
}
}

View File

@ -0,0 +1,86 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* 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.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.blobstore.domain.ContainerMetadata;
/**
* System metadata of the Container
*
* @author Adrian Cole
*/
public class ContainerMetadataImpl implements ContainerMetadata, Comparable<ContainerMetadata> {
protected String name;
/**
* @see #getName()
*/
public ContainerMetadataImpl(String name) {
this.name = checkNotNull(name, "name");
}
public ContainerMetadataImpl() {
super();
}
public void setName(String name) {
this.name = checkNotNull(name, "name");
}
public String getName() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ContainerMetadataImpl other = (ContainerMetadataImpl) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public int compareTo(ContainerMetadata o) {
return (this == o) ? 0 : getName().compareTo(o.getName());
}
}

View File

@ -144,7 +144,7 @@ public class InputStreamMapImpl<C extends ContainerMetadata, M extends BlobMetad
public Set<Map.Entry<String, InputStream>> entrySet() {
Set<Map.Entry<String, InputStream>> entrySet = new HashSet<Map.Entry<String, InputStream>>();
for (B object : this.getAllBlobs.execute(connection, containerName)) {
entrySet.add(new Entry(object.getKey(), (InputStream) object.getData()));
entrySet.add(new Entry(object.getName(), (InputStream) object.getData()));
}
return entrySet;
}
@ -226,7 +226,7 @@ public class InputStreamMapImpl<C extends ContainerMetadata, M extends BlobMetad
Set<Future<String>> puts = Sets.newHashSet();
for (Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
B object = blobFactory.get();
object.getMetadata().setKey(entry.getKey());
object.getMetadata().setName(entry.getKey());
object.setData(entry.getValue());
object.generateMD5();
puts.add(connection.putBlob(containerName, object));
@ -288,7 +288,7 @@ public class InputStreamMapImpl<C extends ContainerMetadata, M extends BlobMetad
@VisibleForTesting
InputStream putInternal(String s, Object o) {
B object = blobFactory.get();
object.getMetadata().setKey(s);
object.getMetadata().setName(s);
try {
InputStream returnVal = containsKey(s) ? get(s) : null;
object.setData(o);

View File

@ -65,7 +65,7 @@ public class DeleteAllKeysClearContainerStrategy<C extends ContainerMetadata, M
public void execute(BlobStore<C, M, B> connection, final String containerName) {
Set<Future<Void>> deletes = Sets.newHashSet();
for (M md : getAllBlobMetadata.execute(connection, containerName)) {
deletes.add(connection.removeBlob(containerName, md.getKey()));
deletes.add(connection.removeBlob(containerName, md.getName()));
}
for (Future<Void> isdeleted : deletes) {
try {

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.blobstore.strategy.internal;
import java.util.Comparator;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
@ -78,10 +79,16 @@ public class RetryOnNotFoundGetAllBlobsStrategy<C extends ContainerMetadata, M e
}
public SortedSet<B> execute(BlobStore<C, M, B> connection, String container) {
SortedSet<B> objects = Sets.<B> newTreeSet();
SortedSet<B> objects = Sets.<B> newTreeSet(new Comparator<B>() {
public int compare(B o1, B o2) {
return (o1 == o2) ? 0 : o1.getName().compareTo(o2.getName());
}
});
Map<String, Future<B>> futureObjects = Maps.newHashMap();
for (M md : getAllBlobMetadata.execute(connection, container)) {
futureObjects.put(md.getKey(), connection.getBlob(container, md.getKey()));
futureObjects.put(md.getName(), connection.getBlob(container, md.getName()));
}
for (Entry<String, Future<B>> futureObjectEntry : futureObjects.entrySet()) {
try {
@ -103,7 +110,7 @@ public class RetryOnNotFoundGetAllBlobsStrategy<C extends ContainerMetadata, M e
for (int i = 0; i < 3; i++) {
try {
B object = value.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
object.getMetadata().setKey(key);
object.getMetadata().setName(key);
objects.add(object);
return;
} catch (KeyNotFoundException e) {

View File

@ -34,6 +34,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.internal.BlobImpl;
import org.jclouds.http.HttpRequest;
import org.jclouds.util.Utils;
import org.testng.annotations.Test;
@ -55,7 +56,7 @@ public class BindBlobToMultipartFormTest {
addData(BOUNDRY, "hello", builder);
builder.append("--").append(BOUNDRY).append("--").append("\r\n");
EXPECTS = builder.toString();
TEST_BLOB = new Blob<BlobMetadata>("hello");
TEST_BLOB = new BlobImpl<BlobMetadata>("hello");
TEST_BLOB.setData("hello");
TEST_BLOB.getMetadata().setContentType(MediaType.TEXT_PLAIN);
}

View File

@ -29,6 +29,7 @@ import java.io.File;
import javax.ws.rs.core.MediaType;
import org.jclouds.blobstore.internal.BlobImpl;
import org.testng.annotations.Test;
@Test(groups = "unit", testName = "blobstore.BlobTest")
@ -36,7 +37,7 @@ public class BlobTest {
@Test
void testSetNoContentType() {
Blob<BlobMetadata> object = new Blob<BlobMetadata>("test");
Blob<BlobMetadata> object = new BlobImpl<BlobMetadata>("test");
File file = new File("hello.txt");
object.setData(file);
assertEquals(object.getMetadata().getContentType(), MediaType.APPLICATION_OCTET_STREAM);

View File

@ -36,6 +36,7 @@ import javax.ws.rs.core.HttpHeaders;
import org.apache.commons.io.IOUtils;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.internal.BlobImpl;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
@ -65,7 +66,7 @@ public class ParseBlobFromHeadersAndHttpContentTest {
private Provider<Blob<BlobMetadata>> blobProvider = new Provider<Blob<BlobMetadata>>() {
public Blob<BlobMetadata> get() {
return new Blob<BlobMetadata>("key");
return new BlobImpl<BlobMetadata>("key");
}
};

View File

@ -36,6 +36,7 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.internal.BlobMetadataImpl;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpResponse;
import org.jclouds.rest.internal.GeneratedHttpRequest;
@ -52,7 +53,7 @@ public class ParseBlobMetadataFromHeadersTest {
private Provider<BlobMetadata> blobMetadataProvider = new Provider<BlobMetadata>() {
public BlobMetadata get() {
return new BlobMetadata("key");
return new BlobMetadataImpl("key");
}
};
@ -74,7 +75,7 @@ public class ParseBlobMetadataFromHeadersTest {
Multimap<String, String> allHeaders = ImmutableMultimap.of("key", "value");
HttpResponse from = new HttpResponse();
from.setHeaders(allHeaders);
BlobMetadata metadata = new BlobMetadata("test");
BlobMetadata metadata = new BlobMetadataImpl("test");
parser.addAllHeadersTo(from, metadata);
assertEquals(metadata.getAllHeaders().get("key"), Collections.singletonList("value"));
}
@ -86,14 +87,14 @@ public class ParseBlobMetadataFromHeadersTest {
from.getHeaders().put(HttpHeaders.LAST_MODIFIED, "Wed, 09 Sep 2009 19:50:23 GMT");
from.getHeaders().put(HttpHeaders.CONTENT_LENGTH, "100");
BlobMetadata metadata = parser.apply(from);
assertEquals(metadata.getKey(), "key");
assertEquals(metadata.getName(), "key");
}
@Test
public void testSetContentLength() {
HttpResponse from = new HttpResponse();
from.getHeaders().put(HttpHeaders.CONTENT_LENGTH, "100");
BlobMetadata metadata = new BlobMetadata("test");
BlobMetadata metadata = new BlobMetadataImpl("test");
parser.setContentLengthOrThrowException(from, metadata);
assertEquals(metadata.getSize(), 100);
}
@ -101,7 +102,7 @@ public class ParseBlobMetadataFromHeadersTest {
@Test(expectedExceptions = HttpException.class)
public void testSetContentLengthException() {
HttpResponse from = new HttpResponse();
BlobMetadata metadata = new BlobMetadata("test");
BlobMetadata metadata = new BlobMetadataImpl("test");
parser.setContentLengthOrThrowException(from, metadata);
}
@ -109,7 +110,7 @@ public class ParseBlobMetadataFromHeadersTest {
public void testSetContentType() {
HttpResponse from = new HttpResponse();
from.getHeaders().put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
BlobMetadata metadata = new BlobMetadata("test");
BlobMetadata metadata = new BlobMetadataImpl("test");
parser.setContentTypeOrThrowException(from, metadata);
assertEquals(metadata.getContentType(), MediaType.APPLICATION_JSON);
}
@ -117,7 +118,7 @@ public class ParseBlobMetadataFromHeadersTest {
@Test(expectedExceptions = HttpException.class)
public void testSetContentTypeException() {
HttpResponse from = new HttpResponse();
BlobMetadata metadata = new BlobMetadata("test");
BlobMetadata metadata = new BlobMetadataImpl("test");
parser.setContentTypeOrThrowException(from, metadata);
}
@ -125,7 +126,7 @@ public class ParseBlobMetadataFromHeadersTest {
public void testSetLastModified() {
HttpResponse from = new HttpResponse();
from.getHeaders().put(HttpHeaders.LAST_MODIFIED, "Wed, 09 Sep 2009 19:50:23 GMT");
BlobMetadata metadata = new BlobMetadata("test");
BlobMetadata metadata = new BlobMetadataImpl("test");
parser.parseLastModifiedOrThrowException(from, metadata);
assertEquals(metadata.getLastModified(), new DateService()
.rfc822DateParse("Wed, 09 Sep 2009 19:50:23 GMT"));
@ -134,7 +135,7 @@ public class ParseBlobMetadataFromHeadersTest {
@Test(expectedExceptions = HttpException.class)
public void testSetLastModifiedException() {
HttpResponse from = new HttpResponse();
BlobMetadata metadata = new BlobMetadata("test");
BlobMetadata metadata = new BlobMetadataImpl("test");
parser.parseLastModifiedOrThrowException(from, metadata);
}
@ -142,7 +143,7 @@ public class ParseBlobMetadataFromHeadersTest {
public void testAddETagTo() {
HttpResponse from = new HttpResponse();
from.getHeaders().put(HttpHeaders.ETAG, "0xfeb");
BlobMetadata metadata = new BlobMetadata("test");
BlobMetadata metadata = new BlobMetadataImpl("test");
parser.addETagTo(from, metadata);
assertEquals(metadata.getETag(), "0xfeb");
}
@ -152,7 +153,7 @@ public class ParseBlobMetadataFromHeadersTest {
Multimap<String, String> allHeaders = ImmutableMultimap.of("prefix" + "key", "value");
HttpResponse from = new HttpResponse();
from.setHeaders(allHeaders);
BlobMetadata metadata = new BlobMetadata("test");
BlobMetadata metadata = new BlobMetadataImpl("test");
parser.addUserMetadataTo(from, metadata);
assertEquals(metadata.getUserMetadata().get("key"), "value");
}

View File

@ -26,8 +26,8 @@ package org.jclouds.blobstore.integration;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerMetadata;
import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
import org.jclouds.blobstore.internal.ContainerMetadataImpl;
import org.testng.annotations.Test;
/**
@ -37,6 +37,6 @@ import org.testng.annotations.Test;
*/
@Test(groups = { "integration"}, testName = "blobstore.StubBlobIntegrationTest")
public class StubBlobIntegrationTest extends
BaseBlobIntegrationTest<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
BaseBlobIntegrationTest<BlobStore<ContainerMetadataImpl, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadataImpl, BlobMetadata, Blob<BlobMetadata>> {
}

View File

@ -26,8 +26,8 @@ package org.jclouds.blobstore.integration;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerMetadata;
import org.jclouds.blobstore.integration.internal.BaseBlobMapIntegrationTest;
import org.jclouds.blobstore.internal.ContainerMetadataImpl;
import org.testng.annotations.Test;
/**
@ -36,6 +36,6 @@ import org.testng.annotations.Test;
@Test(groups = { "integration", "live" }, testName = "blobstore.StubBlobMapIntegrationTest")
public class StubBlobMapIntegrationTest extends
BaseBlobMapIntegrationTest<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
BaseBlobMapIntegrationTest<BlobStore<ContainerMetadataImpl, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadataImpl, BlobMetadata, Blob<BlobMetadata>> {
}

View File

@ -26,8 +26,8 @@ package org.jclouds.blobstore.integration;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerMetadata;
import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
import org.jclouds.blobstore.internal.ContainerMetadataImpl;
import org.testng.annotations.Test;
/**
@ -37,6 +37,6 @@ import org.testng.annotations.Test;
@Test(groups = { "integration", "live" }, testName = "blobstore.StubContainerIntegrationTest")
public class StubContainerIntegrationTest
extends
BaseContainerIntegrationTest<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
BaseContainerIntegrationTest<BlobStore<ContainerMetadataImpl, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadataImpl, BlobMetadata, Blob<BlobMetadata>> {
}

View File

@ -26,8 +26,8 @@ package org.jclouds.blobstore.integration;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerMetadata;
import org.jclouds.blobstore.integration.internal.BaseInputStreamMapIntegrationTest;
import org.jclouds.blobstore.internal.ContainerMetadataImpl;
import org.testng.annotations.Test;
/**
@ -35,6 +35,6 @@ import org.testng.annotations.Test;
*/
@Test(groups = { "integration", "live" }, testName = "blobstore.StubInputStreamMapIntegrationTest")
public class StubInputStreamMapIntegrationTest extends
BaseInputStreamMapIntegrationTest<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
BaseInputStreamMapIntegrationTest<BlobStore<ContainerMetadataImpl, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadataImpl, BlobMetadata, Blob<BlobMetadata>> {
}

View File

@ -26,8 +26,8 @@ package org.jclouds.blobstore.integration;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerMetadata;
import org.jclouds.blobstore.integration.internal.BaseServiceIntegrationTest;
import org.jclouds.blobstore.internal.ContainerMetadataImpl;
import org.testng.annotations.Test;
/**
@ -36,6 +36,6 @@ import org.testng.annotations.Test;
@Test(groups = { "integration", "live" }, testName = "blobstore.StubServiceIntegrationTest")
public class StubServiceIntegrationTest
extends
BaseServiceIntegrationTest<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> {
BaseServiceIntegrationTest<BlobStore<ContainerMetadataImpl, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadataImpl, BlobMetadata, Blob<BlobMetadata>> {
}

View File

@ -46,8 +46,11 @@ public class StubBlobStoreConnectionModule extends AbstractModule {
protected void configure() {
bind(new TypeLiteral<Map<String, Map<String, Blob<BlobMetadata>>>>() {
}).toInstance(map);
bind(new TypeLiteral<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
}).to(new TypeLiteral<StubBlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
bind(
new TypeLiteral<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
})
.to(
new TypeLiteral<StubBlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
}).asEagerSingleton();
}
}

View File

@ -357,7 +357,7 @@ public class BaseBlobIntegrationTest<S, C extends ContainerMetadata, M extends B
try {
assertNotNull(context.getBlobStore().putBlob(containerName, object).get(30,
TimeUnit.SECONDS));
object = context.getBlobStore().getBlob(containerName, object.getKey()).get(30,
object = context.getBlobStore().getBlob(containerName, object.getName()).get(30,
TimeUnit.SECONDS);
String returnedString = BlobStoreUtils.getContentAsStringAndClose(object);
assertEquals(returnedString, realObject);

View File

@ -168,11 +168,11 @@ public class BaseBlobMapIntegrationTest<S, C extends ContainerMetadata, M extend
B object = context.newBlob("one");
object.setData(IOUtils.toInputStream("apple"));
object.generateMD5();
B old = map.put(object.getKey(), object);
B old = map.put(object.getName(), object);
getOneReturnsAppleAndOldValueIsNull(map, old);
object.setData(IOUtils.toInputStream("bear"));
object.generateMD5();
B apple = map.put(object.getKey(), object);
B apple = map.put(object.getName(), object);
getOneReturnsBearAndOldValueIsApple(map, apple);
} finally {
returnContainer(bucketName);

View File

@ -43,6 +43,7 @@ import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerMetadata;
import org.jclouds.blobstore.internal.ContainerMetadataImpl;
import org.jclouds.blobstore.util.BlobStoreUtils;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.util.Utils;
@ -166,10 +167,10 @@ public class BaseBlobStoreIntegrationTest<S, C extends ContainerMetadata, M exte
throws Exception {
try {
for (int i = 0; i < 2; i++) {
Iterable<ContainerMetadata> testContainers = Iterables.filter(
(SortedSet<ContainerMetadata>) context.getBlobStore().listContainers(),
new Predicate<ContainerMetadata>() {
public boolean apply(ContainerMetadata input) {
Iterable<ContainerMetadataImpl> testContainers = Iterables.filter(
(SortedSet<ContainerMetadataImpl>) context.getBlobStore().listContainers(),
new Predicate<ContainerMetadataImpl>() {
public boolean apply(ContainerMetadataImpl input) {
return input.getName().startsWith(CONTAINER_PREFIX.toLowerCase());
}
});

View File

@ -28,6 +28,7 @@ import java.util.SortedSet;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerMetadata;
import org.jclouds.blobstore.internal.ContainerMetadataImpl;
import org.testng.annotations.Test;
/**
@ -40,7 +41,7 @@ public class BaseServiceIntegrationTest<S, C extends ContainerMetadata, M extend
@Test(groups = { "integration", "live" })
void containerDoesntExist() throws Exception {
SortedSet<C> list = context.getBlobStore().listContainers();
assert !list.contains(new ContainerMetadata("shouldntexist"));
assert !list.contains(new ContainerMetadataImpl("shouldntexist"));
}
}

View File

@ -35,6 +35,7 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
@ -146,14 +147,22 @@ public class StubBlobStore<C extends ContainerMetadata, M extends BlobMetadata,
if (realContents == null)
throw new ContainerNotFoundException(name);
SortedSet<M> contents = Sets.newTreeSet(Iterables.transform(realContents.keySet(),
SortedSet<M> contents = Sets.newTreeSet(new Comparator<M>() {
public int compare(M o1, M o2) {
return (o1 == o2) ? 0 : o1.getName().compareTo(o2.getName());
}
});
Iterables.addAll(contents, Iterables.transform(realContents.keySet(),
new Function<String, M>() {
public M apply(String key) {
return realContents.get(key).getMetadata();
}
}));
return Sets.newTreeSet(contents);
return contents;
}
};
}
@ -184,7 +193,7 @@ public class StubBlobStore<C extends ContainerMetadata, M extends BlobMetadata,
public M copy(M in, String newKey) {
M newMd = copy(in);
newMd.setKey(newKey);
newMd.setName(newKey);
return newMd;
}
@ -257,7 +266,14 @@ public class StubBlobStore<C extends ContainerMetadata, M extends BlobMetadata,
}
public SortedSet<C> listContainers() {
return Sets.newTreeSet(Iterables.transform(getContainerToBlobs().keySet(),
SortedSet<C> returnVal = Sets.newTreeSet(new Comparator<C>() {
public int compare(C o1, C o2) {
return (o1 == o2) ? 0 : o1.getName().compareTo(o2.getName());
}
});
Iterables.addAll(returnVal, Iterables.transform(getContainerToBlobs().keySet(),
new Function<String, C>() {
public C apply(String name) {
C cmd = containerMetaProvider.get();
@ -266,6 +282,7 @@ public class StubBlobStore<C extends ContainerMetadata, M extends BlobMetadata,
}
}));
return returnVal;
}
public Future<Boolean> createContainer(final String name) {
@ -297,9 +314,9 @@ public class StubBlobStore<C extends ContainerMetadata, M extends BlobMetadata,
public boolean apply(M metadata) {
if (prefix == null)
return metadata.getKey().indexOf(delimiter) == -1;
if (metadata.getKey().startsWith(prefix))
return metadata.getKey().replaceFirst(prefix, "").indexOf(delimiter) == -1;
return metadata.getName().indexOf(delimiter) == -1;
if (metadata.getName().startsWith(prefix))
return metadata.getName().replaceFirst(prefix, "").indexOf(delimiter) == -1;
return false;
}
}
@ -315,7 +332,7 @@ public class StubBlobStore<C extends ContainerMetadata, M extends BlobMetadata,
}
public String apply(M metadata) {
String working = metadata.getKey();
String working = metadata.getName();
if (prefix != null) {
if (working.startsWith(prefix)) {
@ -401,7 +418,7 @@ public class StubBlobStore<C extends ContainerMetadata, M extends BlobMetadata,
B blob = blobProvider.get();
blob.setMetadata(newMd);
blob.setData(data);
container.put(object.getKey(), blob);
container.put(object.getName(), blob);
// Set HTTP headers to match metadata
newMd.getAllHeaders().put(HttpHeaders.LAST_MODIFIED,

View File

@ -30,7 +30,6 @@ import java.util.Map;
import org.jclouds.blobstore.BlobMap;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.BlobStoreContextImpl;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerMetadata;
@ -86,14 +85,14 @@ public class BaseBlobMapTest {
assertEquals(type4, type5);
TypeLiteral type6 = new TypeLiteral<BlobStoreContextImpl<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
TypeLiteral type6 = new TypeLiteral<BlobStoreContext<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
};
TypeLiteral type7 = TypeLiteral.get(Types.newParameterizedType(BlobStoreContextImpl.class,
Types.newParameterizedType(BlobStore.class, ContainerMetadata.class,
BlobMetadata.class, Types.newParameterizedType(Blob.class,
BlobMetadata.class)), ContainerMetadata.class, BlobMetadata.class,
Types.newParameterizedType(Blob.class, BlobMetadata.class)));
TypeLiteral type7 = TypeLiteral.get(Types.newParameterizedType(BlobStoreContext.class, Types
.newParameterizedType(BlobStore.class, ContainerMetadata.class, BlobMetadata.class,
Types.newParameterizedType(Blob.class, BlobMetadata.class)),
ContainerMetadata.class, BlobMetadata.class, Types.newParameterizedType(Blob.class,
BlobMetadata.class)));
assertEquals(type6, type7);
}

View File

@ -25,7 +25,6 @@ package org.jclouds.blobstore.strategy.internal;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.createNiceMock;
import static org.easymock.classextension.EasyMock.replay;
import java.util.HashSet;
@ -40,6 +39,7 @@ import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ContainerMetadata;
import org.jclouds.blobstore.integration.StubBlobStoreContextBuilder;
import org.jclouds.blobstore.internal.BlobImpl;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@ -73,7 +73,7 @@ public class RetryOnNotFoundGetAllBlobsStrategyTest {
public void testIfNotFoundRetryOtherwiseAddToSet() throws InterruptedException,
ExecutionException, TimeoutException {
Future<Blob<BlobMetadata>> futureObject = createMock(Future.class);
Blob<BlobMetadata> object = new Blob<BlobMetadata>("key");
Blob<BlobMetadata> object = new BlobImpl<BlobMetadata>("key");
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andThrow(
new KeyNotFoundException());
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andReturn(
@ -92,7 +92,7 @@ public class RetryOnNotFoundGetAllBlobsStrategyTest {
public void testIfNotFoundRetryOtherwiseAddToSetButNeverGetsIt() throws InterruptedException,
ExecutionException, TimeoutException {
Future<Blob<BlobMetadata>> futureObject = createMock(Future.class);
Blob object = createNiceMock(Blob.class);
Blob object = createMock(Blob.class);
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andThrow(
new KeyNotFoundException()).atLeastOnce();
replay(futureObject);

View File

@ -42,7 +42,7 @@ public class BindFileInfoToXmlEntity implements Binder {
public void bindToRequest(HttpRequest request, Object toBind) {
Blob<?> blob = (Blob<?>) toBind;
String bareKey = BlobStoreUtils.parseKey(new Key("trash", blob.getKey())).getKey();
String bareKey = BlobStoreUtils.parseKey(new Key("trash", blob.getName())).getKey();
String file = String.format(
"<file><name>%s</name><mime_type>%s</mime_type><public>false</public></file>",
bareKey, blob.getMetadata().getContentType());

View File

@ -32,7 +32,7 @@ import org.joda.time.DateTime;
* @author Adrian Cole
*
*/
public class ContainerMetadata extends org.jclouds.blobstore.domain.ContainerMetadata implements
public class ContainerMetadata extends org.jclouds.blobstore.internal.ContainerMetadataImpl implements
PCSObject {
private URI url;
private URI parent;

View File

@ -25,6 +25,7 @@ package org.jclouds.mezeo.pcs2.domain;
import java.net.URI;
import org.jclouds.blobstore.internal.BlobMetadataImpl;
import org.jclouds.mezeo.pcs2.util.PCSUtils;
import org.joda.time.DateTime;
@ -33,7 +34,7 @@ import org.joda.time.DateTime;
* @author Adrian Cole
*
*/
public class FileMetadata extends org.jclouds.blobstore.domain.BlobMetadata {
public class FileMetadata extends BlobMetadataImpl {
/** The serialVersionUID */
private static final long serialVersionUID = 1L;
private URI url;
@ -47,7 +48,7 @@ public class FileMetadata extends org.jclouds.blobstore.domain.BlobMetadata {
@Override
public String toString() {
return "FileMetadata [key=" + key + ", created=" + created + ", isInProject=" + isInProject
return "FileMetadata [key=" + name + ", created=" + created + ", isInProject=" + isInProject
+ ", isPublic=" + isPublic + ", isShared=" + isShared + ", owner=" + owner
+ ", url=" + url + ", version=" + version + ", allHeaders=" + allHeaders
+ ", dataType=" + dataType + ", eTag=" + eTag + ", accessed="

View File

@ -23,11 +23,13 @@
*/
package org.jclouds.mezeo.pcs2.domain;
import org.jclouds.blobstore.internal.BlobImpl;
/**
* @author Adrian Cole
*/
public class PCSFile extends org.jclouds.blobstore.domain.Blob<FileMetadata> {
public class PCSFile extends BlobImpl<FileMetadata> {
public PCSFile(FileMetadata metadata, FileMetadata data) {
super(metadata, data);

View File

@ -89,7 +89,7 @@ public class AddMetadataAndReturnId implements Function<HttpResponse, String>,
String container = request.getArgs()[0].toString();
PCSFile file = (PCSFile) request.getArgs()[1];
Key key = new Key(container, file.getKey());
Key key = new Key(container, file.getName());
String id = checkNotNull(fileCache.get(key), String.format(
"file %s should have an id in cache by now", key));

View File

@ -87,7 +87,7 @@ public class CreateSubFolderIfNotExistsAndGetResourceId implements Function<Obje
Object[] args = (Object[]) from;
checkArgument(args[0] instanceof String, "arg[0] must be a container name");
checkArgument(args[1] instanceof Blob, "arg[1] must be a pcsfile");
Key key = BlobStoreUtils.parseKey(new Key(args[0].toString(), ((Blob) args[1]).getKey()));
Key key = BlobStoreUtils.parseKey(new Key(args[0].toString(), ((Blob) args[1]).getName()));
try {
return finder.get(key.getContainer());
} catch (ComputationException e) {

View File

@ -93,7 +93,7 @@ public class CreateSubFolderIfNotExistsAndNewFileResource implements Function<Ob
URI newFile = connection.createFile(containerUri, file).get(
this.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
String id = PCSUtils.getFileId(newFile);
fileCache.put(new Key(container, file.getKey()), id);
fileCache.put(new Key(container, file.getName()), id);
return id;
} catch (Exception e) {
Utils.<ContainerNotFoundException> rethrowIfRuntimeOrSameType(e);

View File

@ -67,7 +67,7 @@ public class FindIdInFileList implements Function<Key, String> {
String idForNameInListOrException(String container, String toFind,
SortedSet<FileMetadata> response) {
for (FileMetadata data : response) {
if (toFind.equals(data.getKey())) {
if (toFind.equals(data.getName())) {
String path = data.getUrl().getPath();
int indexAfterContainersSlash = path.indexOf("files/") + "files/".length();
return path.substring(indexAfterContainersSlash);

View File

@ -202,7 +202,7 @@ public class PCSBlobStoreTest {
return new StubBlobStore.FutureBase<URI>() {
public URI get() throws InterruptedException, ExecutionException {
return URI.create("http://localhost/" + object.getKey());
return URI.create("http://localhost/" + object.getName());
}
};
}

View File

@ -133,7 +133,7 @@ public class PCSConnectionLiveTest {
connection.deleteFile(objectURI).get(10, TimeUnit.SECONDS);
// try sending it in 2 parts
object.getMetadata().setKey("sad");
object.getMetadata().setName("sad");
objectURI = connection.createFile(container, object).get(30, TimeUnit.SECONDS);
object.setData(data.substring(0, 2));

View File

@ -47,7 +47,7 @@ import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ParseURIList;
import org.jclouds.http.functions.ParseURIFromListOrLocationHeaderIf20x;
import org.jclouds.http.functions.ReturnInputStream;
import org.jclouds.http.functions.ReturnVoidIf2xx;
import org.jclouds.logging.Logger;
@ -108,7 +108,7 @@ public class PCSConnectionTest {
.singletonList("application/vnd.csp.container-info+xml"));
assertEquals(httpMethod.getEntity(), "<container><name>container</name></container>");
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
ParseURIList.class);
ParseURIFromListOrLocationHeaderIf20x.class);
// TODO check generic type of response parser
}
@ -181,7 +181,7 @@ public class PCSConnectionTest {
assertEquals(Utils.toStringAndClose((InputStream) httpMethod.getEntity()),
BindBlobToMultipartFormTest.EXPECTS);
assertEquals(processor.createResponseParser(method, httpMethod).getClass(),
ParseURIList.class);
ParseURIFromListOrLocationHeaderIf20x.class);
}
public void testDownloadFile() throws SecurityException, NoSuchMethodException, IOException {

View File

@ -59,7 +59,7 @@ public class AssembleBlobFromBlobMetadataCallTest {
replay(response);
PCSFile file = callable.apply(response);
assertEquals(file.getMetadata(), metadata);
assertEquals(file.getKey(), "blob");
assertEquals(file.getName(), "blob");
assertEquals(file.getData(), data);
assertEquals(file.getContentLength(), metadata.getSize());
}

View File

@ -33,9 +33,9 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
import org.jclouds.blobstore.internal.BlobImpl;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.nirvanix.sdn.domain.UploadInfo;
import org.testng.annotations.BeforeGroups;
@ -77,7 +77,7 @@ public class SDNConnectionLiveTest {
assertNotNull(uploadInfo.getToken());
connection.upload(uploadInfo.getHost(), uploadInfo.getToken(), containerName,
new Blob<BlobMetadata>("test.txt", "value")).get(30, TimeUnit.SECONDS);
new BlobImpl<BlobMetadata>("test.txt", "value")).get(30, TimeUnit.SECONDS);
String metadataS = connection.getMetadata(containerName + "/test.txt").get(30,
TimeUnit.SECONDS);

View File

@ -35,10 +35,10 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.binders.BindBlobToEntity;
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.functions.BlobKey;
import org.jclouds.blobstore.functions.BlobName;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
import org.jclouds.http.functions.ParseETagHeader;
@ -113,7 +113,7 @@ public interface CloudFilesBlobStore extends
@ResponseParser(ParseETagHeader.class)
Future<String> putBlob(
@PathParam("container") String container,
@PathParam("key") @ParamParser(BlobKey.class) @BinderParam(BindBlobToEntity.class) Blob<BlobMetadata> object);
@PathParam("key") @ParamParser(BlobName.class) @BinderParam(BindBlobToEntityAndUserMetadataToHeadersWithPrefix.class) Blob<BlobMetadata> object);
@GET
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)

View File

@ -37,11 +37,11 @@ import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.blobstore.binders.BindBlobToEntity;
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
import org.jclouds.blobstore.binders.BindMapToHeadersWithPrefix;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.functions.BlobKey;
import org.jclouds.blobstore.functions.BlobName;
import org.jclouds.blobstore.functions.ThrowContainerNotFoundOn404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
import org.jclouds.http.functions.ParseETagHeader;
@ -205,7 +205,7 @@ public interface CloudFilesConnection {
@ResponseParser(ParseETagHeader.class)
Future<String> putObject(
@PathParam("container") String container,
@PathParam("key") @ParamParser(BlobKey.class) @BinderParam(BindBlobToEntity.class) Blob<BlobMetadata> object);
@PathParam("key") @ParamParser(BlobName.class) @BinderParam(BindBlobToEntityAndUserMetadataToHeadersWithPrefix.class) Blob<BlobMetadata> object);
@GET
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)

View File

@ -30,12 +30,12 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.core.HttpHeaders;
import org.jclouds.blobstore.binders.BindBlobToEntity;
import org.jclouds.blobstore.binders.BindBlobToEntityAndUserMetadataToHeadersWithPrefix;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpUtils;
public class BindCFObjectAsEntity extends BindBlobToEntity {
public class BindCFObjectAsEntity extends BindBlobToEntityAndUserMetadataToHeadersWithPrefix {
@Inject
public BindCFObjectAsEntity(@Named(PROPERTY_USER_METADATA_PREFIX) String metadataPrefix) {
super(metadataPrefix);

View File

@ -28,7 +28,7 @@ package org.jclouds.rackspace.cloudfiles.domain;
* @author James Murty
*
*/
public class ContainerCDNMetadata extends org.jclouds.blobstore.domain.ContainerMetadata {
public class ContainerCDNMetadata extends org.jclouds.blobstore.internal.ContainerMetadataImpl {
private long ttl;
private boolean cdn_enabled;

View File

@ -28,7 +28,7 @@ package org.jclouds.rackspace.cloudfiles.domain;
* @author Adrian Cole
*
*/
public class ContainerMetadata extends org.jclouds.blobstore.domain.ContainerMetadata {
public class ContainerMetadata extends org.jclouds.blobstore.internal.ContainerMetadataImpl {
private long count;
private long bytes;

View File

@ -27,11 +27,13 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.util.Comparator;
import java.util.SortedSet;
import javax.inject.Inject;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.internal.BlobMetadataImpl;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.functions.ParseJson;
import org.joda.time.DateTime;
@ -76,10 +78,17 @@ public class ParseBlobMetadataListFromJsonResponse extends ParseJson<SortedSet<B
try {
SortedSet<CloudFilesMetadata> list = gson.fromJson(new InputStreamReader(stream, "UTF-8"),
listType);
return Sets.newTreeSet(Iterables.transform(list,
SortedSet<BlobMetadata> returnVal = Sets.newTreeSet(new Comparator<BlobMetadata>() {
public int compare(BlobMetadata o1, BlobMetadata o2) {
return (o1 == o2) ? 0 : o1.getName().compareTo(o2.getName());
}
});
Iterables.addAll(returnVal, Iterables.transform(list,
new Function<CloudFilesMetadata, BlobMetadata>() {
public BlobMetadata apply(CloudFilesMetadata from) {
BlobMetadata metadata = new BlobMetadata(from.name);
BlobMetadata metadata = new BlobMetadataImpl(from.name);
metadata.setSize(from.bytes);
metadata.setLastModified(from.last_modified);
metadata.setContentType(from.content_type);
@ -88,6 +97,7 @@ public class ParseBlobMetadataListFromJsonResponse extends ParseJson<SortedSet<B
return metadata;
}
}));
return returnVal;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e);

View File

@ -40,6 +40,7 @@ import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
import org.jclouds.blobstore.internal.BlobImpl;
import org.jclouds.http.HttpResponseException;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.options.GetOptions;
@ -277,7 +278,7 @@ public class CloudFilesConnectionLiveTest {
assertTrue(connection.createContainer(containerName).get(10, TimeUnit.SECONDS));
// Test PUT with string data, ETag hash, and a piece of metadata
Blob<BlobMetadata> object = new Blob<BlobMetadata>("object");
Blob<BlobMetadata> object = new BlobImpl<BlobMetadata>("object");
object.setData(data);
object.setContentLength(data.length());
object.generateMD5();
@ -296,8 +297,8 @@ public class CloudFilesConnectionLiveTest {
}
// Test HEAD of object
BlobMetadata metadata = connection.getObjectMetadata(containerName, object.getKey());
// TODO assertEquals(metadata.getKey(), object.getKey());
BlobMetadata metadata = connection.getObjectMetadata(containerName, object.getName());
// TODO assertEquals(metadata.getName(), object.getName());
assertEquals(metadata.getSize(), data.length());
assertEquals(metadata.getContentType(), "text/plain");
assertEquals(HttpUtils.toHexString(md5), HttpUtils.toHexString(object.getMetadata()
@ -310,7 +311,7 @@ public class CloudFilesConnectionLiveTest {
Map<String, String> userMetadata = Maps.newHashMap();
userMetadata.put("New-Metadata-1", "value-1");
userMetadata.put("New-Metadata-2", "value-2");
assertTrue(connection.setObjectMetadata(containerName, object.getKey(), userMetadata));
assertTrue(connection.setObjectMetadata(containerName, object.getName(), userMetadata));
// Test GET of missing object
try {
@ -319,10 +320,10 @@ public class CloudFilesConnectionLiveTest {
} catch (KeyNotFoundException e) {
}
// Test GET of object (including updated metadata)
Blob<BlobMetadata> getBlob = connection.getObject(containerName, object.getKey()).get(120,
Blob<BlobMetadata> getBlob = connection.getObject(containerName, object.getName()).get(120,
TimeUnit.SECONDS);
assertEquals(IOUtils.toString((InputStream) getBlob.getData()), data);
// TODO assertEquals(getBlob.getKey(), object.getKey());
// TODO assertEquals(getBlob.getName(), object.getName());
assertEquals(getBlob.getContentLength(), data.length());
assertEquals(getBlob.getMetadata().getContentType(), "text/plain");
assertEquals(HttpUtils.toHexString(md5), HttpUtils.toHexString(getBlob.getMetadata()
@ -345,7 +346,7 @@ public class CloudFilesConnectionLiveTest {
// Test PUT chunked/streamed upload with data of "unknown" length
ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes("UTF-8"));
object = new Blob<BlobMetadata>("chunked-object");
object = new BlobImpl<BlobMetadata>("chunked-object");
object.setData(bais);
newEtag = connection.putObject(containerName, object).get(10, TimeUnit.SECONDS);
assertEquals(HttpUtils.toHexString(md5), HttpUtils.toHexString(getBlob.getMetadata()
@ -354,7 +355,7 @@ public class CloudFilesConnectionLiveTest {
// Test GET with options
// Non-matching ETag
try {
connection.getObject(containerName, object.getKey(),
connection.getObject(containerName, object.getName(),
GetOptions.Builder.ifETagDoesntMatch(newEtag)).get(120, TimeUnit.SECONDS);
} catch (Exception e) {
assertEquals(e.getCause().getClass(), HttpResponseException.class);
@ -362,11 +363,12 @@ public class CloudFilesConnectionLiveTest {
}
// Matching ETag
getBlob = connection.getObject(containerName, object.getKey(),
getBlob = connection.getObject(containerName, object.getName(),
GetOptions.Builder.ifETagMatches(newEtag)).get(120, TimeUnit.SECONDS);
assertEquals(getBlob.getMetadata().getETag(), newEtag);
getBlob = connection.getObject(containerName, object.getKey(), GetOptions.Builder.startAt(8))
.get(120, TimeUnit.SECONDS);
getBlob = connection
.getObject(containerName, object.getName(), GetOptions.Builder.startAt(8)).get(120,
TimeUnit.SECONDS);
assertEquals(IOUtils.toString((InputStream) getBlob.getData()), data.substring(8));
assertTrue(connection.removeObject(containerName, "object").get(10, TimeUnit.SECONDS));

View File

@ -29,6 +29,8 @@ import java.io.InputStream;
import java.util.List;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.internal.BlobMetadataImpl;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.functions.config.ParserModule;
import org.joda.time.DateTime;
import org.testng.annotations.Test;
@ -51,14 +53,16 @@ public class ParseBlobMetadataListFromJsonResponseTest {
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/test_list_container.json");
List<BlobMetadata> expects = Lists.newArrayList();
BlobMetadata one = new BlobMetadata("test_obj_1");
BlobMetadata one = new BlobMetadataImpl("test_obj_1");
one.setETag("4281c348eaf83e70ddce0e07221c3d28");
one.setContentMD5(HttpUtils.fromHexString(one.getETag()));
one.setSize(14);
one.setContentType("application/octet-stream");
one.setLastModified(new DateTime("2009-02-03T05:26:32.612278"));
expects.add(one);
BlobMetadata two = new BlobMetadata("test_obj_2");
BlobMetadata two = new BlobMetadataImpl("test_obj_2");
two.setETag("b039efe731ad111bc1b0ef221c3849d0");
two.setContentMD5(HttpUtils.fromHexString(two.getETag()));
two.setSize(64);
two.setContentType("application/octet-stream");
two.setLastModified(new DateTime("2009-02-03T05:26:32.612278"));

View File

@ -29,6 +29,7 @@ import static org.testng.Assert.assertNotNull;
import javax.inject.Provider;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.internal.BlobMetadataImpl;
import org.jclouds.http.HttpResponse;
import org.jclouds.util.DateService;
import org.testng.annotations.Test;
@ -45,7 +46,7 @@ public class ParseObjectMetadataFromHeadersTest {
public void testEtagCaseIssue() {
ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(
createNiceMock(DateService.class), "", createNiceMock(Provider.class));
BlobMetadata md = new BlobMetadata("hello");
BlobMetadata md = new BlobMetadataImpl("hello");
HttpResponse response = new HttpResponse();
response.getHeaders().put("Etag", "feb1");
parser.addETagTo(response, md);