mirror of https://github.com/apache/jclouds.git
Issue 353: refactored payload/blob so that contentMetadata is a type.
This commit is contained in:
parent
546630ba52
commit
3639af0f12
|
@ -22,7 +22,10 @@ package org.jclouds.atmosonline.saas.blobstore.functions;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.atmosonline.saas.domain.MutableContentMetadata;
|
||||
import org.jclouds.atmosonline.saas.domain.internal.DelegatingMutableContentMetadata;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
@ -32,13 +35,9 @@ import com.google.common.base.Function;
|
|||
@Singleton
|
||||
public class BlobToContentMetadata implements Function<BlobMetadata, MutableContentMetadata> {
|
||||
public MutableContentMetadata apply(BlobMetadata base) {
|
||||
MutableContentMetadata to = new MutableContentMetadata();
|
||||
to.setContentType(base.getContentType());
|
||||
to.setContentMD5(base.getContentMD5());
|
||||
to.setName(base.getName());
|
||||
if (base.getSize() != null)
|
||||
to.setContentLength(base.getSize());
|
||||
return to;
|
||||
MutableBlobMetadataImpl to = new MutableBlobMetadataImpl();
|
||||
HttpUtils.copy(base.getContentMetadata(), to.getContentMetadata());
|
||||
return new DelegatingMutableContentMetadata(base.getName(), to.getContentMetadata());
|
||||
}
|
||||
|
||||
}
|
|
@ -33,9 +33,9 @@ import com.google.common.base.Function;
|
|||
@Singleton
|
||||
public class BlobToSystemMetadata implements Function<BlobMetadata, SystemMetadata> {
|
||||
public SystemMetadata apply(BlobMetadata base) {
|
||||
return new SystemMetadata(base.getContentMD5(), null, base.getLastModified(), null, null,
|
||||
null, 1, null, base.getName(), null, (base.getSize() != null) ? base.getSize() : 0,
|
||||
FileType.REGULAR, "root");
|
||||
return new SystemMetadata(base.getContentMetadata().getContentMD5(), null, base.getLastModified(), null, null,
|
||||
null, 1, null, base.getName(), null, (base.getContentMetadata().getContentLength() != null) ? base
|
||||
.getContentMetadata().getContentLength() : 0, FileType.REGULAR, "root");
|
||||
}
|
||||
|
||||
}
|
|
@ -32,6 +32,7 @@ import org.jclouds.blobstore.domain.internal.BlobMetadataImpl;
|
|||
import org.jclouds.blobstore.domain.internal.PageSetImpl;
|
||||
import org.jclouds.blobstore.domain.internal.StorageMetadataImpl;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.io.payloads.BaseMutableContentMetadata;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -59,11 +60,11 @@ public class DirectoryEntryListToResourceMetadataList implements
|
|||
public StorageMetadata apply(DirectoryEntry from) {
|
||||
StorageType type = from.getType() == FileType.DIRECTORY ? StorageType.FOLDER : StorageType.BLOB;
|
||||
if (type == StorageType.FOLDER)
|
||||
return new StorageMetadataImpl(type, from.getObjectID(), from.getObjectName(), defaultLocation.get(),
|
||||
null, null, null, null, Maps.<String, String> newHashMap());
|
||||
return new StorageMetadataImpl(type, from.getObjectID(), from.getObjectName(), defaultLocation
|
||||
.get(), null, null, null, Maps.<String, String> newHashMap());
|
||||
else
|
||||
return new BlobMetadataImpl(from.getObjectID(), from.getObjectName(), defaultLocation.get(), null,
|
||||
null, null, null, Maps.<String, String> newHashMap(), null, null, null, null, null);
|
||||
return new BlobMetadataImpl(from.getObjectID(), from.getObjectName(), defaultLocation.get(),
|
||||
null, null, null, Maps.<String, String> newHashMap(), new BaseMutableContentMetadata());
|
||||
}
|
||||
|
||||
}), from.getToken());
|
||||
|
|
|
@ -27,6 +27,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.atmosonline.saas.domain.AtmosObject;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.Blob.Factory;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
@ -49,9 +50,7 @@ public class ObjectToBlob implements Function<AtmosObject, Blob> {
|
|||
return null;
|
||||
Blob blob = blobFactory.create(object2BlobMd.apply(from));
|
||||
blob.setPayload(checkNotNull(from.getPayload(), "payload: " + from));
|
||||
if (from.getContentMetadata().getContentLength() != null)
|
||||
blob.getMetadata().setSize(from.getContentMetadata().getContentLength());
|
||||
blob.getMetadata().setContentMD5(from.getSystemMetadata().getContentMD5());
|
||||
HttpUtils.copy(from.getContentMetadata(), blob.getPayload().getContentMetadata());
|
||||
blob.setAllHeaders(from.getAllHeaders());
|
||||
return blob;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.jclouds.atmosonline.saas.functions.AtmosObjectName;
|
|||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
@ -58,11 +59,8 @@ public class ObjectToBlobMetadata implements Function<AtmosObject, MutableBlobMe
|
|||
MutableBlobMetadata to = new MutableBlobMetadataImpl();
|
||||
to.setId(from.getSystemMetadata().getObjectID());
|
||||
to.setLastModified(from.getSystemMetadata().getLastUserDataModification());
|
||||
to.setContentMD5(from.getSystemMetadata().getContentMD5());
|
||||
if (from.getContentMetadata().getContentType() != null)
|
||||
to.setContentType(from.getContentMetadata().getContentType());
|
||||
HttpUtils.copy(from.getContentMetadata(), to.getContentMetadata());
|
||||
to.setName(objectName.apply(from));
|
||||
to.setSize(from.getSystemMetadata().getSize());
|
||||
if (from.getSystemMetadata().getType() == FileType.DIRECTORY) {
|
||||
to.setType(StorageType.FOLDER);
|
||||
} else {
|
||||
|
|
|
@ -19,83 +19,20 @@
|
|||
|
||||
package org.jclouds.atmosonline.saas.domain;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import org.jclouds.atmosonline.saas.domain.internal.DelegatingMutableContentMetadata;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
* metadata of the object
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class MutableContentMetadata {
|
||||
@ImplementedBy(DelegatingMutableContentMetadata.class)
|
||||
public interface MutableContentMetadata extends org.jclouds.io.MutableContentMetadata {
|
||||
|
||||
private String name;
|
||||
private Long contentLength;
|
||||
private String contentType = MediaType.APPLICATION_OCTET_STREAM;
|
||||
private byte[] contentMD5;
|
||||
public String getName();
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 #getInput()}
|
||||
* @see org.jclouds.http.HttpHeaders#CONTENT_LENGTH
|
||||
* @see GetObjectOptions
|
||||
*/
|
||||
public Long getContentLength() {
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getContentLength
|
||||
*/
|
||||
public void setContentLength(Long contentLength) {
|
||||
this.contentLength = contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 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 contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getContentType
|
||||
*/
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* The 128-bit MD5 digest of the message (without the headers) according to RFC 1864. This header
|
||||
* can be used as a message integrity check to verify that the data is the same data that was
|
||||
* originally sent. Although it is optional, we recommend using the Content-MD5 mechanism as an
|
||||
* end-to-end integrity check.
|
||||
*
|
||||
*/
|
||||
public byte[] getContentMD5() {
|
||||
return contentMD5;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getContentMD5
|
||||
*/
|
||||
public void setContentMD5(byte[] contentMD5) {
|
||||
this.contentMD5 = contentMD5;
|
||||
}
|
||||
public void setName(String name);
|
||||
|
||||
}
|
|
@ -29,8 +29,6 @@ import org.jclouds.atmosonline.saas.domain.SystemMetadata;
|
|||
import org.jclouds.atmosonline.saas.domain.UserMetadata;
|
||||
import org.jclouds.http.internal.PayloadEnclosingImpl;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.PayloadEnclosing;
|
||||
import org.jclouds.io.payloads.DelegatingPayload;
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
@ -40,8 +38,7 @@ import com.google.common.collect.Multimap;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class AtmosObjectImpl extends PayloadEnclosingImpl implements AtmosObject,
|
||||
Comparable<AtmosObject> {
|
||||
public class AtmosObjectImpl extends PayloadEnclosingImpl implements AtmosObject, Comparable<AtmosObject> {
|
||||
private final UserMetadata userMetadata;
|
||||
private final SystemMetadata systemMetadata;
|
||||
|
||||
|
@ -53,15 +50,13 @@ public class AtmosObjectImpl extends PayloadEnclosingImpl implements AtmosObject
|
|||
return userMetadata;
|
||||
}
|
||||
|
||||
private final MutableContentMetadata _contentMetadata;
|
||||
private final SetPayloadPropertiesMutableContentMetadata contentMetadata;
|
||||
private MutableContentMetadata contentMetadata;
|
||||
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
|
||||
|
||||
public AtmosObjectImpl(MutableContentMetadata contentMetadata, SystemMetadata systemMetadata,
|
||||
UserMetadata userMetadata) {
|
||||
super();
|
||||
this.contentMetadata = linkMetadataToThis(contentMetadata);
|
||||
this._contentMetadata = this.contentMetadata.getDelegate();
|
||||
this.contentMetadata = contentMetadata;
|
||||
this.systemMetadata = systemMetadata;
|
||||
this.userMetadata = userMetadata;
|
||||
}
|
||||
|
@ -102,15 +97,16 @@ public class AtmosObjectImpl extends PayloadEnclosingImpl implements AtmosObject
|
|||
public int compareTo(AtmosObject o) {
|
||||
if (getContentMetadata().getName() == null)
|
||||
return -1;
|
||||
return (this == o) ? 0 : getContentMetadata().getName().compareTo(
|
||||
o.getContentMetadata().getName());
|
||||
return (this == o) ? 0 : getContentMetadata().getName().compareTo(o.getContentMetadata().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((_contentMetadata == null) ? 0 : _contentMetadata.hashCode());
|
||||
result = prime * result + ((contentMetadata == null) ? 0 : contentMetadata.hashCode());
|
||||
result = prime * result + ((systemMetadata == null) ? 0 : systemMetadata.hashCode());
|
||||
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -123,85 +119,32 @@ public class AtmosObjectImpl extends PayloadEnclosingImpl implements AtmosObject
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
AtmosObjectImpl other = (AtmosObjectImpl) obj;
|
||||
if (_contentMetadata == null) {
|
||||
if (other._contentMetadata != null)
|
||||
if (contentMetadata == null) {
|
||||
if (other.contentMetadata != null)
|
||||
return false;
|
||||
} else if (!_contentMetadata.equals(other._contentMetadata))
|
||||
} else if (!contentMetadata.equals(other.contentMetadata))
|
||||
return false;
|
||||
if (systemMetadata == null) {
|
||||
if (other.systemMetadata != null)
|
||||
return false;
|
||||
} else if (!systemMetadata.equals(other.systemMetadata))
|
||||
return false;
|
||||
if (userMetadata == null) {
|
||||
if (other.userMetadata != null)
|
||||
return false;
|
||||
} else if (!userMetadata.equals(other.userMetadata))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[contentMetadata=" + _contentMetadata + "]";
|
||||
return "[contentMetadata=" + contentMetadata + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPayload(Payload data) {
|
||||
linkPayloadToMetadata(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* link the new payload to the contentMetadata object so that when content-related
|
||||
* contentMetadata is updated on the payload, it is also copied the contentMetadata object.
|
||||
*/
|
||||
void linkPayloadToMetadata(Payload data) {
|
||||
if (data instanceof DelegatingPayload)
|
||||
super.setPayload(new SetMetadataPropertiesPayload(DelegatingPayload.class.cast(data)
|
||||
.getDelegate(), _contentMetadata));
|
||||
else
|
||||
super.setPayload(new SetMetadataPropertiesPayload(data, _contentMetadata));
|
||||
}
|
||||
|
||||
static class SetMetadataPropertiesPayload extends DelegatingPayload {
|
||||
|
||||
private transient final MutableContentMetadata contentMetadata;
|
||||
|
||||
public SetMetadataPropertiesPayload(Payload delegate, MutableContentMetadata contentMetadata) {
|
||||
super(delegate);
|
||||
this.contentMetadata = contentMetadata;
|
||||
setContentType(contentMetadata.getContentType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String md5) {
|
||||
super.setContentType(md5);
|
||||
contentMetadata.setContentType(md5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* link the contentMetadata object to this so that when content-related contentMetadata is
|
||||
* updated, it is also copied the currentpayload object.
|
||||
*/
|
||||
SetPayloadPropertiesMutableContentMetadata linkMetadataToThis(
|
||||
MutableContentMetadata contentMetadata) {
|
||||
return contentMetadata instanceof DelegatingMutableContentMetadata ? new SetPayloadPropertiesMutableContentMetadata(
|
||||
DelegatingMutableContentMetadata.class.cast(contentMetadata).getDelegate(), this)
|
||||
: new SetPayloadPropertiesMutableContentMetadata(contentMetadata, this);
|
||||
}
|
||||
|
||||
static class SetPayloadPropertiesMutableContentMetadata extends DelegatingMutableContentMetadata {
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -5072270546219814521L;
|
||||
private transient final PayloadEnclosing object;
|
||||
|
||||
public SetPayloadPropertiesMutableContentMetadata(MutableContentMetadata delegate,
|
||||
PayloadEnclosing object) {
|
||||
super(delegate);
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String type) {
|
||||
super.setContentType(type);
|
||||
if (canSetPayload())
|
||||
object.getPayload().setContentType(type);
|
||||
}
|
||||
|
||||
private boolean canSetPayload() {
|
||||
return object != null && object.getPayload() != null;
|
||||
}
|
||||
this.payload = data;
|
||||
this.contentMetadata = new DelegatingMutableContentMetadata(contentMetadata.getName(), payload.getContentMetadata());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,15 +20,22 @@
|
|||
package org.jclouds.atmosonline.saas.domain.internal;
|
||||
|
||||
import org.jclouds.atmosonline.saas.domain.MutableContentMetadata;
|
||||
import org.jclouds.io.payloads.BaseMutableContentMetadata;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class DelegatingMutableContentMetadata extends MutableContentMetadata {
|
||||
private final MutableContentMetadata delegate;
|
||||
public class DelegatingMutableContentMetadata implements MutableContentMetadata {
|
||||
private String name;
|
||||
private final org.jclouds.io.MutableContentMetadata delegate;
|
||||
|
||||
public DelegatingMutableContentMetadata(MutableContentMetadata delegate) {
|
||||
public DelegatingMutableContentMetadata() {
|
||||
this(null, new BaseMutableContentMetadata());
|
||||
}
|
||||
|
||||
public DelegatingMutableContentMetadata(String name, org.jclouds.io.MutableContentMetadata delegate) {
|
||||
this.name = name;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
@ -49,7 +56,7 @@ public class DelegatingMutableContentMetadata extends MutableContentMetadata {
|
|||
|
||||
@Override
|
||||
public String getName() {
|
||||
return delegate.getName();
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,26 +76,78 @@ public class DelegatingMutableContentMetadata extends MutableContentMetadata {
|
|||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
delegate.setName(name);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return delegate.equals(obj);
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
DelegatingMutableContentMetadata other = (DelegatingMutableContentMetadata) obj;
|
||||
if (delegate == null) {
|
||||
if (other.delegate != null)
|
||||
return false;
|
||||
} else if (!delegate.equals(other.delegate))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((delegate == null) ? 0 : delegate.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
return "[name=" + name + ", delegate=" + delegate + "]";
|
||||
}
|
||||
|
||||
public MutableContentMetadata getDelegate() {
|
||||
public org.jclouds.io.MutableContentMetadata getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentDisposition(String contentDisposition) {
|
||||
delegate.setContentDisposition(contentDisposition);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentEncoding(String contentEncoding) {
|
||||
delegate.setContentEncoding(contentEncoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentLanguage(String contentLanguage) {
|
||||
delegate.setContentLanguage(contentLanguage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentDisposition() {
|
||||
return delegate.getContentDisposition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentEncoding() {
|
||||
return delegate.getContentEncoding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentLanguage() {
|
||||
return delegate.getContentLanguage();
|
||||
}
|
||||
|
||||
}
|
|
@ -171,7 +171,7 @@ public class SignRequest implements HttpRequestFilter {
|
|||
}
|
||||
|
||||
private void appendPayloadMetadata(HttpRequest request, StringBuilder buffer) {
|
||||
buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentType()))
|
||||
buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentMetadata().getContentType()))
|
||||
.append("\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.jclouds.atmosonline.saas.filters.SignRequest;
|
|||
import org.jclouds.atmosonline.saas.xml.ErrorHandler;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
|
@ -72,8 +71,6 @@ public class AtmosStorageUtils {
|
|||
String container, Blob blob) {
|
||||
final String path = container + "/" + blob.getMetadata().getName();
|
||||
deleteAndEnsureGone(sync, path);
|
||||
if (blob.getMetadata().getContentMD5() != null)
|
||||
blob.getMetadata().getUserMetadata().put("content-md5", CryptoStreams.hex(blob.getMetadata().getContentMD5()));
|
||||
sync.createFile(container, blob2Object.apply(blob));
|
||||
return path;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ import org.jclouds.blobstore.domain.Blob.Factory;
|
|||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.io.payloads.PhantomPayload;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.RestClientTest;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
|
@ -83,8 +82,10 @@ public class AtmosBlobRequestSignerTest extends RestClientTest<AtmosStorageAsync
|
|||
NoSuchMethodException, IOException {
|
||||
Blob blob = blobFactory.create(null);
|
||||
blob.getMetadata().setName("name");
|
||||
blob.setPayload(new PhantomPayload(2l, new byte[] { 0, 2, 4, 8 }));
|
||||
blob.getPayload().setContentType("text/plain");
|
||||
blob.setPayload("");
|
||||
blob.getPayload().getContentMetadata().setContentLength(2l);
|
||||
blob.getPayload().getContentMetadata().setContentMD5(new byte[] { 0, 2, 4, 8 });
|
||||
blob.getPayload().getContentMetadata().setContentType("text/plain");
|
||||
|
||||
HttpRequest request = signer.signPutBlob("container", blob);
|
||||
|
||||
|
|
|
@ -110,8 +110,8 @@ public class SignRequestTest {
|
|||
public HttpRequest newRequest() {
|
||||
HttpRequest request = new HttpRequest("POST", URI.create("http://localhost/rest/objects"));
|
||||
request.setPayload("");
|
||||
request.getPayload().setContentLength(4286l);
|
||||
request.getPayload().setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||
request.getPayload().getContentMetadata().setContentLength(4286l);
|
||||
request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||
|
||||
request.getHeaders().put(AtmosStorageHeaders.LISTABLE_META, "part4/part7/part8=quick");
|
||||
request.getHeaders().put(AtmosStorageHeaders.META, "part1=buy");
|
||||
|
|
|
@ -103,7 +103,7 @@ public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient {
|
|||
public URI apply(Boolean from) {
|
||||
if (path != null) {
|
||||
Blob blob = blobStore.newBlob(path + "/");
|
||||
blob.getMetadata().setContentType("application/directory");
|
||||
blob.getMetadata().getContentMetadata().setContentType("application/directory");
|
||||
blob.setPayload("");
|
||||
blobStore.putBlob(container, blob);
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ public class FormSigner implements HttpRequestFilter, RequestSigner {
|
|||
return o1.getKey().compareTo(o2.getKey());
|
||||
}
|
||||
}));
|
||||
request.getPayload().setContentType("application/x-www-form-urlencoded");
|
||||
request.getPayload().getContentMetadata().setContentType("application/x-www-form-urlencoded");
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
|
|
@ -71,9 +71,9 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
|
|||
AWSError error = null;
|
||||
String message = null;
|
||||
if (response.getPayload() != null) {
|
||||
if (response.getPayload().getContentType() != null
|
||||
&& (response.getPayload().getContentType().indexOf("xml") != -1 || response.getPayload()
|
||||
.getContentType().indexOf("unknown") != -1)) {
|
||||
String contentType = response.getPayload().getContentMetadata().getContentType();
|
||||
if (contentType != null
|
||||
&& (contentType.indexOf("xml") != -1 || contentType.indexOf("unknown") != -1)) {
|
||||
error = utils.parseAWSErrorFromContent(request, response);
|
||||
if (error != null) {
|
||||
message = error.getMessage();
|
||||
|
|
|
@ -52,7 +52,7 @@ public class BindACLToXMLPayload implements Binder {
|
|||
try {
|
||||
String stringPayload = generateBuilder(from).asString(outputProperties);
|
||||
request.setPayload(stringPayload);
|
||||
request.getPayload().setContentType(MediaType.TEXT_XML);
|
||||
request.getPayload().getContentMetadata().setContentType(MediaType.TEXT_XML);
|
||||
} catch (Exception e) {
|
||||
Throwables.propagateIfPossible(e);
|
||||
throw new RuntimeException("error transforming acl: " + from, e);
|
||||
|
|
|
@ -52,7 +52,7 @@ public class BindBucketLoggingToXmlPayload implements Binder {
|
|||
try {
|
||||
String stringPayload = generateBuilder(from).asString(outputProperties);
|
||||
request.setPayload(stringPayload);
|
||||
request.getPayload().setContentType(MediaType.TEXT_XML);
|
||||
request.getPayload().getContentMetadata().setContentType(MediaType.TEXT_XML);
|
||||
} catch (Exception e) {
|
||||
Throwables.propagateIfPossible(e);
|
||||
throw new RuntimeException("error transforming bucketLogging: " + from, e);
|
||||
|
|
|
@ -45,6 +45,6 @@ public class BindPayerToXmlPayload implements Binder {
|
|||
"<RequestPaymentConfiguration xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Payer>%s</Payer></RequestPaymentConfiguration>",
|
||||
((Payer) toBind).value());
|
||||
request.setPayload(text);
|
||||
request.getPayload().setContentType(MediaType.TEXT_XML);
|
||||
request.getPayload().getContentMetadata().setContentType(MediaType.TEXT_XML);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package org.jclouds.aws.s3.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -42,32 +41,21 @@ public class BindS3ObjectToPayload implements Binder {
|
|||
private final ObjectToBlob object2Blob;
|
||||
|
||||
@Inject
|
||||
public BindS3ObjectToPayload(ObjectToBlob object2Blob,
|
||||
BindUserMetadataToHeadersWithPrefix blobBinder) {
|
||||
public BindS3ObjectToPayload(ObjectToBlob object2Blob, BindUserMetadataToHeadersWithPrefix blobBinder) {
|
||||
this.blobBinder = blobBinder;
|
||||
this.object2Blob = object2Blob;
|
||||
}
|
||||
|
||||
public void bindToRequest(HttpRequest request, Object payload) {
|
||||
S3Object s3Object = (S3Object) payload;
|
||||
checkNotNull(s3Object.getPayload().getContentLength(), "contentLength");
|
||||
checkArgument(s3Object.getPayload().getContentLength() <= 5l * 1024 * 1024 * 1024,
|
||||
checkArgument(s3Object.getPayload().getContentMetadata().getContentLength() != null,
|
||||
"contentLength must be set, streaming not supported");
|
||||
checkArgument(s3Object.getPayload().getContentMetadata().getContentLength() <= 5l * 1024 * 1024 * 1024,
|
||||
"maximum size for put object is 5GB");
|
||||
blobBinder.bindToRequest(request, object2Blob.apply(s3Object));
|
||||
|
||||
if (s3Object.getMetadata().getCacheControl() != null) {
|
||||
request.getHeaders().put(HttpHeaders.CACHE_CONTROL,
|
||||
s3Object.getMetadata().getCacheControl());
|
||||
}
|
||||
|
||||
if (s3Object.getMetadata().getContentDisposition() != null) {
|
||||
request.getHeaders().put("Content-Disposition",
|
||||
s3Object.getMetadata().getContentDisposition());
|
||||
}
|
||||
|
||||
if (s3Object.getMetadata().getContentEncoding() != null) {
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_ENCODING,
|
||||
s3Object.getMetadata().getContentEncoding());
|
||||
request.getHeaders().put(HttpHeaders.CACHE_CONTROL, s3Object.getMetadata().getCacheControl());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.internal.MutableObjectMetadataImpl;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
@ -38,18 +39,14 @@ public class BlobToObjectMetadata implements Function<BlobMetadata, MutableObjec
|
|||
if (from == null)
|
||||
return null;
|
||||
MutableObjectMetadata to = new MutableObjectMetadataImpl();
|
||||
to.setContentType(from.getContentType());
|
||||
HttpUtils.copy(from.getContentMetadata(), to.getContentMetadata());
|
||||
to.setETag(from.getETag());
|
||||
to.setContentMD5(from.getContentMD5());
|
||||
to.setKey(from.getName());
|
||||
to.setLastModified(from.getLastModified());
|
||||
if (from.getSize() != null)
|
||||
to.setSize(from.getSize());
|
||||
if (from.getUserMetadata() != null) {
|
||||
for (Entry<String, String> entry : from.getUserMetadata().entrySet())
|
||||
to.getUserMetadata().put(entry.getKey().toLowerCase(), entry.getValue());
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
}
|
|
@ -27,6 +27,7 @@ import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
|||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
import org.jclouds.blobstore.strategy.IfDirectoryReturnNameStrategy;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
@ -46,13 +47,9 @@ public class ObjectToBlobMetadata implements Function<ObjectMetadata, MutableBlo
|
|||
if (from == null)
|
||||
return null;
|
||||
MutableBlobMetadata to = new MutableBlobMetadataImpl();
|
||||
if (from.getContentMD5() != null)
|
||||
to.setContentMD5(from.getContentMD5());
|
||||
if (from.getContentType() != null)
|
||||
to.setContentType(from.getContentType());
|
||||
HttpUtils.copy(from.getContentMetadata(), to.getContentMetadata());
|
||||
to.setETag(from.getETag());
|
||||
to.setName(from.getKey());
|
||||
to.setSize(from.getSize());
|
||||
to.setLastModified(from.getLastModified());
|
||||
to.setUserMetadata(from.getUserMetadata());
|
||||
String directoryName = ifDirectoryReturnName.execute(to);
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Date;
|
|||
import java.util.Map;
|
||||
|
||||
import org.jclouds.aws.s3.domain.internal.MutableObjectMetadataImpl;
|
||||
import org.jclouds.io.MutableContentMetadata;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
|
@ -68,47 +69,14 @@ public interface MutableObjectMetadata extends ObjectMetadata {
|
|||
*/
|
||||
void setCacheControl(String cacheControl);
|
||||
|
||||
/**
|
||||
* Specifies presentational information for the object.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1."/>
|
||||
*/
|
||||
void setContentDisposition(String contentDisposition);
|
||||
MutableContentMetadata getContentMetadata();
|
||||
|
||||
/**
|
||||
* Specifies what content encodings have been applied to the object and thus what decoding
|
||||
* mechanisms must be applied in order to obtain the media-type referenced by the Content-Type
|
||||
* header field.
|
||||
*
|
||||
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11" />
|
||||
*/
|
||||
void setContentEncoding(String encoding);
|
||||
|
||||
/**
|
||||
*
|
||||
* 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"/>
|
||||
*/
|
||||
void setContentType(String type);
|
||||
|
||||
/**
|
||||
* The base64 decoded 128-bit MD5 digest of the message (without the headers) according to RFC
|
||||
* 1864. This header can be used as a message integrity check to verify that the data is the same
|
||||
* data that was originally sent. Although it is optional, we recommend using the Content-MD5
|
||||
* mechanism as an end-to-end integrity check.
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTAuthentication.html"/>
|
||||
*/
|
||||
void setContentMD5(byte[] md5);
|
||||
void setContentMetadata(MutableContentMetadata md);
|
||||
|
||||
void setLastModified(Date lastModified);
|
||||
|
||||
void setETag(String eTag);
|
||||
|
||||
void setSize(Long size);
|
||||
|
||||
void setUserMetadata(Map<String, String> userMetadata);
|
||||
|
||||
}
|
|
@ -22,6 +22,8 @@ package org.jclouds.aws.s3.domain;
|
|||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
|
||||
/**
|
||||
* /** Amazon S3 is designed to store objects. Objects are stored in {@link S3BucketListing buckets}
|
||||
* and consist of a {@link org.jclouds.aws.s3.domain.S3Object#getData() value}, a
|
||||
|
@ -67,47 +69,12 @@ public interface ObjectMetadata extends Comparable<ObjectMetadata> {
|
|||
*/
|
||||
String getCacheControl();
|
||||
|
||||
/**
|
||||
* Specifies presentational information for the object.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1."/>
|
||||
*/
|
||||
String getContentDisposition();
|
||||
|
||||
/**
|
||||
* Specifies what content encodings have been applied to the object and thus what decoding
|
||||
* mechanisms must be applied in order to obtain the media-type referenced by the Content-Type
|
||||
* header field.
|
||||
*
|
||||
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11" />
|
||||
*/
|
||||
String getContentEncoding();
|
||||
|
||||
/**
|
||||
*
|
||||
* 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"/>
|
||||
*/
|
||||
String getContentType();
|
||||
|
||||
/**
|
||||
* The base64 decoded 128-bit MD5 digest of the message (without the headers) according to RFC
|
||||
* 1864. This header can be used as a message integrity check to verify that the data is the same
|
||||
* data that was originally sent. Although it is optional, we recommend using the Content-MD5
|
||||
* mechanism as an end-to-end integrity check.
|
||||
*
|
||||
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/latest/RESTAuthentication.html"/>
|
||||
*/
|
||||
byte[] getContentMD5();
|
||||
|
||||
Date getLastModified();
|
||||
|
||||
String getETag();
|
||||
|
||||
Long getSize();
|
||||
|
||||
Map<String, String> getUserMetadata();
|
||||
|
||||
ContentMetadata getContentMetadata();
|
||||
|
||||
}
|
|
@ -20,12 +20,13 @@
|
|||
package org.jclouds.aws.s3.domain.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
import org.jclouds.io.payloads.BaseImmutableContentMetadata;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
|
@ -42,29 +43,21 @@ public class BucketListObjectMetadata implements Serializable, ObjectMetadata {
|
|||
private final String key;
|
||||
private final Date lastModified;
|
||||
private final String eTag;
|
||||
private final long size;
|
||||
private final CanonicalUser owner;
|
||||
private final StorageClass storageClass;
|
||||
private final String contentType;
|
||||
private final byte[] contentMD5;
|
||||
private final String cacheControl;
|
||||
private final String contentDisposition;
|
||||
private final String contentEncoding;
|
||||
private final Map<String, String> userMetadata;
|
||||
private final ContentMetadata contentMetadata;
|
||||
|
||||
public BucketListObjectMetadata(String key, Date lastModified, String eTag, byte[] md5,
|
||||
long size, CanonicalUser owner, StorageClass storageClass) {
|
||||
public BucketListObjectMetadata(String key, Date lastModified, String eTag, byte[] md5, long contentLength,
|
||||
CanonicalUser owner, StorageClass storageClass) {
|
||||
this.key = key;
|
||||
this.lastModified = lastModified;
|
||||
this.eTag = eTag;
|
||||
this.size = size;
|
||||
this.owner = owner;
|
||||
this.contentMD5 = md5;
|
||||
this.contentMetadata = new BaseImmutableContentMetadata(null, contentLength, md5, null, null, null);
|
||||
this.storageClass = storageClass;
|
||||
this.contentType = null;
|
||||
this.cacheControl = null;
|
||||
this.contentDisposition = null;
|
||||
this.contentEncoding = null;
|
||||
this.userMetadata = Maps.newHashMap();
|
||||
}
|
||||
|
||||
|
@ -96,27 +89,6 @@ public class BucketListObjectMetadata implements Serializable, ObjectMetadata {
|
|||
return cacheControl;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentDisposition() {
|
||||
return contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentEncoding() {
|
||||
return contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -131,13 +103,6 @@ public class BucketListObjectMetadata implements Serializable, ObjectMetadata {
|
|||
return eTag;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -155,8 +120,9 @@ public class BucketListObjectMetadata implements Serializable, ObjectMetadata {
|
|||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public byte[] getContentMD5() {
|
||||
return contentMD5;
|
||||
@Override
|
||||
public ContentMetadata getContentMetadata() {
|
||||
return contentMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -164,15 +130,11 @@ public class BucketListObjectMetadata implements Serializable, ObjectMetadata {
|
|||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((cacheControl == null) ? 0 : cacheControl.hashCode());
|
||||
result = prime * result + ((contentDisposition == null) ? 0 : contentDisposition.hashCode());
|
||||
result = prime * result + ((contentEncoding == null) ? 0 : contentEncoding.hashCode());
|
||||
result = prime * result + Arrays.hashCode(contentMD5);
|
||||
result = prime * result + ((contentType == null) ? 0 : contentType.hashCode());
|
||||
result = prime * result + ((contentMetadata == null) ? 0 : contentMetadata.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 + ((owner == null) ? 0 : owner.hashCode());
|
||||
result = prime * result + (int) (size ^ (size >>> 32));
|
||||
result = prime * result + ((storageClass == null) ? 0 : storageClass.hashCode());
|
||||
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
|
||||
return result;
|
||||
|
@ -192,22 +154,10 @@ public class BucketListObjectMetadata implements Serializable, ObjectMetadata {
|
|||
return false;
|
||||
} else if (!cacheControl.equals(other.cacheControl))
|
||||
return false;
|
||||
if (contentDisposition == null) {
|
||||
if (other.contentDisposition != null)
|
||||
if (contentMetadata == null) {
|
||||
if (other.contentMetadata != null)
|
||||
return false;
|
||||
} else if (!contentDisposition.equals(other.contentDisposition))
|
||||
return false;
|
||||
if (contentEncoding == null) {
|
||||
if (other.contentEncoding != null)
|
||||
return false;
|
||||
} else if (!contentEncoding.equals(other.contentEncoding))
|
||||
return false;
|
||||
if (!Arrays.equals(contentMD5, other.contentMD5))
|
||||
return false;
|
||||
if (contentType == null) {
|
||||
if (other.contentType != null)
|
||||
return false;
|
||||
} else if (!contentType.equals(other.contentType))
|
||||
} else if (!contentMetadata.equals(other.contentMetadata))
|
||||
return false;
|
||||
if (eTag == null) {
|
||||
if (other.eTag != null)
|
||||
|
@ -229,8 +179,6 @@ public class BucketListObjectMetadata implements Serializable, ObjectMetadata {
|
|||
return false;
|
||||
} else if (!owner.equals(other.owner))
|
||||
return false;
|
||||
if (size != other.size)
|
||||
return false;
|
||||
if (storageClass == null) {
|
||||
if (other.storageClass != null)
|
||||
return false;
|
||||
|
|
|
@ -20,12 +20,13 @@
|
|||
package org.jclouds.aws.s3.domain.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
import org.jclouds.io.payloads.BaseImmutableContentMetadata;
|
||||
|
||||
/**
|
||||
* Returns the metadata parsable from a bucket listing
|
||||
|
@ -40,28 +41,20 @@ public class CopyObjectResult implements Serializable, ObjectMetadata {
|
|||
private final String key;
|
||||
private final Date lastModified;
|
||||
private final String eTag;
|
||||
private final Long size;
|
||||
private final CanonicalUser owner;
|
||||
private final StorageClass storageClass;
|
||||
private final String contentType;
|
||||
private final byte[] contentMD5;
|
||||
private final String cacheControl;
|
||||
private final String contentDisposition;
|
||||
private final String contentEncoding;
|
||||
private final Map<String, String> userMetadata;
|
||||
private final BaseImmutableContentMetadata contentMetadata;
|
||||
|
||||
public CopyObjectResult(Date lastModified, String eTag) {
|
||||
this.key = null;
|
||||
this.lastModified = lastModified;
|
||||
this.eTag = eTag;
|
||||
this.size = null;
|
||||
this.owner = null;
|
||||
this.storageClass = StorageClass.STANDARD;
|
||||
this.contentType = null;
|
||||
this.contentMD5 = null;
|
||||
this.contentMetadata = new BaseImmutableContentMetadata(null, null, null, null, null, null);
|
||||
this.cacheControl = null;
|
||||
this.contentDisposition = null;
|
||||
this.contentEncoding = null;
|
||||
this.userMetadata = null;
|
||||
}
|
||||
|
||||
|
@ -93,27 +86,6 @@ public class CopyObjectResult implements Serializable, ObjectMetadata {
|
|||
return cacheControl;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentDisposition() {
|
||||
return contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentEncoding() {
|
||||
return contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -128,13 +100,6 @@ public class CopyObjectResult implements Serializable, ObjectMetadata {
|
|||
return eTag;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -152,8 +117,9 @@ public class CopyObjectResult implements Serializable, ObjectMetadata {
|
|||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public byte[] getContentMD5() {
|
||||
return contentMD5;
|
||||
@Override
|
||||
public ContentMetadata getContentMetadata() {
|
||||
return contentMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -161,15 +127,11 @@ public class CopyObjectResult implements Serializable, ObjectMetadata {
|
|||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((cacheControl == null) ? 0 : cacheControl.hashCode());
|
||||
result = prime * result + ((contentDisposition == null) ? 0 : contentDisposition.hashCode());
|
||||
result = prime * result + ((contentEncoding == null) ? 0 : contentEncoding.hashCode());
|
||||
result = prime * result + Arrays.hashCode(contentMD5);
|
||||
result = prime * result + ((contentType == null) ? 0 : contentType.hashCode());
|
||||
result = prime * result + ((contentMetadata == null) ? 0 : contentMetadata.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 + ((owner == null) ? 0 : owner.hashCode());
|
||||
result = prime * result + ((size == null) ? 0 : size.hashCode());
|
||||
result = prime * result + ((storageClass == null) ? 0 : storageClass.hashCode());
|
||||
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
|
||||
return result;
|
||||
|
@ -189,22 +151,10 @@ public class CopyObjectResult implements Serializable, ObjectMetadata {
|
|||
return false;
|
||||
} else if (!cacheControl.equals(other.cacheControl))
|
||||
return false;
|
||||
if (contentDisposition == null) {
|
||||
if (other.contentDisposition != null)
|
||||
if (contentMetadata == null) {
|
||||
if (other.contentMetadata != null)
|
||||
return false;
|
||||
} else if (!contentDisposition.equals(other.contentDisposition))
|
||||
return false;
|
||||
if (contentEncoding == null) {
|
||||
if (other.contentEncoding != null)
|
||||
return false;
|
||||
} else if (!contentEncoding.equals(other.contentEncoding))
|
||||
return false;
|
||||
if (!Arrays.equals(contentMD5, other.contentMD5))
|
||||
return false;
|
||||
if (contentType == null) {
|
||||
if (other.contentType != null)
|
||||
return false;
|
||||
} else if (!contentType.equals(other.contentType))
|
||||
} else if (!contentMetadata.equals(other.contentMetadata))
|
||||
return false;
|
||||
if (eTag == null) {
|
||||
if (other.eTag != null)
|
||||
|
@ -226,11 +176,6 @@ public class CopyObjectResult implements Serializable, ObjectMetadata {
|
|||
return false;
|
||||
} else if (!owner.equals(other.owner))
|
||||
return false;
|
||||
if (size == null) {
|
||||
if (other.size != null)
|
||||
return false;
|
||||
} else if (!size.equals(other.size))
|
||||
return false;
|
||||
if (storageClass == null) {
|
||||
if (other.storageClass != null)
|
||||
return false;
|
||||
|
|
|
@ -1,184 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.aws.s3.domain.internal;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class DelegatingMutableObjectMetadata implements MutableObjectMetadata {
|
||||
private final MutableObjectMetadata delegate;
|
||||
|
||||
public DelegatingMutableObjectMetadata(MutableObjectMetadata delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ObjectMetadata o) {
|
||||
return delegate.compareTo(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return delegate.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCacheControl() {
|
||||
return delegate.getCacheControl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentDisposition() {
|
||||
return delegate.getContentDisposition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentEncoding() {
|
||||
return delegate.getContentEncoding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getContentMD5() {
|
||||
return delegate.getContentMD5();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return delegate.getContentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getETag() {
|
||||
return delegate.getETag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return delegate.getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getLastModified() {
|
||||
return delegate.getLastModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CanonicalUser getOwner() {
|
||||
return delegate.getOwner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSize() {
|
||||
return delegate.getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageClass getStorageClass() {
|
||||
return delegate.getStorageClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getUserMetadata() {
|
||||
return delegate.getUserMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCacheControl(String cacheControl) {
|
||||
delegate.setCacheControl(cacheControl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentDisposition(String contentDisposition) {
|
||||
delegate.setContentDisposition(contentDisposition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentEncoding(String encoding) {
|
||||
delegate.setContentEncoding(encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentMD5(byte[] md5) {
|
||||
delegate.setContentMD5(md5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String contentType) {
|
||||
delegate.setContentType(contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setETag(String eTag) {
|
||||
delegate.setETag(eTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKey(String key) {
|
||||
delegate.setKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastModified(Date lastModified) {
|
||||
delegate.setLastModified(lastModified);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOwner(CanonicalUser owner) {
|
||||
delegate.setOwner(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSize(Long size) {
|
||||
delegate.setSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStorageClass(StorageClass storageClass) {
|
||||
delegate.setStorageClass(storageClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserMetadata(Map<String, String> userMetadata) {
|
||||
delegate.setUserMetadata(userMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
public MutableObjectMetadata getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
}
|
|
@ -20,13 +20,15 @@
|
|||
package org.jclouds.aws.s3.domain.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.aws.s3.domain.CanonicalUser;
|
||||
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
||||
import org.jclouds.aws.s3.domain.ObjectMetadata;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.io.MutableContentMetadata;
|
||||
import org.jclouds.io.payloads.BaseMutableContentMetadata;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
|
@ -43,18 +45,21 @@ public class MutableObjectMetadataImpl implements Serializable, MutableObjectMet
|
|||
private String key;
|
||||
private Date lastModified;
|
||||
private String eTag;
|
||||
private Long size;
|
||||
private CanonicalUser owner;
|
||||
private StorageClass storageClass;
|
||||
private String contentType;
|
||||
private byte[] contentMD5;
|
||||
private String cacheControl;
|
||||
private String contentDisposition;
|
||||
private String contentEncoding;
|
||||
private Map<String, String> userMetadata = Maps.newHashMap();
|
||||
private MutableContentMetadata contentMetadata;
|
||||
|
||||
public MutableObjectMetadataImpl() {
|
||||
this.storageClass = StorageClass.STANDARD;
|
||||
this.contentMetadata = new BaseMutableContentMetadata();
|
||||
}
|
||||
|
||||
public MutableObjectMetadataImpl(ObjectMetadata from) {
|
||||
this.storageClass = StorageClass.STANDARD;
|
||||
this.contentMetadata = new BaseMutableContentMetadata();
|
||||
HttpUtils.copy(from.getContentMetadata(), this.contentMetadata);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,27 +90,6 @@ public class MutableObjectMetadataImpl implements Serializable, MutableObjectMet
|
|||
return cacheControl;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentDisposition() {
|
||||
return contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentEncoding() {
|
||||
return contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -120,13 +104,6 @@ public class MutableObjectMetadataImpl implements Serializable, MutableObjectMet
|
|||
return eTag;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -141,19 +118,6 @@ public class MutableObjectMetadataImpl implements Serializable, MutableObjectMet
|
|||
return userMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -161,38 +125,6 @@ public class MutableObjectMetadataImpl implements Serializable, MutableObjectMet
|
|||
this.cacheControl = cacheControl;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setContentDisposition(String contentDisposition) {
|
||||
this.contentDisposition = contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setContentEncoding(String encoding) {
|
||||
this.contentEncoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setContentMD5(byte[] md5) {
|
||||
if (md5 != null) {
|
||||
byte[] retval = new byte[md5.length];
|
||||
System.arraycopy(md5, 0, retval, 0, md5.length);
|
||||
this.contentMD5 = md5;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -221,13 +153,6 @@ public class MutableObjectMetadataImpl implements Serializable, MutableObjectMet
|
|||
this.owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setSize(Long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -242,20 +167,32 @@ public class MutableObjectMetadataImpl implements Serializable, MutableObjectMet
|
|||
this.userMetadata = userMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MutableContentMetadata getContentMetadata() {
|
||||
return contentMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setContentMetadata(MutableContentMetadata contentMetadata) {
|
||||
this.contentMetadata = contentMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((cacheControl == null) ? 0 : cacheControl.hashCode());
|
||||
result = prime * result + ((contentDisposition == null) ? 0 : contentDisposition.hashCode());
|
||||
result = prime * result + ((contentEncoding == null) ? 0 : contentEncoding.hashCode());
|
||||
result = prime * result + Arrays.hashCode(contentMD5);
|
||||
result = prime * result + ((contentType == null) ? 0 : contentType.hashCode());
|
||||
result = prime * result + ((contentMetadata == null) ? 0 : contentMetadata.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 + ((owner == null) ? 0 : owner.hashCode());
|
||||
result = prime * result + ((size == null) ? 0 : size.hashCode());
|
||||
result = prime * result + ((storageClass == null) ? 0 : storageClass.hashCode());
|
||||
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
|
||||
return result;
|
||||
|
@ -275,22 +212,10 @@ public class MutableObjectMetadataImpl implements Serializable, MutableObjectMet
|
|||
return false;
|
||||
} else if (!cacheControl.equals(other.cacheControl))
|
||||
return false;
|
||||
if (contentDisposition == null) {
|
||||
if (other.contentDisposition != null)
|
||||
if (contentMetadata == null) {
|
||||
if (other.contentMetadata != null)
|
||||
return false;
|
||||
} else if (!contentDisposition.equals(other.contentDisposition))
|
||||
return false;
|
||||
if (contentEncoding == null) {
|
||||
if (other.contentEncoding != null)
|
||||
return false;
|
||||
} else if (!contentEncoding.equals(other.contentEncoding))
|
||||
return false;
|
||||
if (!Arrays.equals(contentMD5, other.contentMD5))
|
||||
return false;
|
||||
if (contentType == null) {
|
||||
if (other.contentType != null)
|
||||
return false;
|
||||
} else if (!contentType.equals(other.contentType))
|
||||
} else if (!contentMetadata.equals(other.contentMetadata))
|
||||
return false;
|
||||
if (eTag == null) {
|
||||
if (other.eTag != null)
|
||||
|
@ -312,11 +237,6 @@ public class MutableObjectMetadataImpl implements Serializable, MutableObjectMet
|
|||
return false;
|
||||
} else if (!owner.equals(other.owner))
|
||||
return false;
|
||||
if (size == null) {
|
||||
if (other.size != null)
|
||||
return false;
|
||||
} else if (!size.equals(other.size))
|
||||
return false;
|
||||
if (storageClass == null) {
|
||||
if (other.storageClass != null)
|
||||
return false;
|
||||
|
@ -332,12 +252,9 @@ public class MutableObjectMetadataImpl implements Serializable, MutableObjectMet
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MutableObjectMetadataImpl [key=" + key + ", cacheControl=" + cacheControl
|
||||
+ ", contentDisposition=" + contentDisposition + ", contentEncoding="
|
||||
+ contentEncoding + ", contentMD5=" + Arrays.toString(contentMD5) + ", contentType="
|
||||
+ contentType + ", eTag=" + eTag + ", lastModified=" + lastModified + ", owner="
|
||||
+ owner + ", size=" + size + ", storageClass=" + storageClass + ", userMetadata="
|
||||
+ userMetadata + "]";
|
||||
return "[key=" + key + ", cacheControl=" + cacheControl + ", contentMetadata=" + contentMetadata + ", eTag="
|
||||
+ eTag + ", lastModified=" + lastModified + ", owner=" + owner + ", storageClass=" + storageClass
|
||||
+ ", userMetadata=" + userMetadata + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -28,8 +28,6 @@ import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
|||
import org.jclouds.aws.s3.domain.S3Object;
|
||||
import org.jclouds.http.internal.PayloadEnclosingImpl;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.PayloadEnclosing;
|
||||
import org.jclouds.io.payloads.DelegatingPayload;
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
@ -59,15 +57,13 @@ public class S3ObjectImpl extends PayloadEnclosingImpl implements S3Object, Comp
|
|||
return this.accessControlList;
|
||||
}
|
||||
|
||||
private final MutableObjectMetadata _metadata;
|
||||
private final SetPayloadPropertiesMutableObjectMetadata metadata;
|
||||
private final MutableObjectMetadata metadata;
|
||||
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
|
||||
|
||||
@Inject
|
||||
public S3ObjectImpl(MutableObjectMetadata metadata) {
|
||||
super();
|
||||
this.metadata = linkMetadataToThis(metadata);
|
||||
this._metadata = this.metadata.getDelegate();
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,7 +104,7 @@ public class S3ObjectImpl extends PayloadEnclosingImpl implements S3Object, Comp
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((_metadata == null) ? 0 : _metadata.hashCode());
|
||||
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -121,85 +117,23 @@ public class S3ObjectImpl extends PayloadEnclosingImpl implements S3Object, Comp
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
S3ObjectImpl other = (S3ObjectImpl) obj;
|
||||
if (_metadata == null) {
|
||||
if (other._metadata != null)
|
||||
if (metadata == null) {
|
||||
if (other.metadata != null)
|
||||
return false;
|
||||
} else if (!_metadata.equals(other._metadata))
|
||||
} else if (!metadata.equals(other.metadata))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[metadata=" + _metadata + "]";
|
||||
return "[metadata=" + metadata + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPayload(Payload data) {
|
||||
linkPayloadToMetadata(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* metadata link the new payload to the metadata object so that when content-related metadata is
|
||||
* updated on the payload, it is also copied the metadata object.
|
||||
*/
|
||||
void linkPayloadToMetadata(Payload data) {
|
||||
if (data instanceof DelegatingPayload)
|
||||
super.setPayload(new SetMetadataPropertiesPayload(DelegatingPayload.class.cast(data)
|
||||
.getDelegate(), _metadata));
|
||||
else
|
||||
super.setPayload(new SetMetadataPropertiesPayload(data, _metadata));
|
||||
}
|
||||
|
||||
static class SetMetadataPropertiesPayload extends DelegatingPayload {
|
||||
|
||||
private transient final MutableObjectMetadata metadata;
|
||||
|
||||
public SetMetadataPropertiesPayload(Payload delegate, MutableObjectMetadata metadata) {
|
||||
super(delegate);
|
||||
this.metadata = checkNotNull(metadata, "metadata");
|
||||
setContentType(metadata.getContentType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String md5) {
|
||||
super.setContentType(md5);
|
||||
metadata.setContentType(md5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* link the metadata object to this so that when content-related metadata is updated, it is also
|
||||
* copied the currentpayload object.
|
||||
*/
|
||||
SetPayloadPropertiesMutableObjectMetadata linkMetadataToThis(MutableObjectMetadata metadata) {
|
||||
return metadata instanceof DelegatingMutableObjectMetadata ? new SetPayloadPropertiesMutableObjectMetadata(
|
||||
DelegatingMutableObjectMetadata.class.cast(metadata).getDelegate(), this)
|
||||
: new SetPayloadPropertiesMutableObjectMetadata(metadata, this);
|
||||
}
|
||||
|
||||
static class SetPayloadPropertiesMutableObjectMetadata extends DelegatingMutableObjectMetadata {
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -5072270546219814521L;
|
||||
private transient final PayloadEnclosing object;
|
||||
|
||||
public SetPayloadPropertiesMutableObjectMetadata(MutableObjectMetadata delegate,
|
||||
PayloadEnclosing object) {
|
||||
super(delegate);
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String type) {
|
||||
super.setContentType(type);
|
||||
if (canSetPayload())
|
||||
object.getPayload().setContentType(type);
|
||||
}
|
||||
|
||||
private boolean canSetPayload() {
|
||||
return object != null && object.getPayload() != null;
|
||||
}
|
||||
super.setPayload(data);
|
||||
metadata.setContentMetadata(data.getContentMetadata());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -175,10 +175,12 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
|
|||
}
|
||||
|
||||
void appendPayloadMetadata(HttpRequest request, StringBuilder buffer) {
|
||||
buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentMD5()))
|
||||
.append("\n");
|
||||
buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentType()))
|
||||
.append("\n");
|
||||
buffer.append(
|
||||
utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentMetadata()
|
||||
.getContentMD5())).append("\n");
|
||||
buffer.append(
|
||||
utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentMetadata()
|
||||
.getContentType())).append("\n");
|
||||
}
|
||||
|
||||
void appendHttpHeaders(HttpRequest request, StringBuilder toSign) {
|
||||
|
|
|
@ -74,6 +74,6 @@ public class BindRegionToXmlPayload extends BindToStringPayload {
|
|||
"<CreateBucketConfiguration><LocationConstraint>%s</LocationConstraint></CreateBucketConfiguration>",
|
||||
value);
|
||||
super.bindToRequest(request, payload);
|
||||
request.getPayload().setContentType(MediaType.TEXT_XML);
|
||||
request.getPayload().getContentMetadata().setContentType(MediaType.TEXT_XML);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,8 +50,6 @@ public class ParseObjectFromHeadersAndHttpContent implements Function<HttpRespon
|
|||
|
||||
public S3Object apply(HttpResponse from) {
|
||||
MutableObjectMetadata metadata = metadataParser.apply(from);
|
||||
if (metadata.getContentMD5() != null)
|
||||
from.getPayload().setContentMD5(metadata.getContentMD5());
|
||||
S3Object object = objectProvider.create(metadata);
|
||||
object.getAllHeaders().putAll(from.getHeaders());
|
||||
object.setPayload(from.getPayload());
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package org.jclouds.aws.s3.functions;
|
||||
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
import static org.jclouds.http.HttpUtils.attemptToParseSizeAndRangeFromHeaders;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
@ -30,11 +29,9 @@ import org.jclouds.aws.s3.blobstore.functions.BlobToObjectMetadata;
|
|||
import org.jclouds.aws.s3.domain.MutableObjectMetadata;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders;
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.rest.InvocationContext;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
|
@ -67,11 +64,7 @@ public class ParseObjectMetadataFromHeaders implements Function<HttpResponse, Mu
|
|||
BlobMetadata base = blobMetadataParser.apply(from);
|
||||
MutableObjectMetadata to = blobToObjectMetadata.apply(base);
|
||||
addETagTo(from, to);
|
||||
to.setSize(attemptToParseSizeAndRangeFromHeaders(from));
|
||||
to.setContentMD5(CryptoStreams.hex(Utils.replaceAll(to.getETag(), '"', "")));
|
||||
to.setCacheControl(from.getFirstHeaderOrNull(HttpHeaders.CACHE_CONTROL));
|
||||
to.setContentDisposition(from.getFirstHeaderOrNull("Content-Disposition"));
|
||||
to.setContentEncoding(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_ENCODING));
|
||||
return to;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,8 +67,8 @@ public class AWSUtils {
|
|||
if (response.getPayload() == null)
|
||||
return null;
|
||||
// Eucalyptus and Walrus occasionally return text/plain
|
||||
if (response.getPayload().getContentType() != null
|
||||
&& response.getPayload().getContentType().indexOf("text/plain") != -1)
|
||||
if (response.getPayload().getContentMetadata().getContentType() != null
|
||||
&& response.getPayload().getContentMetadata().getContentType().indexOf("text/plain") != -1)
|
||||
return null;
|
||||
try {
|
||||
AWSError error = (AWSError) factory.create(errorHandlerProvider.get()).setContext(request)
|
||||
|
|
|
@ -90,7 +90,7 @@ public class BlobStoreAndComputeServiceLiveTest {
|
|||
protected void uploadBlob(String container, String name, String script) {
|
||||
Blob blob = blobContext.getBlobStore().newBlob(name);
|
||||
blob.setPayload(script);
|
||||
blob.getPayload().setContentType("text/plain");
|
||||
blob.getPayload().getContentMetadata().setContentType("text/plain");
|
||||
blobContext.getBlobStore().putBlob(container, blob);
|
||||
}
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ public class ParseAWSErrorFromXmlContentTest {
|
|||
HttpRequest request = new HttpRequest(method, uri);
|
||||
HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Utils
|
||||
.toInputStream(content)));
|
||||
response.getPayload().setContentType(contentType);
|
||||
response.getPayload().getContentMetadata().setContentType(contentType);
|
||||
|
||||
expect(command.getRequest()).andReturn(request).atLeastOnce();
|
||||
command.setException(classEq(expected));
|
||||
|
|
|
@ -270,7 +270,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest {
|
|||
protected String addBlobToContainer(String sourceContainer, String key) {
|
||||
S3Object sourceObject = getApi().newS3Object();
|
||||
sourceObject.getMetadata().setKey(key);
|
||||
sourceObject.getMetadata().setContentType("text/xml");
|
||||
sourceObject.getMetadata().getContentMetadata().setContentType("text/xml");
|
||||
sourceObject.setPayload(TEST_STRING);
|
||||
return getApi().putObject(sourceContainer, sourceObject);
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest {
|
|||
object.getMetadata().setKey(key);
|
||||
object.setPayload(TEST_STRING);
|
||||
object.getMetadata().setCacheControl("no-cache");
|
||||
object.getMetadata().setContentDisposition("attachment; filename=hello.txt");
|
||||
object.getMetadata().getContentMetadata().setContentDisposition("attachment; filename=hello.txt");
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
getApi().putObject(containerName, object);
|
||||
|
@ -299,7 +299,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest {
|
|||
S3Object newObject = validateObject(containerName, key);
|
||||
|
||||
assertEquals(newObject.getMetadata().getCacheControl(), "no-cache");
|
||||
assertEquals(newObject.getMetadata().getContentDisposition(),
|
||||
assertEquals(newObject.getMetadata().getContentMetadata().getContentDisposition(),
|
||||
"attachment; filename=hello.txt");
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
|
@ -313,13 +313,13 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest {
|
|||
S3Object object = getApi().newS3Object();
|
||||
object.getMetadata().setKey(key);
|
||||
object.setPayload(TEST_STRING);
|
||||
object.getMetadata().setContentEncoding("x-compress");
|
||||
object.getMetadata().getContentMetadata().setContentEncoding("x-compress");
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
getApi().putObject(containerName, object);
|
||||
S3Object newObject = validateObject(containerName, key);
|
||||
|
||||
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
|
||||
assertEquals(newObject.getMetadata().getContentMetadata().getContentEncoding(), "x-compress");
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public class BindBucketLoggingToXmlPayloadTest extends BaseHandlerTest {
|
|||
.getInstance(BindBucketLoggingToXmlPayload.class);
|
||||
|
||||
binder.bindToRequest(request, bucketLogging);
|
||||
assertEquals(request.getPayload().getContentType(), "text/xml");
|
||||
assertEquals(request.getPayload().getContentMetadata().getContentType(), "text/xml");
|
||||
assertEquals(request.getPayload().getRawContent(), expected);
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.jclouds.aws.s3.domain.S3Object;
|
|||
import org.jclouds.blobstore.binders.BindUserMetadataToHeadersWithPrefix;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.io.MutableContentMetadata;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -52,17 +53,19 @@ public class BindS3ObjectToPayloadTest {
|
|||
Payload payload = createMock(Payload.class);
|
||||
Blob blob = createMock(Blob.class);
|
||||
MutableObjectMetadata md = createMock(MutableObjectMetadata.class);
|
||||
MutableContentMetadata content = createMock(MutableContentMetadata.class);
|
||||
|
||||
expect(object.getPayload()).andReturn(payload).atLeastOnce();
|
||||
expect(payload.getContentLength()).andReturn(5368709120l).atLeastOnce();
|
||||
expect(payload.getContentMetadata()).andReturn(content).atLeastOnce();
|
||||
|
||||
expect(content.getContentLength()).andReturn(5368709120l).atLeastOnce();
|
||||
expect(object2Blob.apply(object)).andReturn(blob);
|
||||
mdBinder.bindToRequest(request, blob);
|
||||
expect(object.getMetadata()).andReturn(md).atLeastOnce();
|
||||
expect(md.getCacheControl()).andReturn(null).atLeastOnce();
|
||||
expect(md.getContentDisposition()).andReturn(null).atLeastOnce();
|
||||
expect(md.getContentEncoding()).andReturn(null).atLeastOnce();
|
||||
|
||||
replay(payload);
|
||||
replay(content);
|
||||
replay(mdBinder);
|
||||
replay(object2Blob);
|
||||
replay(request);
|
||||
|
@ -75,6 +78,7 @@ public class BindS3ObjectToPayloadTest {
|
|||
binder.bindToRequest(request, object);
|
||||
|
||||
verify(payload);
|
||||
verify(content);
|
||||
verify(mdBinder);
|
||||
verify(object2Blob);
|
||||
verify(request);
|
||||
|
@ -96,9 +100,11 @@ public class BindS3ObjectToPayloadTest {
|
|||
Blob blob = createMock(Blob.class);
|
||||
MutableObjectMetadata md = createMock(MutableObjectMetadata.class);
|
||||
Multimap<String, String> headers = createMock(Multimap.class);
|
||||
MutableContentMetadata content = createMock(MutableContentMetadata.class);
|
||||
|
||||
expect(object.getPayload()).andReturn(payload).atLeastOnce();
|
||||
expect(payload.getContentLength()).andReturn(5368709120l).atLeastOnce();
|
||||
expect(payload.getContentMetadata()).andReturn(content).atLeastOnce();
|
||||
expect(content.getContentLength()).andReturn(5368709120l).atLeastOnce();
|
||||
expect(object2Blob.apply(object)).andReturn(blob);
|
||||
mdBinder.bindToRequest(request, blob);
|
||||
expect(object.getMetadata()).andReturn(md).atLeastOnce();
|
||||
|
@ -106,15 +112,9 @@ public class BindS3ObjectToPayloadTest {
|
|||
expect(md.getCacheControl()).andReturn("no-cache").atLeastOnce();
|
||||
expect(headers.put("Cache-Control", "no-cache")).andReturn(true);
|
||||
|
||||
expect(md.getContentDisposition()).andReturn("attachment; filename=\"fname.ext\"")
|
||||
.atLeastOnce();
|
||||
expect(headers.put("Content-Disposition", "attachment; filename=\"fname.ext\"")).andReturn(true);
|
||||
|
||||
expect(md.getContentEncoding()).andReturn("gzip").atLeastOnce();
|
||||
expect(headers.put("Content-Encoding", "gzip")).andReturn(true);
|
||||
|
||||
replay(headers);
|
||||
replay(payload);
|
||||
replay(content);
|
||||
replay(mdBinder);
|
||||
replay(object2Blob);
|
||||
replay(request);
|
||||
|
@ -127,6 +127,7 @@ public class BindS3ObjectToPayloadTest {
|
|||
binder.bindToRequest(request, object);
|
||||
|
||||
verify(headers);
|
||||
verify(content);
|
||||
verify(payload);
|
||||
verify(mdBinder);
|
||||
verify(object2Blob);
|
||||
|
@ -147,17 +148,20 @@ public class BindS3ObjectToPayloadTest {
|
|||
Payload payload = createMock(Payload.class);
|
||||
Blob blob = createMock(Blob.class);
|
||||
MutableObjectMetadata md = createMock(MutableObjectMetadata.class);
|
||||
MutableContentMetadata content = createMock(MutableContentMetadata.class);
|
||||
|
||||
expect(object.getPayload()).andReturn(payload).atLeastOnce();
|
||||
expect(payload.getContentLength()).andReturn(5368709121l).atLeastOnce();
|
||||
expect(payload.getContentMetadata()).andReturn(content).atLeastOnce();
|
||||
expect(content.getContentLength()).andReturn(5368709121l).atLeastOnce();
|
||||
expect(object2Blob.apply(object)).andReturn(blob);
|
||||
mdBinder.bindToRequest(request, blob);
|
||||
expect(object.getMetadata()).andReturn(md).atLeastOnce();
|
||||
expect(md.getCacheControl()).andReturn(null).atLeastOnce();
|
||||
expect(md.getContentDisposition()).andReturn(null).atLeastOnce();
|
||||
expect(md.getContentEncoding()).andReturn(null).atLeastOnce();
|
||||
expect(content.getContentDisposition()).andReturn(null).atLeastOnce();
|
||||
expect(content.getContentEncoding()).andReturn(null).atLeastOnce();
|
||||
|
||||
replay(payload);
|
||||
replay(content);
|
||||
replay(mdBinder);
|
||||
replay(object2Blob);
|
||||
replay(request);
|
||||
|
@ -170,6 +174,7 @@ public class BindS3ObjectToPayloadTest {
|
|||
bindS3ObjectToPayload.bindToRequest(request, object);
|
||||
|
||||
verify(payload);
|
||||
verify(content);
|
||||
verify(mdBinder);
|
||||
verify(object2Blob);
|
||||
verify(request);
|
||||
|
|
|
@ -81,8 +81,10 @@ public class S3BlobRequestSignerTest extends RestClientTest<S3AsyncClient> {
|
|||
NoSuchMethodException, IOException {
|
||||
Blob blob = blobFactory.create(null);
|
||||
blob.getMetadata().setName("name");
|
||||
blob.setPayload(new PhantomPayload(2l, new byte[] { 0, 2, 4, 8 }));
|
||||
blob.getPayload().setContentType("text/plain");
|
||||
blob.setPayload(new PhantomPayload());
|
||||
blob.getPayload().getContentMetadata().setContentLength(2l);
|
||||
blob.getPayload().getContentMetadata().setContentMD5(new byte[] { 0, 2, 4, 8 });
|
||||
blob.getPayload().getContentMetadata().setContentType("text/plain");
|
||||
|
||||
HttpRequest request = signer.signPutBlob("container", blob);
|
||||
|
||||
|
|
|
@ -53,11 +53,11 @@ public class ParseObjectMetadataFromHeadersTest {
|
|||
@Test
|
||||
void testNormal() throws Exception {
|
||||
HttpResponse http = new HttpResponse(400, "boa", Payloads.newStringPayload(""));
|
||||
http.getPayload().setContentLength(1025l);
|
||||
http.getPayload().getContentMetadata().setContentLength(1025l);
|
||||
|
||||
http.getHeaders().put(HttpHeaders.CACHE_CONTROL, "cacheControl");
|
||||
http.getHeaders().put("Content-Disposition", "contentDisposition");
|
||||
http.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "encoding");
|
||||
http.getPayload().getContentMetadata().setContentDisposition("contentDisposition");
|
||||
http.getPayload().getContentMetadata().setContentEncoding("encoding");
|
||||
ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http, "\"abcd\""),
|
||||
blobToObjectMetadata, "x-amz-meta-");
|
||||
MutableObjectMetadata response = parser.apply(http);
|
||||
|
@ -68,11 +68,10 @@ public class ParseObjectMetadataFromHeadersTest {
|
|||
void testAmzEtag() throws Exception {
|
||||
|
||||
HttpResponse http = new HttpResponse(400, "boa", Payloads.newStringPayload(""));
|
||||
http.getPayload().setContentLength(1025l);
|
||||
|
||||
http.getPayload().getContentMetadata().setContentLength(1025l);
|
||||
http.getPayload().getContentMetadata().setContentDisposition("contentDisposition");
|
||||
http.getPayload().getContentMetadata().setContentEncoding("encoding");
|
||||
http.getHeaders().put(HttpHeaders.CACHE_CONTROL, "cacheControl");
|
||||
http.getHeaders().put("Content-Disposition", "contentDisposition");
|
||||
http.getHeaders().put(HttpHeaders.CONTENT_ENCODING, "encoding");
|
||||
http.getHeaders().put("x-amz-meta-object-eTag", "\"abcd\"");
|
||||
ParseObjectMetadataFromHeaders parser = new ParseObjectMetadataFromHeaders(blobParser(http, null),
|
||||
blobToObjectMetadata, "x-amz-meta-");
|
||||
|
@ -88,11 +87,14 @@ public class ParseObjectMetadataFromHeadersTest {
|
|||
private ParseSystemAndUserMetadataFromHeaders blobParser(HttpResponse response, String etag) {
|
||||
ParseSystemAndUserMetadataFromHeaders parser = createMock(ParseSystemAndUserMetadataFromHeaders.class);
|
||||
MutableBlobMetadata md = new MutableBlobMetadataImpl();
|
||||
md.setContentType("type");
|
||||
md.getContentMetadata().setContentType("type");
|
||||
md.setETag(etag);
|
||||
md.setName("key");
|
||||
md.setLastModified(now);
|
||||
md.setSize(1025l);
|
||||
md.getContentMetadata().setContentLength(1025l);
|
||||
md.getContentMetadata().setContentDisposition("contentDisposition");
|
||||
md.getContentMetadata().setContentEncoding("encoding");
|
||||
md.getContentMetadata().setContentMD5(CryptoStreams.hex("abcd"));
|
||||
md.setUserMetadata(userMetadata);
|
||||
expect(parser.apply(response)).andReturn(md);
|
||||
replay(parser);
|
||||
|
@ -104,15 +106,15 @@ public class ParseObjectMetadataFromHeadersTest {
|
|||
blobToObjectMetadata = new BlobToObjectMetadata();
|
||||
expects = new MutableObjectMetadataImpl();
|
||||
expects.setCacheControl("cacheControl");
|
||||
expects.setContentDisposition("contentDisposition");
|
||||
expects.setContentEncoding("encoding");
|
||||
expects.setContentMD5(CryptoStreams.hex("abcd"));
|
||||
expects.setContentType("type");
|
||||
expects.getContentMetadata().setContentDisposition("contentDisposition");
|
||||
expects.getContentMetadata().setContentEncoding("encoding");
|
||||
expects.getContentMetadata().setContentMD5(CryptoStreams.hex("abcd"));
|
||||
expects.getContentMetadata().setContentType("type");
|
||||
expects.getContentMetadata().setContentLength(1025l);
|
||||
expects.setETag("\"abcd\"");
|
||||
expects.setKey("key");
|
||||
expects.setLastModified(now);
|
||||
expects.setOwner(null);
|
||||
expects.setSize(1025l);
|
||||
expects.setStorageClass(StorageClass.STANDARD);
|
||||
expects.setUserMetadata(userMetadata);
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ public class S3ParserTest extends PerformanceTest {
|
|||
assert object.getLastModified().equals(expected) : String.format("expected %1$s, but got %1$s", expected, object
|
||||
.getLastModified());
|
||||
assertEquals(object.getETag(), "\"9d7bb64e8e18ee34eec06dd2cf37b766\"");
|
||||
assert object.getSize() == 136;
|
||||
assert object.getContentMetadata().getContentLength() == 136;
|
||||
CanonicalUser owner = new CanonicalUser("e1a5f66a480ca99a4fdfe8e318c3020446c9989d7004e7778029fbcc5d990fa0");
|
||||
owner.setDisplayName("ferncam");
|
||||
assert object.getOwner().equals(owner);
|
||||
|
|
|
@ -73,7 +73,7 @@ public class AWSUtilsTest {
|
|||
|
||||
HttpResponse response(InputStream content) {
|
||||
HttpResponse response = new HttpResponse(400, "boa", Payloads.newInputStreamPayload(content));
|
||||
response.getPayload().setContentType("text/xml");
|
||||
response.getPayload().getContentMetadata().setContentType("text/xml");
|
||||
response.getHeaders().put("x-amz-request-id", "requestid");
|
||||
response.getHeaders().put("x-amz-id-2", "requesttoken");
|
||||
return response;
|
||||
|
|
|
@ -39,40 +39,27 @@ public class BindAzureBlobToPayload implements Binder {
|
|||
private final BindUserMetadataToHeadersWithPrefix blobBinder;
|
||||
|
||||
@Inject
|
||||
public BindAzureBlobToPayload(AzureBlobToBlob azureBlob2Blob,
|
||||
BindUserMetadataToHeadersWithPrefix blobBinder) {
|
||||
public BindAzureBlobToPayload(AzureBlobToBlob azureBlob2Blob, BindUserMetadataToHeadersWithPrefix blobBinder) {
|
||||
this.azureBlob2Blob = azureBlob2Blob;
|
||||
this.blobBinder = blobBinder;
|
||||
}
|
||||
|
||||
public void bindToRequest(HttpRequest request, Object payload) {
|
||||
AzureBlob blob = (AzureBlob) payload;
|
||||
checkArgument(blob.getPayload().getContentLength() >= 0, "size must be set");
|
||||
checkArgument(blob.getPayload().getContentMetadata().getContentLength() >= 0, "size must be set");
|
||||
request.getHeaders().put("x-ms-blob-type", blob.getProperties().getType().toString());
|
||||
|
||||
switch (blob.getProperties().getType()) {
|
||||
case PAGE_BLOB:
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, "0");
|
||||
request.getHeaders().put("x-ms-blob-content-length",
|
||||
blob.getPayload().getContentLength().toString());
|
||||
blob.getPayload().getContentMetadata().getContentLength().toString());
|
||||
break;
|
||||
case BLOCK_BLOB:
|
||||
checkArgument(checkNotNull(blob.getPayload().getContentLength(),
|
||||
"blob.getContentLength()") <= 64l * 1024 * 1024,
|
||||
"maximum size for put Blob is 64MB");
|
||||
checkArgument(checkNotNull(blob.getPayload().getContentMetadata().getContentLength(),
|
||||
"blob.getContentLength()") <= 64l * 1024 * 1024, "maximum size for put Blob is 64MB");
|
||||
break;
|
||||
}
|
||||
blobBinder.bindToRequest(request, azureBlob2Blob.apply(blob));
|
||||
|
||||
if (blob.getProperties().getContentLanguage() != null) {
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_LANGUAGE,
|
||||
blob.getProperties().getContentLanguage());
|
||||
}
|
||||
|
||||
if (blob.getProperties().getContentEncoding() != null) {
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_ENCODING,
|
||||
blob.getProperties().getContentEncoding());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.internal.MutableBlobPropertiesImpl;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
@ -38,13 +39,10 @@ public class BlobMetadataToBlobProperties implements Function<BlobMetadata, Muta
|
|||
if (from == null)
|
||||
return null;
|
||||
MutableBlobProperties to = new MutableBlobPropertiesImpl();
|
||||
to.setContentType(from.getContentType());
|
||||
HttpUtils.copy(from.getContentMetadata(), to.getContentMetadata());
|
||||
to.setETag(from.getETag());
|
||||
to.setContentMD5(from.getContentMD5());
|
||||
to.setName(from.getName());
|
||||
to.setLastModified(from.getLastModified());
|
||||
if (from.getSize() != null)
|
||||
to.setContentLength(from.getSize());
|
||||
if (from.getUserMetadata() != null) {
|
||||
for (Entry<String, String> entry : from.getUserMetadata().entrySet())
|
||||
to.getMetadata().put(entry.getKey().toLowerCase(), entry.getValue());
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
|||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
import org.jclouds.blobstore.strategy.IfDirectoryReturnNameStrategy;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
@ -46,15 +47,11 @@ public class BlobPropertiesToBlobMetadata implements Function<BlobProperties, Mu
|
|||
if (from == null)
|
||||
return null;
|
||||
MutableBlobMetadata to = new MutableBlobMetadataImpl();
|
||||
if (from.getContentMD5() != null)
|
||||
to.setContentMD5(from.getContentMD5());
|
||||
if (from.getContentType() != null)
|
||||
to.setContentType(from.getContentType());
|
||||
HttpUtils.copy(from.getContentMetadata(), to.getContentMetadata());
|
||||
to.setUserMetadata(from.getMetadata());
|
||||
to.setETag(from.getETag());
|
||||
to.setLastModified(from.getLastModified());
|
||||
to.setName(from.getName());
|
||||
to.setSize(from.getContentLength());
|
||||
String directoryName = ifDirectoryReturnName.execute(to);
|
||||
if (directoryName != null) {
|
||||
to.setName(directoryName);
|
||||
|
|
|
@ -60,7 +60,7 @@ public class FindMD5InBlobProperties implements ContainsValueInListStrategy {
|
|||
byte[] toSearch = objectMD5.apply(value);
|
||||
for (BlobMetadata metadata : getAllBlobMetadata.execute(containerName, options)) {
|
||||
BlobProperties properties = client.getBlobProperties(containerName, metadata.getName());
|
||||
if (Arrays.equals(toSearch, properties.getContentMD5()))
|
||||
if (Arrays.equals(toSearch, properties.getContentMetadata().getContentMD5()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -23,6 +23,8 @@ import java.net.URI;
|
|||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
|
@ -47,31 +49,6 @@ public interface BlobProperties extends Comparable<BlobProperties> {
|
|||
|
||||
String getETag();
|
||||
|
||||
Long getContentLength();
|
||||
ContentMetadata getContentMetadata();
|
||||
|
||||
/**
|
||||
* This value present in system metadata requests on blobs which were created specifying the
|
||||
* Content-MD5 header.
|
||||
*/
|
||||
byte[] getContentMD5();
|
||||
|
||||
/**
|
||||
*
|
||||
* 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"/>
|
||||
*/
|
||||
String getContentType();
|
||||
|
||||
/**
|
||||
* Specifies what content encodings have been applied to the object and thus what decoding
|
||||
* mechanisms must be applied in order to obtain the media-type referenced by the Content-Type
|
||||
* header field.
|
||||
*
|
||||
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11" />
|
||||
*/
|
||||
public String getContentEncoding();
|
||||
|
||||
public String getContentLanguage();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Date;
|
|||
import java.util.Map;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.internal.MutableBlobPropertiesImpl;
|
||||
import org.jclouds.io.MutableContentMetadata;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
|
@ -54,30 +55,9 @@ public interface MutableBlobProperties extends BlobProperties {
|
|||
*/
|
||||
void setETag(String eTag);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#getContentLength
|
||||
*/
|
||||
void setContentLength(Long size);
|
||||
MutableContentMetadata getContentMetadata();
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#getContentMD5
|
||||
*/
|
||||
void setContentMD5(byte[] md5);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#getContentType
|
||||
*/
|
||||
void setContentType(String contentType);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#getContentEncoding
|
||||
*/
|
||||
void setContentEncoding(String contentEncoding);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#getContentLanguage
|
||||
*/
|
||||
void setContentLanguage(String contentLanguage);
|
||||
void setContentMetadata(MutableContentMetadata md);
|
||||
|
||||
/**
|
||||
* @see ListableContainerProperties#getMetadata
|
||||
|
|
|
@ -27,8 +27,6 @@ import org.jclouds.azure.storage.blob.domain.AzureBlob;
|
|||
import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
|
||||
import org.jclouds.http.internal.PayloadEnclosingImpl;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.PayloadEnclosing;
|
||||
import org.jclouds.io.payloads.DelegatingPayload;
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
@ -40,15 +38,13 @@ import com.google.common.collect.Multimap;
|
|||
*/
|
||||
public class AzureBlobImpl extends PayloadEnclosingImpl implements AzureBlob, Comparable<AzureBlob> {
|
||||
|
||||
private final MutableBlobProperties _properties;
|
||||
private final SetPayloadPropertiesMutableBlobProperties properties;
|
||||
private final MutableBlobProperties properties;
|
||||
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
|
||||
|
||||
@Inject
|
||||
public AzureBlobImpl(MutableBlobProperties properties) {
|
||||
super();
|
||||
this.properties = linkMetadataToThis(properties);
|
||||
this._properties = this.properties.getDelegate();
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,7 +85,7 @@ public class AzureBlobImpl extends PayloadEnclosingImpl implements AzureBlob, Co
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((_properties == null) ? 0 : _properties.hashCode());
|
||||
result = prime * result + ((properties == null) ? 0 : properties.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -102,83 +98,23 @@ public class AzureBlobImpl extends PayloadEnclosingImpl implements AzureBlob, Co
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
AzureBlobImpl other = (AzureBlobImpl) obj;
|
||||
if (_properties == null) {
|
||||
if (other._properties != null)
|
||||
if (properties == null) {
|
||||
if (other.properties != null)
|
||||
return false;
|
||||
} else if (!_properties.equals(other._properties))
|
||||
} else if (!properties.equals(other.properties))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[properties=" + _properties + "]";
|
||||
return "[properties=" + properties + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPayload(Payload data) {
|
||||
linkPayloadToMetadata(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* link the new payload to the properties object so that when content-related properties is
|
||||
* updated on the payload, it is also copied the properties object.
|
||||
*/
|
||||
void linkPayloadToMetadata(Payload data) {
|
||||
if (data instanceof DelegatingPayload)
|
||||
super.setPayload(new SetMetadataPropertiesPayload(DelegatingPayload.class.cast(data)
|
||||
.getDelegate(), _properties));
|
||||
else
|
||||
super.setPayload(new SetMetadataPropertiesPayload(data, _properties));
|
||||
}
|
||||
|
||||
static class SetMetadataPropertiesPayload extends DelegatingPayload {
|
||||
|
||||
private transient final MutableBlobProperties properties;
|
||||
|
||||
public SetMetadataPropertiesPayload(Payload delegate, MutableBlobProperties properties) {
|
||||
super(delegate);
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String md5) {
|
||||
super.setContentType(md5);
|
||||
properties.setContentType(md5);
|
||||
super.setPayload(data);
|
||||
properties.setContentMetadata(data.getContentMetadata());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* link the properties object to this so that when content-related properties is updated, it is
|
||||
* also copied the currentpayload object.
|
||||
*/
|
||||
SetPayloadPropertiesMutableBlobProperties linkMetadataToThis(MutableBlobProperties properties) {
|
||||
return properties instanceof DelegatingMutableBlobProperties ? new SetPayloadPropertiesMutableBlobProperties(
|
||||
DelegatingMutableBlobProperties.class.cast(properties).getDelegate(), this)
|
||||
: new SetPayloadPropertiesMutableBlobProperties(properties, this);
|
||||
}
|
||||
|
||||
static class SetPayloadPropertiesMutableBlobProperties extends DelegatingMutableBlobProperties {
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -5072270546219814521L;
|
||||
private transient final PayloadEnclosing blob;
|
||||
|
||||
public SetPayloadPropertiesMutableBlobProperties(MutableBlobProperties delegate,
|
||||
PayloadEnclosing blob) {
|
||||
super(delegate);
|
||||
this.blob = blob;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String type) {
|
||||
super.setContentType(type);
|
||||
if (canSetPayload())
|
||||
blob.getPayload().setContentType(type);
|
||||
}
|
||||
|
||||
private boolean canSetPayload() {
|
||||
return blob != null && blob.getPayload() != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,13 +23,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobType;
|
||||
import org.jclouds.azure.storage.blob.domain.LeaseStatus;
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
import org.jclouds.io.payloads.BaseImmutableContentMetadata;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
@ -48,40 +49,24 @@ public class BlobPropertiesImpl implements Serializable, BlobProperties {
|
|||
private final URI url;
|
||||
private final Date lastModified;
|
||||
private final String eTag;
|
||||
private final long size;
|
||||
private final String contentType;
|
||||
private final byte[] contentMD5;
|
||||
private final String contentEncoding;
|
||||
private final String contentLanguage;
|
||||
private final Map<String, String> metadata = Maps.newLinkedHashMap();
|
||||
private final LeaseStatus leaseStatus;
|
||||
private final BaseImmutableContentMetadata contentMetadata;
|
||||
|
||||
public BlobPropertiesImpl(BlobType type, String name, URI url, Date lastModified, String eTag,
|
||||
long size, String contentType, @Nullable byte[] contentMD5,
|
||||
@Nullable String contentEncoding, @Nullable String contentLanguage,
|
||||
LeaseStatus leaseStatus, Map<String, String> metadata) {
|
||||
public BlobPropertiesImpl(BlobType type, String name, URI url, Date lastModified, String eTag, long size,
|
||||
String contentType, @Nullable byte[] contentMD5, @Nullable String contentMetadata,
|
||||
@Nullable String contentLanguage, LeaseStatus leaseStatus, Map<String, String> metadata) {
|
||||
this.type = checkNotNull(type, "type");
|
||||
this.leaseStatus = checkNotNull(leaseStatus, "leaseStatus");
|
||||
this.name = checkNotNull(name, "name");
|
||||
this.url = checkNotNull(url, "url");
|
||||
this.lastModified = checkNotNull(lastModified, "lastModified");
|
||||
this.eTag = checkNotNull(eTag, "eTag");
|
||||
this.size = size;
|
||||
this.contentType = checkNotNull(contentType, "contentType");
|
||||
this.contentMD5 = contentMD5;
|
||||
this.contentEncoding = contentEncoding;
|
||||
this.contentLanguage = contentLanguage;
|
||||
this.contentMetadata = new BaseImmutableContentMetadata(contentType, size, contentMD5, null, contentLanguage,
|
||||
contentMetadata);
|
||||
this.metadata.putAll(checkNotNull(metadata, "metadata"));
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public byte[] getContentMD5() {
|
||||
return contentMD5;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -98,22 +83,6 @@ public class BlobPropertiesImpl implements Serializable, BlobProperties {
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentEncoding() {
|
||||
return contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -130,14 +99,6 @@ public class BlobPropertiesImpl implements Serializable, BlobProperties {
|
|||
return eTag;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Long getContentLength() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -154,14 +115,6 @@ public class BlobPropertiesImpl implements Serializable, BlobProperties {
|
|||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentLanguage() {
|
||||
return contentLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -178,20 +131,24 @@ public class BlobPropertiesImpl implements Serializable, BlobProperties {
|
|||
return leaseStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public ContentMetadata getContentMetadata() {
|
||||
return contentMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((contentEncoding == null) ? 0 : contentEncoding.hashCode());
|
||||
result = prime * result + ((contentLanguage == null) ? 0 : contentLanguage.hashCode());
|
||||
result = prime * result + Arrays.hashCode(contentMD5);
|
||||
result = prime * result + ((contentType == null) ? 0 : contentType.hashCode());
|
||||
result = prime * result + ((contentMetadata == null) ? 0 : contentMetadata.hashCode());
|
||||
result = prime * result + ((eTag == null) ? 0 : eTag.hashCode());
|
||||
result = prime * result + ((lastModified == null) ? 0 : lastModified.hashCode());
|
||||
result = prime * result + ((leaseStatus == null) ? 0 : leaseStatus.hashCode());
|
||||
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + (int) (size ^ (size >>> 32));
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
result = prime * result + ((url == null) ? 0 : url.hashCode());
|
||||
return result;
|
||||
|
@ -206,22 +163,10 @@ public class BlobPropertiesImpl implements Serializable, BlobProperties {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
BlobPropertiesImpl other = (BlobPropertiesImpl) obj;
|
||||
if (contentEncoding == null) {
|
||||
if (other.contentEncoding != null)
|
||||
if (contentMetadata == null) {
|
||||
if (other.contentMetadata != null)
|
||||
return false;
|
||||
} else if (!contentEncoding.equals(other.contentEncoding))
|
||||
return false;
|
||||
if (contentLanguage == null) {
|
||||
if (other.contentLanguage != null)
|
||||
return false;
|
||||
} else if (!contentLanguage.equals(other.contentLanguage))
|
||||
return false;
|
||||
if (!Arrays.equals(contentMD5, other.contentMD5))
|
||||
return false;
|
||||
if (contentType == null) {
|
||||
if (other.contentType != null)
|
||||
return false;
|
||||
} else if (!contentType.equals(other.contentType))
|
||||
} else if (!contentMetadata.equals(other.contentMetadata))
|
||||
return false;
|
||||
if (eTag == null) {
|
||||
if (other.eTag != null)
|
||||
|
@ -248,8 +193,6 @@ public class BlobPropertiesImpl implements Serializable, BlobProperties {
|
|||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (size != other.size)
|
||||
return false;
|
||||
if (type == null) {
|
||||
if (other.type != null)
|
||||
return false;
|
||||
|
@ -265,8 +208,8 @@ public class BlobPropertiesImpl implements Serializable, BlobProperties {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[name=" + name + ", type=" + type + ", contentType=" + contentType
|
||||
+ ", eTag=" + eTag + ", lastModified=" + lastModified + ", size=" + size + "]";
|
||||
return "[name=" + name + ", type=" + type + ", contentMetadata=" + contentMetadata + ", eTag=" + eTag
|
||||
+ ", lastModified=" + lastModified + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,186 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.azure.storage.blob.domain.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.BlobType;
|
||||
import org.jclouds.azure.storage.blob.domain.LeaseStatus;
|
||||
import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
|
||||
|
||||
/**
|
||||
* Allows you to manipulate metadata.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class DelegatingMutableBlobProperties implements Serializable, MutableBlobProperties {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = 9136392820647068818L;
|
||||
|
||||
private final MutableBlobProperties delegate;
|
||||
|
||||
public DelegatingMutableBlobProperties(MutableBlobProperties delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(BlobProperties o) {
|
||||
return delegate.compareTo(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return delegate.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentEncoding() {
|
||||
return delegate.getContentEncoding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentLanguage() {
|
||||
return delegate.getContentLanguage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getContentLength() {
|
||||
return delegate.getContentLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getContentMD5() {
|
||||
return delegate.getContentMD5();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return delegate.getContentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getETag() {
|
||||
return delegate.getETag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getLastModified() {
|
||||
return delegate.getLastModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaseStatus getLeaseStatus() {
|
||||
return delegate.getLeaseStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMetadata() {
|
||||
return delegate.getMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return delegate.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlobType getType() {
|
||||
return delegate.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getUrl() {
|
||||
return delegate.getUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentEncoding(String encoding) {
|
||||
delegate.setContentEncoding(encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentLanguage(String contentLanguage) {
|
||||
delegate.setContentLanguage(contentLanguage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentLength(Long size) {
|
||||
delegate.setContentLength(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentMD5(byte[] md5) {
|
||||
delegate.setContentMD5(md5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String contentType) {
|
||||
delegate.setContentType(contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setETag(String eTag) {
|
||||
delegate.setETag(eTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastModified(Date lastModified) {
|
||||
delegate.setLastModified(lastModified);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetadata(Map<String, String> metadata) {
|
||||
delegate.setMetadata(metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
delegate.setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUrl(URI url) {
|
||||
delegate.setUrl(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
public static long getSerialversionuid() {
|
||||
return serialVersionUID;
|
||||
}
|
||||
|
||||
public MutableBlobProperties getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,6 @@ package org.jclouds.azure.storage.blob.domain.internal;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -29,6 +28,9 @@ import org.jclouds.azure.storage.blob.domain.BlobProperties;
|
|||
import org.jclouds.azure.storage.blob.domain.BlobType;
|
||||
import org.jclouds.azure.storage.blob.domain.LeaseStatus;
|
||||
import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.io.MutableContentMetadata;
|
||||
import org.jclouds.io.payloads.BaseMutableContentMetadata;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
|
@ -49,14 +51,17 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
private URI url;
|
||||
private Date lastModified;
|
||||
private String eTag;
|
||||
private Long size;
|
||||
private String contentType;
|
||||
private byte[] contentMD5;
|
||||
private String contentEncoding;
|
||||
private String contentLanguage;
|
||||
private MutableContentMetadata contentMetadata;
|
||||
private Map<String, String> metadata = Maps.newHashMap();
|
||||
|
||||
public MutableBlobPropertiesImpl() {
|
||||
super();
|
||||
this.contentMetadata = new BaseMutableContentMetadata();
|
||||
}
|
||||
|
||||
public MutableBlobPropertiesImpl(BlobProperties from) {
|
||||
this.contentMetadata = new BaseMutableContentMetadata();
|
||||
HttpUtils.copy(from.getContentMetadata(), this.contentMetadata);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,20 +85,6 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentEncoding() {
|
||||
return contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -108,13 +99,6 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
return eTag;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public Long getContentLength() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -129,37 +113,6 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setContentEncoding(String encoding) {
|
||||
this.contentEncoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setContentMD5(byte[] md5) {
|
||||
if (md5 != null) {
|
||||
byte[] retval = new byte[md5.length];
|
||||
System.arraycopy(md5, 0, retval, 0, md5.length);
|
||||
this.contentMD5 = md5;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -168,13 +121,6 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
return leaseStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -196,13 +142,6 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
public void setContentLength(Long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
*{@inheritDoc}
|
||||
*/
|
||||
|
@ -210,18 +149,10 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
public void setContentLanguage(String contentLanguage) {
|
||||
this.contentLanguage = contentLanguage;
|
||||
}
|
||||
|
||||
public void setUrl(URI url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getContentLanguage() {
|
||||
return contentLanguage;
|
||||
}
|
||||
|
||||
public URI getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
@ -230,15 +161,11 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((contentEncoding == null) ? 0 : contentEncoding.hashCode());
|
||||
result = prime * result + ((contentLanguage == null) ? 0 : contentLanguage.hashCode());
|
||||
result = prime * result + Arrays.hashCode(contentMD5);
|
||||
result = prime * result + ((contentType == null) ? 0 : contentType.hashCode());
|
||||
result = prime * result + ((contentMetadata == null) ? 0 : contentMetadata.hashCode());
|
||||
result = prime * result + ((eTag == null) ? 0 : eTag.hashCode());
|
||||
result = prime * result + ((lastModified == null) ? 0 : lastModified.hashCode());
|
||||
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + (int) (size ^ (size >>> 32));
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
result = prime * result + ((url == null) ? 0 : url.hashCode());
|
||||
return result;
|
||||
|
@ -253,22 +180,10 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
MutableBlobPropertiesImpl other = (MutableBlobPropertiesImpl) obj;
|
||||
if (contentEncoding == null) {
|
||||
if (other.contentEncoding != null)
|
||||
if (contentMetadata == null) {
|
||||
if (other.contentMetadata != null)
|
||||
return false;
|
||||
} else if (!contentEncoding.equals(other.contentEncoding))
|
||||
return false;
|
||||
if (contentLanguage == null) {
|
||||
if (other.contentLanguage != null)
|
||||
return false;
|
||||
} else if (!contentLanguage.equals(other.contentLanguage))
|
||||
return false;
|
||||
if (!Arrays.equals(contentMD5, other.contentMD5))
|
||||
return false;
|
||||
if (contentType == null) {
|
||||
if (other.contentType != null)
|
||||
return false;
|
||||
} else if (!contentType.equals(other.contentType))
|
||||
} else if (!contentMetadata.equals(other.contentMetadata))
|
||||
return false;
|
||||
if (eTag == null) {
|
||||
if (other.eTag != null)
|
||||
|
@ -290,8 +205,6 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (size != other.size)
|
||||
return false;
|
||||
if (type == null) {
|
||||
if (other.type != null)
|
||||
return false;
|
||||
|
@ -310,4 +223,21 @@ public class MutableBlobPropertiesImpl implements Serializable, MutableBlobPrope
|
|||
return "[name=" + name + ", type=" + type + ", lastModified=" + lastModified + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MutableContentMetadata getContentMetadata() {
|
||||
return contentMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setContentMetadata(MutableContentMetadata contentMetadata) {
|
||||
this.contentMetadata = contentMetadata;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -19,10 +19,7 @@
|
|||
|
||||
package org.jclouds.azure.storage.blob.functions;
|
||||
|
||||
import static org.jclouds.http.HttpUtils.attemptToParseSizeAndRangeFromHeaders;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.azure.storage.blob.blobstore.functions.BlobMetadataToBlobProperties;
|
||||
import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
|
||||
|
@ -41,8 +38,7 @@ import com.google.common.base.Function;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ParseBlobPropertiesFromHeaders implements
|
||||
Function<HttpResponse, MutableBlobProperties>, InvocationContext {
|
||||
public class ParseBlobPropertiesFromHeaders implements Function<HttpResponse, MutableBlobProperties>, InvocationContext {
|
||||
private final ParseSystemAndUserMetadataFromHeaders blobMetadataParser;
|
||||
private final BlobMetadataToBlobProperties blobToBlobProperties;
|
||||
|
||||
|
@ -59,9 +55,6 @@ public class ParseBlobPropertiesFromHeaders implements
|
|||
public MutableBlobProperties apply(HttpResponse from) {
|
||||
BlobMetadata base = blobMetadataParser.apply(from);
|
||||
MutableBlobProperties to = blobToBlobProperties.apply(base);
|
||||
to.setContentLength(attemptToParseSizeAndRangeFromHeaders(from));
|
||||
to.setContentLanguage(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_LANGUAGE));
|
||||
to.setContentEncoding(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_ENCODING));
|
||||
return to;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,9 +103,9 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
|
|||
}
|
||||
|
||||
private void appendPayloadMetadata(HttpRequest request, StringBuilder buffer) {
|
||||
buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentMD5()))
|
||||
buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentMetadata().getContentMD5()))
|
||||
.append("\n");
|
||||
buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentType()))
|
||||
buffer.append(utils.valueOrEmpty(request.getPayload() == null ? null : request.getPayload().getContentMetadata().getContentType()))
|
||||
.append("\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -229,11 +229,12 @@ public class AzureBlobClientLiveTest {
|
|||
object.getProperties().setName("object");
|
||||
object.setPayload(data);
|
||||
Payloads.calculateMD5(object);
|
||||
object.getProperties().setContentType("text/plain");
|
||||
object.getProperties().getContentMetadata().setContentType("text/plain");
|
||||
object.getProperties().getMetadata().put("mykey", "metadata-value");
|
||||
byte[] md5 = object.getProperties().getContentMD5();
|
||||
byte[] md5 = object.getProperties().getContentMetadata().getContentMD5();
|
||||
String newEtag = client.putBlob(privateContainer, object);
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(object.getProperties().getContentMD5()));
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(object.getProperties().getContentMetadata()
|
||||
.getContentMD5()));
|
||||
|
||||
// Test HEAD of missing object
|
||||
assert client.getBlobProperties(privateContainer, "non-existent-object") == null;
|
||||
|
@ -247,9 +248,10 @@ public class AzureBlobClientLiveTest {
|
|||
// inexpensive fashion
|
||||
// http://code.google.com/p/jclouds/issues/detail?id=92
|
||||
// assertEquals(metadata.getSize(), data.length());
|
||||
assertEquals(metadata.getContentType(), "text/plain");
|
||||
assertEquals(metadata.getContentMetadata().getContentType(), "text/plain");
|
||||
// Azure doesn't return the Content-MD5 on head request..
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(object.getProperties().getContentMD5()));
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(object.getProperties().getContentMetadata()
|
||||
.getContentMD5()));
|
||||
assertEquals(metadata.getETag(), newEtag);
|
||||
assertEquals(metadata.getMetadata().entrySet().size(), 1);
|
||||
assertEquals(metadata.getMetadata().get("mykey"), "metadata-value");
|
||||
|
@ -268,9 +270,10 @@ public class AzureBlobClientLiveTest {
|
|||
AzureBlob getBlob = client.getBlob(privateContainer, object.getProperties().getName());
|
||||
assertEquals(Utils.toStringAndClose(getBlob.getPayload().getInput()), data);
|
||||
// TODO assertEquals(getBlob.getName(), object.getProperties().getName());
|
||||
assertEquals(getBlob.getPayload().getContentLength(), new Long(data.length()));
|
||||
assertEquals(getBlob.getProperties().getContentType(), "text/plain");
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getProperties().getContentMD5()));
|
||||
assertEquals(getBlob.getPayload().getContentMetadata().getContentLength(), new Long(data.length()));
|
||||
assertEquals(getBlob.getProperties().getContentMetadata().getContentType(), "text/plain");
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getProperties().getContentMetadata()
|
||||
.getContentMD5()));
|
||||
assertEquals(newEtag, getBlob.getProperties().getETag());
|
||||
// wait until we can update metadata
|
||||
// assertEquals(getBlob.getProperties().getMetadata().entries().size(), 2);
|
||||
|
@ -306,9 +309,10 @@ public class AzureBlobClientLiveTest {
|
|||
object = client.newBlob();
|
||||
object.getProperties().setName("chunked-object");
|
||||
object.setPayload(bais);
|
||||
object.getPayload().setContentLength(new Long(data.getBytes().length));
|
||||
object.getPayload().getContentMetadata().setContentLength(new Long(data.getBytes().length));
|
||||
newEtag = client.putBlob(privateContainer, object);
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getProperties().getContentMD5()));
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getProperties().getContentMetadata()
|
||||
.getContentMD5()));
|
||||
|
||||
// Test GET with options
|
||||
// Non-matching ETag
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.jclouds.azure.storage.blob.domain.MutableBlobProperties;
|
|||
import org.jclouds.blobstore.binders.BindUserMetadataToHeadersWithPrefix;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.io.MutableContentMetadata;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -55,9 +56,11 @@ public class BindAzureBlobToPayloadTest {
|
|||
Blob blob = createMock(Blob.class);
|
||||
MutableBlobProperties md = createMock(MutableBlobProperties.class);
|
||||
Multimap<String, String> headers = createMock(Multimap.class);
|
||||
MutableContentMetadata content = createMock(MutableContentMetadata.class);
|
||||
|
||||
expect(object.getPayload()).andReturn(payload).atLeastOnce();
|
||||
expect(payload.getContentLength()).andReturn(1024l).atLeastOnce();
|
||||
expect(payload.getContentMetadata()).andReturn(content).atLeastOnce();
|
||||
expect(content.getContentLength()).andReturn(1024l).atLeastOnce();
|
||||
expect(object2Blob.apply(object)).andReturn(blob);
|
||||
mdBinder.bindToRequest(request, blob);
|
||||
expect(object.getProperties()).andReturn(md).atLeastOnce();
|
||||
|
@ -65,10 +68,8 @@ public class BindAzureBlobToPayloadTest {
|
|||
expect(request.getHeaders()).andReturn(headers).atLeastOnce();
|
||||
expect(headers.put("x-ms-blob-type", "BlockBlob")).andReturn(true);
|
||||
|
||||
expect(md.getContentLanguage()).andReturn(null).atLeastOnce();
|
||||
expect(md.getContentEncoding()).andReturn(null).atLeastOnce();
|
||||
|
||||
replay(headers);
|
||||
replay(content);
|
||||
replay(payload);
|
||||
replay(mdBinder);
|
||||
replay(object2Blob);
|
||||
|
@ -82,6 +83,7 @@ public class BindAzureBlobToPayloadTest {
|
|||
binder.bindToRequest(request, object);
|
||||
|
||||
verify(headers);
|
||||
verify(content);
|
||||
verify(payload);
|
||||
verify(mdBinder);
|
||||
verify(object2Blob);
|
||||
|
@ -104,9 +106,11 @@ public class BindAzureBlobToPayloadTest {
|
|||
Blob blob = createMock(Blob.class);
|
||||
MutableBlobProperties md = createMock(MutableBlobProperties.class);
|
||||
Multimap<String, String> headers = createMock(Multimap.class);
|
||||
MutableContentMetadata content = createMock(MutableContentMetadata.class);
|
||||
|
||||
expect(object.getPayload()).andReturn(payload).atLeastOnce();
|
||||
expect(payload.getContentLength()).andReturn(1024l).atLeastOnce();
|
||||
expect(payload.getContentMetadata()).andReturn(content).atLeastOnce();
|
||||
expect(content.getContentLength()).andReturn(1024l).atLeastOnce();
|
||||
expect(object2Blob.apply(object)).andReturn(blob);
|
||||
mdBinder.bindToRequest(request, blob);
|
||||
expect(object.getProperties()).andReturn(md).atLeastOnce();
|
||||
|
@ -114,14 +118,9 @@ public class BindAzureBlobToPayloadTest {
|
|||
expect(request.getHeaders()).andReturn(headers).atLeastOnce();
|
||||
expect(headers.put("x-ms-blob-type", "BlockBlob")).andReturn(true);
|
||||
|
||||
expect(md.getContentLanguage()).andReturn("en").atLeastOnce();
|
||||
expect(headers.put("Content-Language", "en")).andReturn(true);
|
||||
|
||||
expect(md.getContentEncoding()).andReturn("gzip").atLeastOnce();
|
||||
expect(headers.put("Content-Encoding", "gzip")).andReturn(true);
|
||||
|
||||
replay(headers);
|
||||
replay(payload);
|
||||
replay(content);
|
||||
replay(mdBinder);
|
||||
replay(object2Blob);
|
||||
replay(request);
|
||||
|
@ -135,6 +134,7 @@ public class BindAzureBlobToPayloadTest {
|
|||
|
||||
verify(headers);
|
||||
verify(payload);
|
||||
verify(content);
|
||||
verify(mdBinder);
|
||||
verify(object2Blob);
|
||||
verify(request);
|
||||
|
@ -156,9 +156,11 @@ public class BindAzureBlobToPayloadTest {
|
|||
Blob blob = createMock(Blob.class);
|
||||
MutableBlobProperties md = createMock(MutableBlobProperties.class);
|
||||
Multimap<String, String> headers = createMock(Multimap.class);
|
||||
MutableContentMetadata content = createMock(MutableContentMetadata.class);
|
||||
|
||||
expect(object.getPayload()).andReturn(payload).atLeastOnce();
|
||||
expect(payload.getContentLength()).andReturn(5368709121l).atLeastOnce();
|
||||
expect(payload.getContentMetadata()).andReturn(content).atLeastOnce();
|
||||
expect(content.getContentLength()).andReturn(5368709121l).atLeastOnce();
|
||||
expect(object2Blob.apply(object)).andReturn(blob);
|
||||
mdBinder.bindToRequest(request, blob);
|
||||
expect(object.getProperties()).andReturn(md).atLeastOnce();
|
||||
|
@ -166,11 +168,13 @@ public class BindAzureBlobToPayloadTest {
|
|||
expect(request.getHeaders()).andReturn(headers).atLeastOnce();
|
||||
expect(headers.put("x-ms-blob-type", "BlockBlob")).andReturn(true);
|
||||
|
||||
expect(md.getContentLanguage()).andReturn(null).atLeastOnce();
|
||||
expect(md.getContentEncoding()).andReturn(null).atLeastOnce();
|
||||
expect(content.getContentLanguage()).andReturn(null).atLeastOnce();
|
||||
expect(content.getContentEncoding()).andReturn(null).atLeastOnce();
|
||||
|
||||
replay(headers);
|
||||
replay(payload);
|
||||
replay(content);
|
||||
|
||||
replay(mdBinder);
|
||||
replay(object2Blob);
|
||||
replay(request);
|
||||
|
@ -178,12 +182,12 @@ public class BindAzureBlobToPayloadTest {
|
|||
replay(blob);
|
||||
replay(md);
|
||||
|
||||
BindAzureBlobToPayload bindAzureBlobToPayload = new BindAzureBlobToPayload(object2Blob,
|
||||
mdBinder);
|
||||
BindAzureBlobToPayload bindAzureBlobToPayload = new BindAzureBlobToPayload(object2Blob, mdBinder);
|
||||
|
||||
bindAzureBlobToPayload.bindToRequest(request, object);
|
||||
|
||||
verify(headers);
|
||||
verify(content);
|
||||
verify(payload);
|
||||
verify(mdBinder);
|
||||
verify(object2Blob);
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.jclouds.blobstore.domain.Blob.Factory;
|
|||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.io.payloads.PhantomPayload;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.RestClientTest;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
|
@ -46,7 +45,7 @@ import com.google.inject.Module;
|
|||
import com.google.inject.TypeLiteral;
|
||||
|
||||
@Test(groups = "unit", testName = "s3.AzureBlobBlobRequestSignerTest")
|
||||
public class AzureBlobBlobRequestSignerTest extends RestClientTest<AzureBlobAsyncClient> {
|
||||
public class AzureBlobRequestSignerTest extends RestClientTest<AzureBlobAsyncClient> {
|
||||
|
||||
private BlobRequestSigner signer;
|
||||
private Factory blobFactory;
|
||||
|
@ -81,8 +80,10 @@ public class AzureBlobBlobRequestSignerTest extends RestClientTest<AzureBlobAsyn
|
|||
NoSuchMethodException, IOException {
|
||||
Blob blob = blobFactory.create(null);
|
||||
blob.getMetadata().setName("name");
|
||||
blob.setPayload(new PhantomPayload(2l, new byte[] { 0, 2, 4, 8 }));
|
||||
blob.getPayload().setContentType("text/plain");
|
||||
blob.setPayload("");
|
||||
blob.getPayload().getContentMetadata().setContentLength(2l);
|
||||
blob.getPayload().getContentMetadata().setContentMD5(new byte[] { 0, 2, 4, 8 });
|
||||
blob.getPayload().getContentMetadata().setContentType("text/plain");
|
||||
|
||||
HttpRequest request = signer.signPutBlob("container", blob);
|
||||
|
|
@ -239,35 +239,6 @@ Options can also be specified for extension modules
|
|||
([container-name path #^BlobStore blobstore]
|
||||
(.getBlob blobstore container-name path)))
|
||||
|
||||
(defn sign-get-blob-request
|
||||
"Get a signed http request for a blob, so that you can retrieve it
|
||||
in another application. ex. curl"
|
||||
([container-name path]
|
||||
(sign-get-blob-request container-name path *blobstore*))
|
||||
([container-name path #^BlobStore blobstore]
|
||||
(.signGetBlob (.. blobstore getContext getSigner) container-name path)))
|
||||
|
||||
(defn sign-remove-blob-request
|
||||
"Get a signed http request for deleting a blob in another application.
|
||||
ex. curl"
|
||||
([container-name path]
|
||||
(sign-remove-blob-request container-name path *blobstore*))
|
||||
([container-name path #^BlobStore blobstore]
|
||||
(.signRemoveBlob (.. blobstore getContext getSigner) container-name path)))
|
||||
|
||||
(defn sign-put-blob-request
|
||||
"Get a signed http request for uploading a blob in another application.
|
||||
ex. curl"
|
||||
([container-name path content-type size]
|
||||
(sign-put-blob-request container-name path content-type size *blobstore*))
|
||||
([container-name path content-type size #^BlobStore blobstore]
|
||||
(.signPutBlob (.. blobstore getContext getSigner) container-name
|
||||
(doto (.newBlob blobstore path)
|
||||
(.setPayload (doto
|
||||
;; until we pass content md5
|
||||
(PhantomPayload. (long size) nil)
|
||||
(.setContentType content-type)))))))
|
||||
|
||||
(defn sign-blob-request
|
||||
"Get a signed http request for manipulating a blob in another application.
|
||||
ex. curl"
|
||||
|
@ -278,14 +249,18 @@ in another application. ex. curl"
|
|||
{:keys [method content-type content-length content-md5]} blobstore]
|
||||
{:pre [(or content-length (#{:delete :get} method))]}
|
||||
(case method
|
||||
:delete (sign-remove-blob-request container-name path blobstore)
|
||||
:get (sign-get-blob-request container-name path blobstore)
|
||||
:delete (.signRemoveBlob (.. blobstore getContext getSigner) container-name path)
|
||||
:get (.signGetBlob (.. blobstore getContext getSigner) container-name path)
|
||||
:put (.signPutBlob
|
||||
(.. blobstore getContext getSigner) container-name
|
||||
(doto (.newBlob blobstore path)
|
||||
(.setPayload
|
||||
(doto (PhantomPayload. (long content-length) content-md5)
|
||||
(.setContentType content-type))))))))
|
||||
(doto
|
||||
(PhantomPayload. )
|
||||
;; TODO look into use of ContentMetadata constructor
|
||||
(.getContentMetadata (.setContentLength (long content-length)))
|
||||
(.getContentMetadata (.setContentType content-type))
|
||||
(.getContentMetadata (.setContentMD5 content-md5)))))))))
|
||||
|
||||
(defn get-blob-stream
|
||||
"Get an inputstream from the blob at a given path"
|
||||
|
@ -371,7 +346,7 @@ container, name, string -> etag"
|
|||
target (.md5(.crypto (.utils (blobstore-context blobstore)))))]
|
||||
(.writeTo (.getPayload blob) digest-stream)
|
||||
(let [digest (.digest (.getMessageDigest digest-stream))
|
||||
metadata-digest (.getContentMD5 (.getPayload blob))]
|
||||
metadata-digest (.getContentMD5 (.getContentMetadata (.getPayload blob)))]
|
||||
(when-not (Arrays/equals digest metadata-digest)
|
||||
(if (<= (or retries 0) *max-retries*)
|
||||
(recur container-name name target blobstore [(inc (or retries 1))])
|
||||
|
|
|
@ -86,7 +86,9 @@ import org.jclouds.http.HttpCommand;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.options.HttpRequestOptions;
|
||||
import org.jclouds.io.MutableContentMetadata;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.io.payloads.ByteArrayPayload;
|
||||
|
@ -103,8 +105,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
import com.google.inject.internal.Nullable;
|
||||
|
||||
/**
|
||||
* Implementation of {@link BaseAsyncBlobStore} which keeps all data in a local
|
||||
* Map object.
|
||||
* Implementation of {@link BaseAsyncBlobStore} which keeps all data in a local Map object.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @author James Murty
|
||||
|
@ -122,7 +123,8 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
@Inject
|
||||
protected TransientAsyncBlobStore(BlobStoreContext context, DateService dateService, Crypto crypto,
|
||||
ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs,
|
||||
ConcurrentMap<String, Location> containerToLocation, HttpGetOptionsListToGetOptions httpGetOptionsConverter,
|
||||
ConcurrentMap<String, Location> containerToLocation,
|
||||
HttpGetOptionsListToGetOptions httpGetOptionsConverter,
|
||||
IfDirectoryReturnNameStrategy ifDirectoryReturnName, Blob.Factory blobFactory, BlobUtils blobUtils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier<Location> defaultLocation,
|
||||
Supplier<Set<? extends Location>> locations) {
|
||||
|
@ -242,9 +244,10 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
os = new ObjectOutputStream(bout);
|
||||
os.writeObject(in);
|
||||
ObjectInput is = new ObjectInputStream(new ByteArrayInputStream(bout.toByteArray()));
|
||||
MutableBlobMetadata metadata = (MutableBlobMetadata) is.readObject();
|
||||
convertUserMetadataKeysToLowercase(metadata);
|
||||
return metadata;
|
||||
MutableBlobMetadata out = (MutableBlobMetadata) is.readObject();
|
||||
convertUserMetadataKeysToLowercase(out);
|
||||
HttpUtils.copy(in.getContentMetadata(), out.getContentMetadata());
|
||||
return out;
|
||||
} catch (Exception e) {
|
||||
propagate(e);
|
||||
assert false : "exception should have propagated: " + e;
|
||||
|
@ -509,17 +512,17 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
.getPayload()) : null;
|
||||
if (payload == null)
|
||||
payload = (in.getPayload() instanceof DelegatingPayload) ? (DelegatingPayload.class.cast(in.getPayload())
|
||||
.getDelegate() instanceof ByteArrayPayload) ? ByteArrayPayload.class.cast(DelegatingPayload.class.cast(
|
||||
in.getPayload()).getDelegate()) : null : null;
|
||||
.getDelegate() instanceof ByteArrayPayload) ? ByteArrayPayload.class.cast(DelegatingPayload.class
|
||||
.cast(in.getPayload()).getDelegate()) : null : null;
|
||||
try {
|
||||
if (payload == null || !(payload instanceof ByteArrayPayload)) {
|
||||
String oldContentType = in.getPayload().getContentType();
|
||||
MutableContentMetadata oldMd = in.getPayload().getContentMetadata();
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
in.getPayload().writeTo(out);
|
||||
payload = (ByteArrayPayload) Payloads.calculateMD5(Payloads.newPayload(out.toByteArray()));
|
||||
payload.setContentType(oldContentType);
|
||||
HttpUtils.copy(oldMd, payload.getContentMetadata());
|
||||
} else {
|
||||
if (payload.getContentMD5() == null)
|
||||
if (payload.getContentMetadata().getContentMD5() == null)
|
||||
Payloads.calculateMD5(in, crypto.md5());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
@ -528,14 +531,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
Blob blob = blobFactory.create(copy(in.getMetadata()));
|
||||
blob.setPayload(payload);
|
||||
blob.getMetadata().setLastModified(new Date());
|
||||
blob.getMetadata().setSize(payload.getContentLength());
|
||||
blob.getMetadata().setContentMD5(payload.getContentMD5());
|
||||
blob.getMetadata().setContentType(payload.getContentType());
|
||||
blob.getMetadata().setContentDisposition(payload.getContentDisposition());
|
||||
blob.getMetadata().setContentEncoding(payload.getContentEncoding());
|
||||
blob.getMetadata().setContentLanguage(payload.getContentLanguage());
|
||||
|
||||
String eTag = CryptoStreams.hex(payload.getContentMD5());
|
||||
String eTag = CryptoStreams.hex(payload.getContentMetadata().getContentMD5());
|
||||
blob.getMetadata().setETag(eTag);
|
||||
// Set HTTP headers to match metadata
|
||||
blob.getAllHeaders().replaceValues(HttpHeaders.LAST_MODIFIED,
|
||||
|
@ -547,23 +543,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
}
|
||||
|
||||
private void copyPayloadHeadersToBlob(Payload payload, Blob blob) {
|
||||
if (payload.getContentType() != null)
|
||||
blob.getAllHeaders().replaceValues(HttpHeaders.CONTENT_TYPE, Collections.singleton(payload.getContentType()));
|
||||
if (payload.getContentDisposition() != null)
|
||||
blob.getAllHeaders().replaceValues("Content-Disposition",
|
||||
Collections.singleton(payload.getContentDisposition()));
|
||||
if (payload.getContentEncoding() != null)
|
||||
blob.getAllHeaders().replaceValues(HttpHeaders.CONTENT_ENCODING,
|
||||
Collections.singleton(payload.getContentEncoding()));
|
||||
if (payload.getContentEncoding() != null)
|
||||
blob.getAllHeaders().replaceValues(HttpHeaders.CONTENT_LANGUAGE,
|
||||
Collections.singleton(payload.getContentLanguage()));
|
||||
if (payload.getContentLength() != null)
|
||||
blob.getAllHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
|
||||
Collections.singleton(payload.getContentLength() + ""));
|
||||
if (payload.getContentMD5() != null)
|
||||
blob.getAllHeaders().replaceValues("Content-MD5",
|
||||
Collections.singleton(CryptoStreams.base64(payload.getContentMD5())));
|
||||
HttpUtils.addContentHeadersFromMetadata(payload.getContentMetadata(), blob.getAllHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -644,7 +624,6 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
|
||||
}
|
||||
returnVal.setPayload(out.toByteArray());
|
||||
returnVal.getMetadata().setSize(new Long(data.length));
|
||||
}
|
||||
checkNotNull(returnVal.getPayload(), "payload " + returnVal);
|
||||
return immediateFuture(returnVal);
|
||||
|
|
|
@ -25,11 +25,10 @@ import java.net.URI;
|
|||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.filters.BasicAuthentication;
|
||||
|
||||
/**
|
||||
|
@ -57,12 +56,7 @@ public class TransientBlobRequestSigner implements BlobRequestSigner {
|
|||
public HttpRequest signPutBlob(String container, Blob blob) {
|
||||
HttpRequest request = new HttpRequest("PUT", URI.create(String.format("http://localhost/%s/%s", container, blob
|
||||
.getMetadata().getName())));
|
||||
if (blob.getPayload().getContentLength() != null)
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_LENGTH, blob.getPayload().getContentLength().toString());
|
||||
if (blob.getPayload().getContentType() != null)
|
||||
request.getHeaders().put(HttpHeaders.CONTENT_TYPE, blob.getPayload().getContentType());
|
||||
if (blob.getPayload().getContentMD5() != null)
|
||||
request.getHeaders().put("Content-MD5", CryptoStreams.base64(blob.getPayload().getContentMD5()));
|
||||
HttpUtils.addContentHeadersFromMetadata(blob.getMetadata().getContentMetadata(), request.getHeaders());
|
||||
request.setPayload(blob.getPayload());
|
||||
basicAuth.filter(request);
|
||||
return request;
|
||||
|
|
|
@ -39,7 +39,7 @@ public class BindBlobToMultipartForm implements Binder {
|
|||
Blob blob = (Blob) payload;
|
||||
|
||||
Part part = Part.create(blob.getMetadata().getName(), blob.getPayload(),
|
||||
new PartOptions().contentType(blob.getMetadata().getContentType()));
|
||||
new PartOptions().contentType(blob.getMetadata().getContentMetadata().getContentType()));
|
||||
|
||||
request.setPayload(new MultipartForm(part));
|
||||
}
|
||||
|
|
|
@ -19,9 +19,8 @@
|
|||
|
||||
package org.jclouds.blobstore.domain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.blobstore.domain.internal.BlobMetadataImpl;
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
|
@ -32,40 +31,5 @@ import com.google.inject.ImplementedBy;
|
|||
*/
|
||||
@ImplementedBy(BlobMetadataImpl.class)
|
||||
public interface BlobMetadata extends StorageMetadata {
|
||||
|
||||
/**
|
||||
* 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." />
|
||||
*/
|
||||
String getContentType();
|
||||
|
||||
byte[] getContentMD5();
|
||||
|
||||
/**
|
||||
* Content-Disposition to set for the blob.
|
||||
* <p/>
|
||||
* <b>Attention</b>: Not all provider support it!
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getContentDisposition();
|
||||
|
||||
/**
|
||||
* Get Content Encoding of the blob
|
||||
* <p/>
|
||||
* Not all providers may support it
|
||||
*/
|
||||
@Nullable
|
||||
String getContentEncoding();
|
||||
|
||||
/**
|
||||
* Get Content Language of the blob
|
||||
* <p/>
|
||||
* Not all providers may support it
|
||||
*/
|
||||
@Nullable
|
||||
String getContentLanguage();
|
||||
ContentMetadata getContentMetadata();
|
||||
}
|
|
@ -19,9 +19,8 @@
|
|||
|
||||
package org.jclouds.blobstore.domain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
import org.jclouds.io.MutableContentMetadata;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
|
@ -32,22 +31,8 @@ import com.google.inject.ImplementedBy;
|
|||
*/
|
||||
@ImplementedBy(MutableBlobMetadataImpl.class)
|
||||
public interface MutableBlobMetadata extends BlobMetadata, MutableStorageMetadata {
|
||||
MutableContentMetadata getContentMetadata();
|
||||
|
||||
/**
|
||||
* 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." />
|
||||
*/
|
||||
void setContentType(@Nullable String type);
|
||||
|
||||
void setContentMD5(@Nullable byte[] md5);
|
||||
|
||||
void setContentDisposition(@Nullable String contentDisposition);
|
||||
|
||||
void setContentEncoding(@Nullable String contentEncoding);
|
||||
|
||||
void setContentLanguage(@Nullable String contentLanguage);
|
||||
void setContentMetadata(MutableContentMetadata md);
|
||||
|
||||
}
|
|
@ -21,8 +21,6 @@ package org.jclouds.blobstore.domain;
|
|||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
|
||||
import org.jclouds.domain.MutableResourceMetadata;
|
||||
|
||||
|
@ -42,10 +40,6 @@ public interface MutableStorageMetadata extends MutableResourceMetadata<StorageT
|
|||
*/
|
||||
void setETag(String eTag);
|
||||
|
||||
/**
|
||||
* @see #getSize
|
||||
*/
|
||||
void setSize(@Nullable Long size);
|
||||
|
||||
/**
|
||||
* @see #getLastModified
|
||||
|
|
|
@ -83,14 +83,6 @@ public interface StorageMetadata extends ResourceMetadata<StorageType> {
|
|||
*/
|
||||
String getETag();
|
||||
|
||||
/**
|
||||
* Size of the resource in bytes
|
||||
*
|
||||
* @see org.jclouds.blobstore.attr.ContainerCapability#CONTAINER_SIZE
|
||||
* @see org.jclouds.blobstore.attr.ContainerCapability#BLOB_SIZE
|
||||
*/
|
||||
Long getSize();
|
||||
|
||||
/**
|
||||
* Last modification time of the resource
|
||||
*
|
||||
|
|
|
@ -28,8 +28,6 @@ import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
|||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
import org.jclouds.http.internal.PayloadEnclosingImpl;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.PayloadEnclosing;
|
||||
import org.jclouds.io.payloads.DelegatingPayload;
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
@ -44,15 +42,13 @@ import com.google.common.collect.Multimap;
|
|||
*/
|
||||
public class BlobImpl extends PayloadEnclosingImpl implements Blob, Comparable<Blob> {
|
||||
|
||||
private final MutableBlobMetadata _metadata;
|
||||
private final SetPayloadPropertiesMutableBlobMetadata metadata;
|
||||
private final MutableBlobMetadata metadata;
|
||||
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
|
||||
|
||||
@Inject
|
||||
public BlobImpl(MutableBlobMetadata metadata) {
|
||||
super();
|
||||
this.metadata = linkMetadataToThis(metadata);
|
||||
this._metadata = this.metadata.getDelegate();
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,7 +89,7 @@ public class BlobImpl extends PayloadEnclosingImpl implements Blob, Comparable<B
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((_metadata == null) ? 0 : _metadata.hashCode());
|
||||
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -106,124 +102,23 @@ public class BlobImpl extends PayloadEnclosingImpl implements Blob, Comparable<B
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
BlobImpl other = (BlobImpl) obj;
|
||||
if (_metadata == null) {
|
||||
if (other._metadata != null)
|
||||
if (metadata == null) {
|
||||
if (other.metadata != null)
|
||||
return false;
|
||||
} else if (!_metadata.equals(other._metadata))
|
||||
} else if (!metadata.equals(other.metadata))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[metadata=" + _metadata + "]";
|
||||
return "[metadata=" + metadata + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPayload(Payload data) {
|
||||
linkPayloadToMetadata(data);
|
||||
super.setPayload(data);
|
||||
metadata.setContentMetadata(data.getContentMetadata());
|
||||
}
|
||||
|
||||
/**
|
||||
* link the new payload to the metadata object so that when content-related
|
||||
* metadata is updated on the payload, it is also copied the metadata object.
|
||||
*/
|
||||
void linkPayloadToMetadata(Payload data) {
|
||||
if (data instanceof DelegatingPayload)
|
||||
super
|
||||
.setPayload(new SetMetadataPropertiesPayload(DelegatingPayload.class.cast(data).getDelegate(), _metadata));
|
||||
else
|
||||
super.setPayload(new SetMetadataPropertiesPayload(data, _metadata));
|
||||
}
|
||||
|
||||
static class SetMetadataPropertiesPayload extends DelegatingPayload {
|
||||
|
||||
private transient final MutableBlobMetadata metadata;
|
||||
|
||||
public SetMetadataPropertiesPayload(Payload delegate, MutableBlobMetadata metadata) {
|
||||
super(delegate);
|
||||
this.metadata = metadata;
|
||||
setContentType(metadata.getContentType());
|
||||
setContentDisposition(metadata.getContentDisposition());
|
||||
setContentEncoding(metadata.getContentEncoding());
|
||||
setContentLanguage(metadata.getContentLanguage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String md5) {
|
||||
super.setContentType(md5);
|
||||
metadata.setContentType(md5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentDisposition(String contentDisposition) {
|
||||
super.setContentDisposition(contentDisposition);
|
||||
metadata.setContentDisposition(contentDisposition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentEncoding(String contentEncoding) {
|
||||
super.setContentEncoding(contentEncoding);
|
||||
metadata.setContentEncoding(contentEncoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentLanguage(String contentLanguage) {
|
||||
super.setContentLanguage(contentLanguage);
|
||||
metadata.setContentLanguage(contentLanguage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* link the metadata object to this so that when content-related metadata is
|
||||
* updated, it is also copied the currentpayload object.
|
||||
*/
|
||||
SetPayloadPropertiesMutableBlobMetadata linkMetadataToThis(MutableBlobMetadata metadata) {
|
||||
return metadata instanceof DelegatingMutableBlobMetadata ? new SetPayloadPropertiesMutableBlobMetadata(
|
||||
DelegatingMutableBlobMetadata.class.cast(metadata).getDelegate(), this)
|
||||
: new SetPayloadPropertiesMutableBlobMetadata(metadata, this);
|
||||
}
|
||||
|
||||
static class SetPayloadPropertiesMutableBlobMetadata extends DelegatingMutableBlobMetadata {
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -5072270546219814521L;
|
||||
private transient final PayloadEnclosing blob;
|
||||
|
||||
public SetPayloadPropertiesMutableBlobMetadata(MutableBlobMetadata delegate, PayloadEnclosing blob) {
|
||||
super(delegate);
|
||||
this.blob = blob;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String type) {
|
||||
super.setContentType(type);
|
||||
if (canSetPayload())
|
||||
blob.getPayload().setContentType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentDisposition(String Disposition) {
|
||||
super.setContentDisposition(Disposition);
|
||||
if (canSetPayload())
|
||||
blob.getPayload().setContentDisposition(Disposition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentEncoding(String Encoding) {
|
||||
super.setContentEncoding(Encoding);
|
||||
if (canSetPayload())
|
||||
blob.getPayload().setContentEncoding(Encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentLanguage(String Language) {
|
||||
super.setContentLanguage(Language);
|
||||
if (canSetPayload())
|
||||
blob.getPayload().setContentLanguage(Language);
|
||||
}
|
||||
|
||||
private boolean canSetPayload() {
|
||||
return blob != null && blob.getPayload() != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
package org.jclouds.blobstore.domain.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
|
@ -28,6 +30,7 @@ import org.jclouds.blobstore.domain.Blob;
|
|||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
|
||||
import com.google.inject.internal.Nullable;
|
||||
|
||||
|
@ -39,68 +42,20 @@ import com.google.inject.internal.Nullable;
|
|||
public class BlobMetadataImpl extends StorageMetadataImpl implements Serializable, BlobMetadata {
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -5932618957134612231L;
|
||||
private final ContentMetadata contentMetadata;
|
||||
|
||||
private final String contentType;
|
||||
private final String contentDisposition;
|
||||
private final String contentEncoding;
|
||||
private final String contentLanguage;
|
||||
private final byte[] contentMD5;
|
||||
|
||||
public BlobMetadataImpl(String id, String name, @Nullable Location location, URI uri, String eTag, Long size,
|
||||
Date lastModified, Map<String, String> userMetadata, String contentType, String contentDisposition,
|
||||
String contentEncoding, String contentLanguage, byte[] contentMD5) {
|
||||
super(StorageType.BLOB, id, name, location, uri, eTag, size, lastModified, userMetadata);
|
||||
this.contentType = contentType;
|
||||
this.contentDisposition = contentDisposition;
|
||||
this.contentEncoding = contentEncoding;
|
||||
this.contentLanguage = contentLanguage;
|
||||
this.contentMD5 = contentMD5;
|
||||
public BlobMetadataImpl(String id, String name, @Nullable Location location, URI uri, String eTag,
|
||||
Date lastModified, Map<String, String> userMetadata, ContentMetadata contentMetadata) {
|
||||
super(StorageType.BLOB, id, name, location, uri, eTag, lastModified, userMetadata);
|
||||
this.contentMetadata = checkNotNull(contentMetadata, "contentMetadata");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentDisposition() {
|
||||
return contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentEncoding() {
|
||||
return contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentLanguage() {
|
||||
return contentLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
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 ContentMetadata getContentMetadata() {
|
||||
return contentMetadata;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,209 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.domain.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.ResourceMetadata;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class DelegatingMutableBlobMetadata implements MutableBlobMetadata, Serializable {
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -2739517840958218727L;
|
||||
protected final MutableBlobMetadata delegate;
|
||||
|
||||
public DelegatingMutableBlobMetadata(MutableBlobMetadata delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentMD5(byte[] md5) {
|
||||
delegate.setContentMD5(md5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String type) {
|
||||
delegate.setContentType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getContentMD5() {
|
||||
return delegate.getContentMD5();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return delegate.getContentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setETag(String eTag) {
|
||||
delegate.setETag(eTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastModified(Date lastModified) {
|
||||
delegate.setLastModified(lastModified);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSize(Long size) {
|
||||
delegate.setSize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getETag() {
|
||||
return delegate.getETag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getLastModified() {
|
||||
return delegate.getLastModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return delegate.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProviderId() {
|
||||
return delegate.getProviderId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSize() {
|
||||
return delegate.getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageType getType() {
|
||||
return delegate.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getUri() {
|
||||
return delegate.getUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getUserMetadata() {
|
||||
return delegate.getUserMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
delegate.setId(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocation(Location location) {
|
||||
delegate.setLocation(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
delegate.setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(StorageType type) {
|
||||
delegate.setType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUri(URI url) {
|
||||
delegate.setUri(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserMetadata(Map<String, String> userMetadata) {
|
||||
delegate.setUserMetadata(userMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return delegate.getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ResourceMetadata<StorageType> o) {
|
||||
return delegate.compareTo(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return delegate.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
public MutableBlobMetadata getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentDisposition(String contentDisposition) {
|
||||
delegate.setContentDisposition(contentDisposition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentDisposition() {
|
||||
return delegate.getContentDisposition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentEncoding() {
|
||||
return delegate.getContentEncoding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentLanguage() {
|
||||
return delegate.getContentLanguage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentEncoding(String contentEncoding) {
|
||||
delegate.setContentEncoding(contentEncoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentLanguage(String contentLanguage) {
|
||||
delegate.setContentLanguage(contentLanguage);
|
||||
}
|
||||
|
||||
}
|
|
@ -23,6 +23,9 @@ import org.jclouds.blobstore.domain.Blob;
|
|||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.blobstore.domain.MutableBlobMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.io.MutableContentMetadata;
|
||||
import org.jclouds.io.payloads.BaseMutableContentMetadata;
|
||||
|
||||
/**
|
||||
* System and user Metadata for the {@link Blob}.
|
||||
|
@ -32,115 +35,34 @@ import org.jclouds.blobstore.domain.StorageType;
|
|||
public class MutableBlobMetadataImpl extends MutableStorageMetadataImpl implements MutableBlobMetadata {
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -5932618957134612231L;
|
||||
|
||||
private String contentType;
|
||||
private String contentDisposition;
|
||||
private String contentEncoding;
|
||||
private String contentLanguage;
|
||||
private byte[] contentMD5;
|
||||
private MutableContentMetadata contentMetadata;
|
||||
|
||||
public MutableBlobMetadataImpl() {
|
||||
super();
|
||||
this.setType(StorageType.BLOB);
|
||||
this.contentMetadata = new BaseMutableContentMetadata();
|
||||
}
|
||||
|
||||
public MutableBlobMetadataImpl(BlobMetadata from) {
|
||||
super(from);
|
||||
this.contentType = from.getContentType();
|
||||
this.contentDisposition = from.getContentDisposition();
|
||||
this.contentEncoding = from.getContentEncoding();
|
||||
this.contentLanguage = from.getContentLanguage();
|
||||
this.contentMD5 = from.getContentMD5();
|
||||
this.contentMetadata = new BaseMutableContentMetadata();
|
||||
HttpUtils.copy(from.getContentMetadata(), this.contentMetadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
public MutableContentMetadata getContentMetadata() {
|
||||
return contentMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentDisposition() {
|
||||
return contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setContentDisposition(String contentDisposition) {
|
||||
this.contentDisposition = contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentEncoding() {
|
||||
return contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setContentEncoding(String contentEncoding) {
|
||||
this.contentEncoding = contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentLanguage() {
|
||||
return contentLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setContentLanguage(String contentLanguage) {
|
||||
this.contentLanguage = contentLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setContentMD5(byte[] md5) {
|
||||
if (md5 != null) {
|
||||
byte[] retval = new byte[md5.length];
|
||||
System.arraycopy(md5, 0, retval, 0, md5.length);
|
||||
this.contentMD5 = md5;
|
||||
}
|
||||
public void setContentMetadata(MutableContentMetadata contentMetadata) {
|
||||
this.contentMetadata = contentMetadata;
|
||||
}
|
||||
|
||||
}
|
|
@ -39,7 +39,6 @@ public class MutableStorageMetadataImpl extends MutableResourceMetadataImpl<Stor
|
|||
private static final long serialVersionUID = -280558162576368264L;
|
||||
|
||||
private String eTag;
|
||||
private Long size;
|
||||
private Date lastModified;
|
||||
|
||||
public MutableStorageMetadataImpl() {
|
||||
|
@ -49,7 +48,6 @@ public class MutableStorageMetadataImpl extends MutableResourceMetadataImpl<Stor
|
|||
public MutableStorageMetadataImpl(StorageMetadata from) {
|
||||
super(from);
|
||||
this.eTag = from.getETag();
|
||||
this.size = from.getSize();
|
||||
this.lastModified = from.getLastModified();
|
||||
}
|
||||
|
||||
|
@ -61,14 +59,6 @@ public class MutableStorageMetadataImpl extends MutableResourceMetadataImpl<Stor
|
|||
return eTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -85,14 +75,6 @@ public class MutableStorageMetadataImpl extends MutableResourceMetadataImpl<Stor
|
|||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setSize(Long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -36,25 +36,22 @@ import com.google.inject.internal.Nullable;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class StorageMetadataImpl extends ResourceMetadataImpl<StorageType> implements
|
||||
StorageMetadata, Serializable {
|
||||
public class StorageMetadataImpl extends ResourceMetadataImpl<StorageType> implements StorageMetadata, Serializable {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -280558162576368264L;
|
||||
|
||||
@Nullable
|
||||
private final String eTag;
|
||||
@Nullable
|
||||
private final Long size;
|
||||
|
||||
@Nullable
|
||||
private final Date lastModified;
|
||||
|
||||
public StorageMetadataImpl(StorageType type, @Nullable String id, @Nullable String name,
|
||||
@Nullable Location location, @Nullable URI uri, @Nullable String eTag,
|
||||
@Nullable Long size, @Nullable Date lastModified, Map<String, String> userMetadata) {
|
||||
@Nullable Location location, @Nullable URI uri, @Nullable String eTag, @Nullable Date lastModified,
|
||||
Map<String, String> userMetadata) {
|
||||
super(type, id, name, location, uri, userMetadata);
|
||||
this.eTag = eTag;
|
||||
this.size = size;
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
|
@ -66,14 +63,6 @@ public class StorageMetadataImpl extends ResourceMetadataImpl<StorageType> imple
|
|||
return eTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -49,13 +49,13 @@ public class ObjectMD5 implements Function<Object, byte[]> {
|
|||
object = blobFactory.create(null);
|
||||
object.setPayload(Payloads.newPayload(from));
|
||||
}
|
||||
if (object.getMetadata().getContentMD5() == null)
|
||||
if (object.getMetadata().getContentMetadata().getContentMD5() == null)
|
||||
try {
|
||||
Payloads.calculateMD5(object, crypto.md5());
|
||||
} catch (IOException e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return object.getPayload().getContentMD5();
|
||||
return object.getPayload().getContentMetadata().getContentMD5();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import static com.google.common.base.Preconditions.checkArgument;
|
|||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
import static org.jclouds.blobstore.util.BlobStoreUtils.getKeyFor;
|
||||
import static org.jclouds.http.HttpUtils.attemptToParseSizeAndRangeFromHeaders;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
@ -37,6 +36,7 @@ import org.jclouds.date.DateService;
|
|||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.rest.InvocationContext;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
|
@ -68,11 +68,9 @@ public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpRespo
|
|||
String objectKey = getKeyFor(request, from);
|
||||
MutableBlobMetadata to = metadataFactory.get();
|
||||
to.setName(objectKey);
|
||||
setContentTypeOrThrowException(from, to);
|
||||
HttpUtils.copy(from.getPayload().getContentMetadata(), to.getContentMetadata());
|
||||
addETagTo(from, to);
|
||||
addContentMD5To(from, to);
|
||||
parseLastModifiedOrThrowException(from, to);
|
||||
setContentLength(from, to);
|
||||
addUserMetadataTo(from, to);
|
||||
return to;
|
||||
}
|
||||
|
@ -86,11 +84,6 @@ public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpRespo
|
|||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setContentLength(HttpResponse from, MutableBlobMetadata metadata) throws HttpException {
|
||||
metadata.setSize(attemptToParseSizeAndRangeFromHeaders(from));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void parseLastModifiedOrThrowException(HttpResponse from, MutableBlobMetadata metadata) throws HttpException {
|
||||
String lastModified = from.getFirstHeaderOrNull(HttpHeaders.LAST_MODIFIED);
|
||||
|
@ -115,21 +108,6 @@ public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpRespo
|
|||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected void addContentMD5To(HttpResponse from, MutableBlobMetadata metadata) {
|
||||
if (from.getPayload() != null)
|
||||
metadata.setContentMD5(from.getPayload().getContentMD5());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setContentTypeOrThrowException(HttpResponse from, MutableBlobMetadata metadata) throws HttpException {
|
||||
if (from.getPayload() != null)
|
||||
metadata.setContentType(from.getPayload().getContentType());
|
||||
if (from.getStatusCode() != 204 && (metadata.getContentType() == null
|
||||
|| "application/unknown".equals(metadata.getContentType())))
|
||||
throw new HttpException(HttpHeaders.CONTENT_TYPE + " not found in headers");
|
||||
}
|
||||
|
||||
public ParseSystemAndUserMetadataFromHeaders setContext(HttpRequest request) {
|
||||
checkArgument(request instanceof GeneratedHttpRequest<?>, "note this handler requires a GeneratedHttpRequest");
|
||||
this.request = (GeneratedHttpRequest<?>) request;
|
||||
|
|
|
@ -29,8 +29,7 @@ import org.jclouds.blobstore.reference.BlobStoreConstants;
|
|||
import com.google.common.base.Function;
|
||||
|
||||
@Singleton
|
||||
public class ResourceMetadataToRelativePathResourceMetadata implements
|
||||
Function<StorageMetadata, StorageMetadata> {
|
||||
public class ResourceMetadataToRelativePathResourceMetadata implements Function<StorageMetadata, StorageMetadata> {
|
||||
|
||||
public StorageMetadata apply(StorageMetadata md) {
|
||||
String name = md.getName();
|
||||
|
@ -38,9 +37,8 @@ public class ResourceMetadataToRelativePathResourceMetadata implements
|
|||
if (name.endsWith(suffix))
|
||||
name = name.substring(0, name.length() - suffix.length());
|
||||
}
|
||||
return new StorageMetadataImpl(StorageType.RELATIVE_PATH, md.getProviderId(), name, md
|
||||
.getLocation(), md.getUri(), md.getETag(), md.getSize(), md.getLastModified(), md
|
||||
.getUserMetadata());
|
||||
return new StorageMetadataImpl(StorageType.RELATIVE_PATH, md.getProviderId(), name, md.getLocation(),
|
||||
md.getUri(), md.getETag(), md.getLastModified(), md.getUserMetadata());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class FindMD5InList implements ContainsValueInListStrategy {
|
|||
try {
|
||||
byte[] toSearch = objectMD5.apply(value);
|
||||
for (BlobMetadata metadata : getAllBlobMetadata.execute(containerName, options)) {
|
||||
if (Arrays.equals(toSearch, metadata.getContentMD5()))
|
||||
if (Arrays.equals(toSearch, metadata.getContentMetadata().getContentMD5()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -54,7 +54,7 @@ public class MarkerFileMkdirStrategy implements MkdirStrategy {
|
|||
public void execute(String containerName, String directory) {
|
||||
Blob blob = connection.newBlob(directory + directorySuffix);
|
||||
blob.setPayload(Payloads.newByteArrayPayload(new byte[] {}));
|
||||
blob.getPayload().setContentType("application/directory");
|
||||
blob.getPayload().getContentMetadata().setContentType("application/directory");
|
||||
blob.getMetadata().setType(StorageType.RELATIVE_PATH);
|
||||
connection.putBlob(containerName, blob);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ public class MarkersGetDirectoryStrategy implements GetDirectoryStrategy {
|
|||
|
||||
public StorageMetadata execute(String containerName, String directory) {
|
||||
BlobMetadata md = connection.blobMetadata(containerName, directory);
|
||||
if (md != null && md.getContentType().equals("application/directory"))
|
||||
if (md != null && md.getContentMetadata().getContentType().equals("application/directory"))
|
||||
return resource2Directory.apply(md);
|
||||
for (String suffix : BlobStoreConstants.DIRECTORY_SUFFIXES) {
|
||||
md = connection.blobMetadata(containerName, directory + suffix);
|
||||
|
|
|
@ -48,8 +48,8 @@ public class MarkersIfDirectoryReturnNameStrategy implements IfDirectoryReturnNa
|
|||
}
|
||||
// It is important that this is last, in case there is a file with a known directory
|
||||
// suffix who also has content type set to application/directory
|
||||
if (blobMd.getContentType() != null
|
||||
&& blobMd.getContentType().equals("application/directory"))
|
||||
if (blobMd.getContentMetadata().getContentType() != null
|
||||
&& blobMd.getContentMetadata().getContentType().equals("application/directory"))
|
||||
return metadata.getName();
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.jclouds.functions.ExceptionToValueOrPropagate;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
|
@ -79,8 +80,7 @@ public class BlobStoreUtils {
|
|||
public static Blob newBlob(BlobStore blobStore, StorageMetadata blobMeta) {
|
||||
Blob blob = blobStore.newBlob(blobMeta.getName());
|
||||
if (blobMeta instanceof BlobMetadata) {
|
||||
blob.getMetadata().setContentMD5(((BlobMetadata) blobMeta).getContentMD5());
|
||||
blob.getMetadata().setContentType(((BlobMetadata) blobMeta).getContentType());
|
||||
HttpUtils.copy(((BlobMetadata) blobMeta).getContentMetadata(), blob.getMetadata().getContentMetadata());
|
||||
}
|
||||
blob.getMetadata().setETag(blobMeta.getETag());
|
||||
blob.getMetadata().setId(blobMeta.getProviderId());
|
||||
|
|
|
@ -109,14 +109,6 @@
|
|||
(download-blob container-name name data-file)))
|
||||
(finally (.delete data-file))))))
|
||||
|
||||
;; this will fail until somebody fixes it!
|
||||
#_
|
||||
(deftest sing-put-blob-request-test
|
||||
(let [request (sign-put-blob-request "container" "path" "text/plain" 10)]
|
||||
(is (= "PUT" (.getMethod request)))
|
||||
(is (= "10" (get "Content-Length" (.getHeaders request))))
|
||||
(is (= "text/plain" (get "Content-Type" (.getHeaders request))))))
|
||||
|
||||
;; this will fail until somebody fixes it!
|
||||
#_
|
||||
(deftest sing-blob-request-test
|
||||
|
|
|
@ -69,8 +69,10 @@ public class TransientBlobRequestSignerTest extends RestClientTest<TransientAsyn
|
|||
NoSuchMethodException, IOException {
|
||||
Blob blob = blobFactory.create(null);
|
||||
blob.getMetadata().setName("name");
|
||||
blob.setPayload(new PhantomPayload(2l, new byte[] { 0, 2, 4, 8 }));
|
||||
blob.getPayload().setContentType("text/plain");
|
||||
blob.setPayload(new PhantomPayload());
|
||||
blob.getPayload().getContentMetadata().setContentLength(2l);
|
||||
blob.getPayload().getContentMetadata().setContentMD5(new byte[] { 0, 2, 4, 8 });
|
||||
blob.getPayload().getContentMetadata().setContentType("text/plain");
|
||||
|
||||
HttpRequest request = signer.signPutBlob("container", blob);
|
||||
|
||||
|
|
|
@ -46,8 +46,8 @@ public class BindBlobToMultipartFormTest {
|
|||
public static final Blob TEST_BLOB;
|
||||
|
||||
static {
|
||||
blobProvider = new RestContextFactory().createContextBuilder("transient", "identity",
|
||||
"credential").buildInjector().getInstance(Blob.Factory.class);
|
||||
blobProvider = new RestContextFactory().createContextBuilder("transient", "identity", "credential")
|
||||
.buildInjector().getInstance(Blob.Factory.class);
|
||||
StringBuilder builder = new StringBuilder("--");
|
||||
addData(BOUNDARY, "hello", builder);
|
||||
builder.append("--").append(BOUNDARY).append("--").append("\r\n");
|
||||
|
@ -55,7 +55,7 @@ public class BindBlobToMultipartFormTest {
|
|||
TEST_BLOB = blobProvider.create(null);
|
||||
TEST_BLOB.getMetadata().setName("hello");
|
||||
TEST_BLOB.setPayload("hello");
|
||||
TEST_BLOB.getMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||
TEST_BLOB.getMetadata().getContentMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||
}
|
||||
|
||||
public void testSinglePart() throws IOException {
|
||||
|
@ -68,16 +68,15 @@ public class BindBlobToMultipartFormTest {
|
|||
binder.bindToRequest(request, TEST_BLOB);
|
||||
|
||||
assertEquals(toStringAndClose(request.getPayload().getInput()), EXPECTS);
|
||||
assertEquals(request.getPayload().getContentLength(), new Long(113));
|
||||
assertEquals(request.getPayload().getContentMetadata().getContentLength(), new Long(113));
|
||||
|
||||
assertEquals(request.getPayload().getContentType(), "multipart/form-data; boundary="
|
||||
assertEquals(request.getPayload().getContentMetadata().getContentType(), "multipart/form-data; boundary="
|
||||
+ BOUNDARY);
|
||||
}
|
||||
|
||||
private static void addData(String boundary, String data, StringBuilder builder) {
|
||||
builder.append(boundary).append("\r\n");
|
||||
builder.append("Content-Disposition").append(": ").append("form-data; name=\"hello\"")
|
||||
.append("\r\n");
|
||||
builder.append("Content-Disposition").append(": ").append("form-data; name=\"hello\"").append("\r\n");
|
||||
builder.append("Content-Type").append(": ").append("text/plain").append("\r\n");
|
||||
builder.append("\r\n");
|
||||
builder.append(data).append("\r\n");
|
||||
|
|
|
@ -79,8 +79,8 @@ public class ParseBlobFromHeadersAndHttpContentTest {
|
|||
metadataParser, blobProvider);
|
||||
|
||||
HttpResponse response = new HttpResponse(200, "ok", Payloads.newStringPayload(""));
|
||||
response.getPayload().setContentType(MediaType.APPLICATION_JSON);
|
||||
response.getPayload().setContentLength(10485760l);
|
||||
response.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON);
|
||||
response.getPayload().getContentMetadata().setContentLength(10485760l);
|
||||
response.getHeaders().put("Content-Range", "0-10485759/20232760");
|
||||
|
||||
MutableBlobMetadata meta = blobMetadataProvider.get();
|
||||
|
@ -88,8 +88,7 @@ public class ParseBlobFromHeadersAndHttpContentTest {
|
|||
replay(metadataParser);
|
||||
|
||||
Blob object = callable.apply(response);
|
||||
assertEquals(object.getPayload().getContentLength(), new Long(10485760));
|
||||
assertEquals(object.getMetadata().getSize(), null);// TODO
|
||||
assertEquals(object.getPayload().getContentMetadata().getContentLength(), new Long(10485760));
|
||||
assertEquals(object.getAllHeaders().get("Content-Range"), Collections
|
||||
.singletonList("0-10485759/20232760"));
|
||||
|
||||
|
|
|
@ -75,9 +75,9 @@ public class ParseSystemAndUserMetadataFromHeadersTest {
|
|||
@Test
|
||||
public void testApplySetsKey() {
|
||||
HttpResponse from = new HttpResponse(200, "ok", Payloads.newStringPayload(""));
|
||||
from.getPayload().setContentType(MediaType.APPLICATION_JSON);
|
||||
from.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON);
|
||||
from.getHeaders().put(HttpHeaders.LAST_MODIFIED, "Wed, 09 Sep 2009 19:50:23 GMT");
|
||||
from.getPayload().setContentLength(100l);
|
||||
from.getPayload().getContentMetadata().setContentLength(100l);
|
||||
BlobMetadata metadata = parser.apply(from);
|
||||
assertEquals(metadata.getName(), "key");
|
||||
}
|
||||
|
@ -89,38 +89,6 @@ public class ParseSystemAndUserMetadataFromHeadersTest {
|
|||
parser.apply(from);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetContentLength() {
|
||||
HttpResponse from = new HttpResponse(200, "ok", Payloads.newStringPayload(""));
|
||||
from.getPayload().setContentLength(100l);
|
||||
MutableBlobMetadata metadata = blobMetadataProvider.get();
|
||||
parser.setContentLength(from, metadata);
|
||||
assertEquals(metadata.getSize(), new Long(100));
|
||||
}
|
||||
|
||||
public void testSetContentLengthNoHeader() {
|
||||
HttpResponse from = new HttpResponse(200, "ok", Payloads.newStringPayload(""));
|
||||
MutableBlobMetadata metadata = blobMetadataProvider.get();
|
||||
parser.setContentLength(from, metadata);
|
||||
assertEquals(metadata.getSize(), new Long(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetContentType() {
|
||||
HttpResponse from = new HttpResponse(200, "ok", Payloads.newStringPayload(""));
|
||||
from.getPayload().setContentType(MediaType.APPLICATION_JSON);
|
||||
MutableBlobMetadata metadata = blobMetadataProvider.get();
|
||||
parser.setContentTypeOrThrowException(from, metadata);
|
||||
assertEquals(metadata.getContentType(), MediaType.APPLICATION_JSON);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = HttpException.class)
|
||||
public void testSetContentTypeException() {
|
||||
HttpResponse from = new HttpResponse(200, "ok", Payloads.newStringPayload(""));
|
||||
MutableBlobMetadata metadata = blobMetadataProvider.get();
|
||||
parser.setContentTypeOrThrowException(from, metadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetLastModified() {
|
||||
HttpResponse from = new HttpResponse(200, "ok", Payloads.newStringPayload(""));
|
||||
|
|
|
@ -47,8 +47,7 @@ public class TransientContainerIntegrationTest extends BaseContainerIntegrationT
|
|||
|
||||
Blob object = context.getBlobStore().newBlob(key);
|
||||
object.setPayload(TEST_STRING);
|
||||
object.getMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||
object.getMetadata().setSize(new Long(TEST_STRING.length()));
|
||||
object.getMetadata().getContentMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||
// NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the
|
||||
// providers.
|
||||
object.getMetadata().getUserMetadata().put("Adrian", "powderpuff");
|
||||
|
|
|
@ -147,23 +147,22 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
private void uploadConstitution(String containerName, String key, String contentDisposition) throws IOException {
|
||||
Blob sourceObject = context.getBlobStore().newBlob(key);
|
||||
sourceObject.getMetadata().setContentType("text/plain");
|
||||
sourceObject.getMetadata().setContentMD5(oneHundredOneConstitutionsMD5);
|
||||
sourceObject.getMetadata().setContentDisposition(contentDisposition);
|
||||
sourceObject.setPayload(oneHundredOneConstitutions.getInput());
|
||||
sourceObject.getMetadata().getContentMetadata().setContentType("text/plain");
|
||||
sourceObject.getMetadata().getContentMetadata().setContentMD5(oneHundredOneConstitutionsMD5);
|
||||
sourceObject.getMetadata().getContentMetadata().setContentDisposition(contentDisposition);
|
||||
context.getBlobStore().putBlob(containerName, sourceObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods for checking Content-Disposition. In this way, in implementations
|
||||
* that do not support the new field, it is easy to override with empty, and
|
||||
* allow the rest of the test to work.
|
||||
* Methods for checking Content-Disposition. In this way, in implementations that do not support
|
||||
* the new field, it is easy to override with empty, and allow the rest of the test to work.
|
||||
*
|
||||
* @param blob
|
||||
* @param expected
|
||||
*/
|
||||
protected void checkContentDispostion(Blob blob, String expected) {
|
||||
assertEquals(blob.getPayload().getContentDisposition(), expected);
|
||||
assertEquals(blob.getPayload().getContentMetadata().getContentDisposition(), expected);
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" })
|
||||
|
@ -374,8 +373,8 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
@DataProvider(name = "delete")
|
||||
public Object[][] createData() {
|
||||
return new Object[][] { { "normal" }, { "sp ace" }, { "qu?stion" }, { "unic₪de" }, { "path/foo" },
|
||||
{ "colon:" }, { "asteri*k" }, { "quote\"" }, { "{great<r}" }, { "lesst>en" }, { "p|pe" } };
|
||||
return new Object[][] { { "normal" }, { "sp ace" }, { "qu?stion" }, { "unic₪de" }, { "path/foo" }, { "colon:" },
|
||||
{ "asteri*k" }, { "quote\"" }, { "{great<r}" }, { "lesst>en" }, { "p|pe" } };
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" }, dataProvider = "delete")
|
||||
|
@ -401,8 +400,8 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
});
|
||||
assertEquals(Iterables.size(listing), 0, String.format(
|
||||
"deleting %s, we still have %s blobs left in container %s, using encoding %s", key,
|
||||
Iterables.size(listing), containerName, LOCAL_ENCODING));
|
||||
"deleting %s, we still have %s blobs left in container %s, using encoding %s", key, Iterables
|
||||
.size(listing), containerName, LOCAL_ENCODING));
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" })
|
||||
|
@ -430,8 +429,10 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
public void testPutObject(String key, String type, Object content, Object realObject) throws InterruptedException,
|
||||
IOException {
|
||||
Blob blob = context.getBlobStore().newBlob(key);
|
||||
blob.getMetadata().setContentType(type);
|
||||
blob.setPayload(Payloads.newPayload(content));
|
||||
blob.getMetadata().getContentMetadata().setContentType(type);
|
||||
addContentMetadata(blob);
|
||||
|
||||
if (content instanceof InputStream) {
|
||||
Payloads.calculateMD5(blob, context.utils().crypto().md5());
|
||||
}
|
||||
|
@ -439,6 +440,8 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
try {
|
||||
assertNotNull(context.getBlobStore().putBlob(containerName, blob));
|
||||
blob = context.getBlobStore().getBlob(containerName, blob.getMetadata().getName());
|
||||
checkContentMetadata(blob);
|
||||
|
||||
String returnedString = getContentAsStringOrNullAndClose(blob);
|
||||
assertEquals(returnedString, realObject);
|
||||
PageSet<? extends StorageMetadata> set = context.getBlobStore().list(containerName);
|
||||
|
@ -457,10 +460,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
outstream.write("foo".getBytes());
|
||||
}
|
||||
}));
|
||||
blob.getMetadata().setContentType("text/csv");
|
||||
blob.getMetadata().setContentDisposition("attachment; filename=photo.jpg");
|
||||
blob.getMetadata().setContentEncoding("gzip");
|
||||
blob.getMetadata().setContentLanguage("en");
|
||||
addContentMetadata(blob);
|
||||
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
|
@ -470,10 +470,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
blob = context.getBlobStore().getBlob(containerName, blob.getMetadata().getName());
|
||||
String returnedString = getContentAsStringOrNullAndClose(blob);
|
||||
assertEquals(returnedString, "foo");
|
||||
checkContentType(blob, "text/csv");
|
||||
checkContentDisposition(blob, "attachment; filename=photo.jpg");
|
||||
checkContentEncoding(blob, "gzip");
|
||||
checkContentLanguage(blob, "en");
|
||||
checkContentMetadata(blob);
|
||||
PageSet<? extends StorageMetadata> set = context.getBlobStore().list(containerName);
|
||||
assert set.size() == 1 : set;
|
||||
} finally {
|
||||
|
@ -481,38 +478,51 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkContentMetadata(Blob blob) {
|
||||
checkContentType(blob, "text/csv");
|
||||
checkContentDisposition(blob, "attachment; filename=photo.jpg");
|
||||
checkContentEncoding(blob, "gzip");
|
||||
checkContentLanguage(blob, "en");
|
||||
}
|
||||
|
||||
private void addContentMetadata(Blob blob) {
|
||||
blob.getMetadata().getContentMetadata().setContentType("text/csv");
|
||||
blob.getMetadata().getContentMetadata().setContentDisposition("attachment; filename=photo.jpg");
|
||||
blob.getMetadata().getContentMetadata().setContentEncoding("gzip");
|
||||
blob.getMetadata().getContentMetadata().setContentLanguage("en");
|
||||
}
|
||||
|
||||
protected void checkContentType(Blob blob, String contentType) {
|
||||
assert blob.getPayload().getContentType().startsWith(contentType) : blob.getPayload().getContentType();
|
||||
assert blob.getMetadata().getContentType().startsWith(contentType) : blob.getMetadata().getContentType();
|
||||
assert blob.getPayload().getContentMetadata().getContentType().startsWith(contentType) : blob.getPayload()
|
||||
.getContentMetadata().getContentType();
|
||||
assert blob.getMetadata().getContentMetadata().getContentType().startsWith(contentType) : blob.getMetadata()
|
||||
.getContentMetadata().getContentType();
|
||||
assert Iterables.getOnlyElement(blob.getAllHeaders().get(HttpHeaders.CONTENT_TYPE)).startsWith(contentType) : blob
|
||||
.getAllHeaders().get(HttpHeaders.CONTENT_TYPE);
|
||||
}
|
||||
|
||||
protected void checkContentDisposition(Blob blob, String contentDisposition) {
|
||||
assert blob.getPayload().getContentDisposition().startsWith(contentDisposition) : blob.getPayload()
|
||||
.getContentDisposition();
|
||||
assert blob.getMetadata().getContentDisposition().startsWith(contentDisposition) : blob.getMetadata()
|
||||
.getContentDisposition();
|
||||
assert Iterables.getOnlyElement(blob.getAllHeaders().get("Content-Disposition")).startsWith(contentDisposition) : blob
|
||||
.getAllHeaders().get("Content-Disposition");
|
||||
assert blob.getPayload().getContentMetadata().getContentDisposition().startsWith(contentDisposition) : blob
|
||||
.getPayload().getContentMetadata().getContentDisposition();
|
||||
assert blob.getMetadata().getContentMetadata().getContentDisposition().startsWith(contentDisposition) : blob
|
||||
.getMetadata().getContentMetadata().getContentDisposition();
|
||||
|
||||
}
|
||||
|
||||
protected void checkContentEncoding(Blob blob, String contentEncoding) {
|
||||
assert blob.getPayload().getContentEncoding().startsWith(contentEncoding) : blob.getPayload()
|
||||
.getContentEncoding();
|
||||
assert blob.getMetadata().getContentEncoding().startsWith(contentEncoding) : blob.getMetadata()
|
||||
.getContentEncoding();
|
||||
assert Iterables.getOnlyElement(blob.getAllHeaders().get(HttpHeaders.CONTENT_ENCODING)).startsWith(
|
||||
contentEncoding) : blob.getAllHeaders().get(HttpHeaders.CONTENT_ENCODING);
|
||||
assert blob.getPayload().getContentMetadata().getContentEncoding().startsWith(contentEncoding) : blob
|
||||
.getPayload().getContentMetadata().getContentEncoding();
|
||||
assert blob.getMetadata().getContentMetadata().getContentEncoding().startsWith(contentEncoding) : blob
|
||||
.getMetadata().getContentMetadata().getContentEncoding();
|
||||
|
||||
}
|
||||
|
||||
protected void checkContentLanguage(Blob blob, String contentLanguage) {
|
||||
assert blob.getPayload().getContentLanguage().startsWith(contentLanguage) : blob.getPayload()
|
||||
.getContentLanguage();
|
||||
assert blob.getMetadata().getContentLanguage().startsWith(contentLanguage) : blob.getMetadata()
|
||||
.getContentLanguage();
|
||||
assert Iterables.getOnlyElement(blob.getAllHeaders().get(HttpHeaders.CONTENT_LANGUAGE)).startsWith(
|
||||
contentLanguage) : blob.getAllHeaders().get(HttpHeaders.CONTENT_LANGUAGE);
|
||||
assert blob.getPayload().getContentMetadata().getContentLanguage().startsWith(contentLanguage) : blob
|
||||
.getPayload().getContentMetadata().getContentLanguage();
|
||||
assert blob.getMetadata().getContentMetadata().getContentLanguage().startsWith(contentLanguage) : blob
|
||||
.getMetadata().getContentMetadata().getContentLanguage();
|
||||
|
||||
}
|
||||
|
||||
protected volatile static Crypto crypto;
|
||||
|
@ -532,8 +542,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
Blob blob = context.getBlobStore().newBlob(key);
|
||||
blob.setPayload(TEST_STRING);
|
||||
blob.getMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||
blob.getMetadata().setSize(new Long(TEST_STRING.length()));
|
||||
blob.getMetadata().getContentMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||
// NOTE all metadata in jclouds comes out as lowercase, in an effort to
|
||||
// normalize the
|
||||
// providers.
|
||||
|
@ -565,10 +574,11 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
}
|
||||
|
||||
protected void validateMetadata(BlobMetadata metadata) throws IOException {
|
||||
assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType();
|
||||
assertEquals(metadata.getSize(), new Long(TEST_STRING.length()));
|
||||
assert metadata.getContentMetadata().getContentType().startsWith("text/plain") : metadata.getContentMetadata()
|
||||
.getContentType();
|
||||
assertEquals(metadata.getContentMetadata().getContentLength(), new Long(TEST_STRING.length()));
|
||||
assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff");
|
||||
assertEquals(metadata.getContentMD5(), CryptoStreams.md5(InputSuppliers.of(TEST_STRING)));
|
||||
assertEquals(metadata.getContentMetadata().getContentMD5(), CryptoStreams.md5(InputSuppliers.of(TEST_STRING)));
|
||||
}
|
||||
|
||||
}
|
|
@ -63,12 +63,12 @@ public class BaseBlobLiveTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
Blob blob = context.getBlobStore().newBlob(name);
|
||||
blob.setPayload(input);
|
||||
blob.getPayload().setContentLength(length);
|
||||
blob.getPayload().setContentMD5(md5);
|
||||
blob.getPayload().getContentMetadata().setContentLength(length);
|
||||
blob.getPayload().getContentMetadata().setContentMD5(md5);
|
||||
String container = getContainerName();
|
||||
try {
|
||||
context.getBlobStore().putBlob(container, blob);
|
||||
assertEquals(context.getBlobStore().blobMetadata(container, name).getContentMD5(), md5);
|
||||
assertEquals(context.getBlobStore().blobMetadata(container, name).getContentMetadata().getContentMD5(), md5);
|
||||
} finally {
|
||||
returnContainer(container);
|
||||
}
|
||||
|
|
|
@ -197,7 +197,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest<
|
|||
for (String key : fiveInputs.keySet()) {
|
||||
Blob blob = context.getBlobStore().newBlob(key);
|
||||
blob.setPayload(fiveInputs.get(key));
|
||||
blob.getPayload().setContentLength((long) fiveBytes.get(key).length);
|
||||
blob.getPayload().getContentMetadata().setContentLength((long) fiveBytes.get(key).length);
|
||||
newMap.put(key, blob);
|
||||
}
|
||||
map.putAll(newMap);
|
||||
|
|
|
@ -43,7 +43,7 @@ public class BaseBlobSignerLiveTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
Blob blob = context.getBlobStore().newBlob(name);
|
||||
blob.setPayload(text);
|
||||
blob.getPayload().setContentType("text/plain");
|
||||
blob.getPayload().getContentMetadata().setContentType("text/plain");
|
||||
String container = getContainerName();
|
||||
try {
|
||||
context.getBlobStore().putBlob(container, blob);
|
||||
|
@ -63,7 +63,7 @@ public class BaseBlobSignerLiveTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
Blob blob = context.getBlobStore().newBlob(name);
|
||||
blob.setPayload(text);
|
||||
blob.getPayload().setContentType("text/plain");
|
||||
blob.getPayload().getContentMetadata().setContentType("text/plain");
|
||||
String container = getContainerName();
|
||||
try {
|
||||
context.getBlobStore().putBlob(container, blob);
|
||||
|
@ -82,7 +82,7 @@ public class BaseBlobSignerLiveTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
Blob blob = context.getBlobStore().newBlob(name);
|
||||
blob.setPayload(text);
|
||||
blob.getPayload().setContentType("text/plain");
|
||||
blob.getPayload().getContentMetadata().setContentType("text/plain");
|
||||
String container = getContainerName();
|
||||
try {
|
||||
HttpRequest request = context.getSigner().signPutBlob(container, blob);
|
||||
|
|
|
@ -240,15 +240,15 @@ public class BaseBlobStoreIntegrationTest {
|
|||
protected String addBlobToContainer(String sourceContainer, String key) {
|
||||
Blob sourceObject = context.getBlobStore().newBlob(key);
|
||||
sourceObject.setPayload(TEST_STRING);
|
||||
sourceObject.getMetadata().setContentType("text/xml");
|
||||
sourceObject.getMetadata().getContentMetadata().setContentType("text/xml");
|
||||
return addBlobToContainer(sourceContainer, sourceObject);
|
||||
}
|
||||
|
||||
protected void add5BlobsUnderPathAnd5UnderRootToContainer(String sourceContainer) {
|
||||
for (Entry<String, String> entry : Iterables.concat(fiveStrings.entrySet(), fiveStringsUnderPath.entrySet())) {
|
||||
Blob sourceObject = context.getBlobStore().newBlob(entry.getKey());
|
||||
sourceObject.getMetadata().setContentType("text/xml");
|
||||
sourceObject.setPayload(entry.getValue());
|
||||
sourceObject.getMetadata().getContentMetadata().setContentType("text/xml");
|
||||
addBlobToContainer(sourceContainer, sourceObject);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,8 +77,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
Blob object = context.getBlobStore().newBlob(key);
|
||||
object.setPayload(TEST_STRING);
|
||||
object.getMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||
object.getMetadata().setSize(new Long(TEST_STRING.length()));
|
||||
object.getMetadata().getContentMetadata().setContentType(MediaType.TEXT_PLAIN);
|
||||
// NOTE all metadata in jclouds comes out as lowercase, in an effort to
|
||||
// normalize the
|
||||
// providers.
|
||||
|
@ -94,10 +93,10 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
BlobMetadata metadata = BlobMetadata.class.cast(get(container, 0));
|
||||
|
||||
assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType();
|
||||
assertEquals(metadata.getSize(), new Long(TEST_STRING.length()));
|
||||
assert metadata.getContentMetadata().getContentType().startsWith("text/plain") : metadata.getContentMetadata().getContentType();
|
||||
assertEquals(metadata.getContentMetadata().getContentLength(), new Long(TEST_STRING.length()));
|
||||
assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff");
|
||||
assertEquals(metadata.getContentMD5(), CryptoStreams.md5(InputSuppliers.of(TEST_STRING)));
|
||||
assertEquals(metadata.getContentMetadata().getContentMD5(), CryptoStreams.md5(InputSuppliers.of(TEST_STRING)));
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
|
|
@ -257,7 +257,7 @@ public class TemplateOptions {
|
|||
checkArgument(checkNotNull(privateKey, "privateKey").startsWith("-----BEGIN RSA PRIVATE KEY-----"),
|
||||
"key should start with -----BEGIN RSA PRIVATE KEY-----");
|
||||
Payload payload = newStringPayload(privateKey);
|
||||
payload.setContentType("text/plain");
|
||||
payload.getContentMetadata().setContentType("text/plain");
|
||||
return installPrivateKey(payload);
|
||||
}
|
||||
|
||||
|
@ -300,7 +300,7 @@ public class TemplateOptions {
|
|||
public TemplateOptions authorizePublicKey(String publicKey) {
|
||||
checkArgument(checkNotNull(publicKey, "publicKey").startsWith("ssh-rsa"), "key should start with ssh-rsa");
|
||||
Payload payload = newStringPayload(publicKey);
|
||||
payload.setContentType("text/plain");
|
||||
payload.getContentMetadata().setContentType("text/plain");
|
||||
return authorizePublicKey(payload);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ import static com.google.common.collect.Sets.newTreeSet;
|
|||
import static com.google.common.io.ByteStreams.toByteArray;
|
||||
import static com.google.common.io.Closeables.closeQuietly;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static javax.ws.rs.core.HttpHeaders.CONTENT_ENCODING;
|
||||
import static javax.ws.rs.core.HttpHeaders.CONTENT_LANGUAGE;
|
||||
import static javax.ws.rs.core.HttpHeaders.CONTENT_LENGTH;
|
||||
import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
|
||||
import static javax.ws.rs.core.HttpHeaders.HOST;
|
||||
|
@ -52,6 +54,7 @@ import java.net.URI;
|
|||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -69,7 +72,9 @@ import javax.ws.rs.core.UriBuilder;
|
|||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
import org.jclouds.io.InputSuppliers;
|
||||
import org.jclouds.io.MutableContentMetadata;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.PayloadEnclosing;
|
||||
import org.jclouds.io.Payloads;
|
||||
|
@ -200,6 +205,21 @@ public class HttpUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void addContentHeadersFromMetadata(ContentMetadata md, Multimap<String, String> allHeaders) {
|
||||
if (md.getContentType() != null)
|
||||
allHeaders.replaceValues(HttpHeaders.CONTENT_TYPE, Collections.singleton(md.getContentType()));
|
||||
if (md.getContentDisposition() != null)
|
||||
allHeaders.replaceValues("Content-Disposition", Collections.singleton(md.getContentDisposition()));
|
||||
if (md.getContentEncoding() != null)
|
||||
allHeaders.replaceValues(HttpHeaders.CONTENT_ENCODING, Collections.singleton(md.getContentEncoding()));
|
||||
if (md.getContentEncoding() != null)
|
||||
allHeaders.replaceValues(HttpHeaders.CONTENT_LANGUAGE, Collections.singleton(md.getContentLanguage()));
|
||||
if (md.getContentLength() != null)
|
||||
allHeaders.replaceValues(HttpHeaders.CONTENT_LENGTH, Collections.singleton(md.getContentLength() + ""));
|
||||
if (md.getContentMD5() != null)
|
||||
allHeaders.replaceValues("Content-MD5", Collections.singleton(CryptoStreams.base64(md.getContentMD5())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Web browsers do not always handle '+' characters well, use the well-supported '%20' instead.
|
||||
*/
|
||||
|
@ -255,13 +275,23 @@ public class HttpUtils {
|
|||
byte[] returnVal = toByteArrayOrNull(response);
|
||||
if (returnVal != null && !response.getPayload().isRepeatable()) {
|
||||
Payload newPayload = Payloads.newByteArrayPayload(returnVal);
|
||||
newPayload.setContentMD5(response.getPayload().getContentMD5());
|
||||
newPayload.setContentType(response.getPayload().getContentType());
|
||||
MutableContentMetadata fromMd = response.getPayload().getContentMetadata();
|
||||
MutableContentMetadata toMd = newPayload.getContentMetadata();
|
||||
copy(fromMd, toMd);
|
||||
response.setPayload(newPayload);
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
public static void copy(ContentMetadata fromMd, MutableContentMetadata toMd) {
|
||||
toMd.setContentLength(fromMd.getContentLength());
|
||||
toMd.setContentMD5(fromMd.getContentMD5());
|
||||
toMd.setContentType(fromMd.getContentType());
|
||||
toMd.setContentDisposition(fromMd.getContentDisposition());
|
||||
toMd.setContentEncoding(fromMd.getContentEncoding());
|
||||
toMd.setContentLanguage(fromMd.getContentLanguage());
|
||||
}
|
||||
|
||||
public static URI parseEndPoint(String hostHeader) {
|
||||
URI redirectURI = URI.create(hostHeader);
|
||||
String scheme = redirectURI.getScheme();
|
||||
|
@ -338,17 +368,27 @@ public class HttpUtils {
|
|||
logger.debug("%s %s: %s", prefix, header.getKey(), header.getValue());
|
||||
}
|
||||
if (message.getPayload() != null) {
|
||||
if (message.getPayload().getContentType() != null)
|
||||
logger.debug("%s %s: %s", prefix, HttpHeaders.CONTENT_TYPE, message.getPayload().getContentType());
|
||||
if (message.getPayload().getContentLength() != null)
|
||||
logger.debug("%s %s: %s", prefix, HttpHeaders.CONTENT_LENGTH, message.getPayload().getContentLength());
|
||||
if (message.getPayload().getContentMD5() != null)
|
||||
if (message.getPayload().getContentMetadata().getContentType() != null)
|
||||
logger.debug("%s %s: %s", prefix, CONTENT_TYPE, message.getPayload().getContentMetadata().getContentType());
|
||||
if (message.getPayload().getContentMetadata().getContentLength() != null)
|
||||
logger.debug("%s %s: %s", prefix, CONTENT_LENGTH, message.getPayload().getContentMetadata()
|
||||
.getContentLength());
|
||||
if (message.getPayload().getContentMetadata().getContentMD5() != null)
|
||||
try {
|
||||
logger.debug("%s %s: %s", prefix, "Content-MD5", CryptoStreams.base64Encode(InputSuppliers.of(message
|
||||
.getPayload().getContentMD5())));
|
||||
.getPayload().getContentMetadata().getContentMD5())));
|
||||
} catch (IOException e) {
|
||||
logger.warn(e, " error getting md5 for %s", message);
|
||||
}
|
||||
if (message.getPayload().getContentMetadata().getContentDisposition() != null)
|
||||
logger.debug("%s %s: %s", prefix, "Content-Disposition", message.getPayload().getContentMetadata()
|
||||
.getContentDisposition());
|
||||
if (message.getPayload().getContentMetadata().getContentEncoding() != null)
|
||||
logger.debug("%s %s: %s", prefix, CONTENT_ENCODING, message.getPayload().getContentMetadata()
|
||||
.getContentEncoding());
|
||||
if (message.getPayload().getContentMetadata().getContentLanguage() != null)
|
||||
logger.debug("%s %s: %s", prefix, CONTENT_LANGUAGE, message.getPayload().getContentMetadata()
|
||||
.getContentLanguage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -503,16 +543,22 @@ public class HttpUtils {
|
|||
for (Entry<String, String> header : headers.entries()) {
|
||||
if (!chunked && CONTENT_LENGTH.equalsIgnoreCase(header.getKey())) {
|
||||
if (payload != null)
|
||||
payload.setContentLength(new Long(header.getValue()));
|
||||
payload.getContentMetadata().setContentLength(new Long(header.getValue()));
|
||||
} else if ("Content-MD5".equalsIgnoreCase(header.getKey())) {
|
||||
if (payload != null)
|
||||
payload.setContentMD5(CryptoStreams.base64(header.getValue()));
|
||||
payload.getContentMetadata().setContentMD5(CryptoStreams.base64(header.getValue()));
|
||||
} else if (CONTENT_TYPE.equalsIgnoreCase(header.getKey())) {
|
||||
if (payload != null)
|
||||
payload.setContentType(header.getValue());
|
||||
payload.getContentMetadata().setContentType(header.getValue());
|
||||
} else if ("Content-Disposition".equalsIgnoreCase(header.getKey())) {
|
||||
if (payload != null)
|
||||
payload.setContentDisposition(header.getValue());
|
||||
payload.getContentMetadata().setContentDisposition(header.getValue());
|
||||
} else if ("Content-Encoding".equalsIgnoreCase(header.getKey())) {
|
||||
if (payload != null)
|
||||
payload.getContentMetadata().setContentEncoding(header.getValue());
|
||||
} else if ("Content-Language".equalsIgnoreCase(header.getKey())) {
|
||||
if (payload != null)
|
||||
payload.getContentMetadata().setContentLanguage(header.getValue());
|
||||
} else {
|
||||
message.getHeaders().put(header.getKey(), header.getValue());
|
||||
}
|
||||
|
@ -521,19 +567,34 @@ public class HttpUtils {
|
|||
if (message instanceof HttpRequest) {
|
||||
checkArgument(
|
||||
message.getPayload() == null || message.getFirstHeaderOrNull(CONTENT_TYPE) == null,
|
||||
"configuration error please use request.getPayload().setContentType(value) as opposed to adding a content type header: "
|
||||
"configuration error please use request.getPayload().getContentMetadata().setContentType(value) as opposed to adding a content type header: "
|
||||
+ message);
|
||||
checkArgument(
|
||||
message.getPayload() == null || message.getFirstHeaderOrNull(CONTENT_LENGTH) == null,
|
||||
"configuration error please use request.getPayload().setContentLength(value) as opposed to adding a content length header: "
|
||||
"configuration error please use request.getPayload().getContentMetadata().setContentLength(value) as opposed to adding a content length header: "
|
||||
+ message);
|
||||
checkArgument(message.getPayload() == null || message.getPayload().getContentLength() != null
|
||||
checkArgument(message.getPayload() == null
|
||||
|| message.getPayload().getContentMetadata().getContentLength() != null
|
||||
|| "chunked".equalsIgnoreCase(message.getFirstHeaderOrNull("Transfer-Encoding")),
|
||||
"either chunked encoding must be set on the http request or contentlength set on the payload: "
|
||||
+ message);
|
||||
checkArgument(message.getPayload() == null || message.getFirstHeaderOrNull("Content-MD5") == null,
|
||||
"configuration error please use request.getPayload().setContentMD5(value) as opposed to adding a content md5 header: "
|
||||
checkArgument(
|
||||
message.getPayload() == null || message.getFirstHeaderOrNull("Content-MD5") == null,
|
||||
"configuration error please use request.getPayload().getContentMetadata().setContentMD5(value) as opposed to adding a content md5 header: "
|
||||
+ message);
|
||||
checkArgument(
|
||||
message.getPayload() == null || message.getFirstHeaderOrNull("Content-Disposition") == null,
|
||||
"configuration error please use request.getPayload().getContentMetadata().setContentDisposition(value) as opposed to adding a content disposition header: "
|
||||
+ message);
|
||||
checkArgument(
|
||||
message.getPayload() == null || message.getFirstHeaderOrNull(CONTENT_ENCODING) == null,
|
||||
"configuration error please use request.getPayload().getContentMetadata().setContentEncoding(value) as opposed to adding a content encoding header: "
|
||||
+ message);
|
||||
checkArgument(
|
||||
message.getPayload() == null || message.getFirstHeaderOrNull(CONTENT_LANGUAGE) == null,
|
||||
"configuration error please use request.getPayload().getContentMetadata().setContentLanguage(value) as opposed to adding a content language header: "
|
||||
+ message);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -557,7 +618,7 @@ public class HttpUtils {
|
|||
public static Long attemptToParseSizeAndRangeFromHeaders(HttpResponse from) throws HttpException {
|
||||
String contentRange = from.getFirstHeaderOrNull("Content-Range");
|
||||
if (contentRange == null && from.getPayload() != null) {
|
||||
return from.getPayload().getContentLength();
|
||||
return from.getPayload().getContentMetadata().getContentLength();
|
||||
} else if (contentRange != null) {
|
||||
return Long.parseLong(contentRange.substring(contentRange.lastIndexOf('/') + 1));
|
||||
}
|
||||
|
@ -566,7 +627,8 @@ public class HttpUtils {
|
|||
|
||||
public static void checkRequestHasContentLengthOrChunkedEncoding(HttpRequest request, String message) {
|
||||
boolean chunked = "chunked".equals(request.getFirstHeaderOrNull("Transfer-Encoding"));
|
||||
checkArgument(request.getPayload() == null || chunked || request.getPayload().getContentLength() != null, message);
|
||||
checkArgument(request.getPayload() == null || chunked
|
||||
|| request.getPayload().getContentMetadata().getContentLength() != null, message);
|
||||
}
|
||||
|
||||
public static void wirePayloadIfEnabled(Wire wire, HttpRequest request) {
|
||||
|
|
|
@ -33,8 +33,7 @@ import com.google.common.base.Function;
|
|||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ParseContentMD5FromHeaders implements Function<HttpResponse, byte[]>,
|
||||
InvocationContext {
|
||||
public class ParseContentMD5FromHeaders implements Function<HttpResponse, byte[]>, InvocationContext {
|
||||
|
||||
public static class NoContentMD5Exception extends RuntimeException {
|
||||
|
||||
|
@ -65,7 +64,7 @@ public class ParseContentMD5FromHeaders implements Function<HttpResponse, byte[]
|
|||
public byte[] apply(HttpResponse from) {
|
||||
releasePayload(from);
|
||||
if (from.getPayload() != null) {
|
||||
return from.getPayload().getContentMD5();
|
||||
return from.getPayload().getContentMetadata().getContentMD5();
|
||||
}
|
||||
throw new NoContentMD5Exception(request, from);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ import org.jclouds.http.HttpUtils;
|
|||
import org.jclouds.http.IOExceptionRetryHandler;
|
||||
import org.jclouds.http.handlers.DelegatingErrorHandler;
|
||||
import org.jclouds.http.handlers.DelegatingRetryHandler;
|
||||
import org.jclouds.io.MutableContentMetadata;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
@ -197,20 +198,21 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
|
|||
connection.setRequestProperty(HttpHeaders.USER_AGENT, USER_AGENT);
|
||||
|
||||
if (request.getPayload() != null) {
|
||||
if (request.getPayload().getContentMD5() != null)
|
||||
connection.setRequestProperty("Content-MD5", CryptoStreams.base64(request.getPayload().getContentMD5()));
|
||||
if (request.getPayload().getContentType() != null)
|
||||
connection.setRequestProperty(HttpHeaders.CONTENT_TYPE, request.getPayload().getContentType());
|
||||
if (request.getPayload().getContentDisposition() != null)
|
||||
connection.setRequestProperty("Content-Disposition", request.getPayload().getContentDisposition());
|
||||
if (request.getPayload().getContentEncoding() != null)
|
||||
connection.setRequestProperty("Content-Encoding", request.getPayload().getContentEncoding());
|
||||
if (request.getPayload().getContentLanguage() != null)
|
||||
connection.setRequestProperty("Content-Language", request.getPayload().getContentLanguage());
|
||||
MutableContentMetadata md = request.getPayload().getContentMetadata();
|
||||
if (md.getContentMD5() != null)
|
||||
connection.setRequestProperty("Content-MD5", CryptoStreams.base64(md.getContentMD5()));
|
||||
if (md.getContentType() != null)
|
||||
connection.setRequestProperty(HttpHeaders.CONTENT_TYPE, md.getContentType());
|
||||
if (md.getContentDisposition() != null)
|
||||
connection.setRequestProperty("Content-Disposition", md.getContentDisposition());
|
||||
if (md.getContentEncoding() != null)
|
||||
connection.setRequestProperty("Content-Encoding", md.getContentEncoding());
|
||||
if (md.getContentLanguage() != null)
|
||||
connection.setRequestProperty("Content-Language", md.getContentLanguage());
|
||||
if (chunked) {
|
||||
connection.setChunkedStreamingMode(8196);
|
||||
} else {
|
||||
Long length = checkNotNull(request.getPayload().getContentLength(), "payload.getContentLength");
|
||||
Long length = checkNotNull(md.getContentLength(), "payload.getContentLength");
|
||||
connection.setRequestProperty(HttpHeaders.CONTENT_LENGTH, length.toString());
|
||||
connection.setFixedLengthStreamingMode(length.intValue());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.io;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface ContentMetadata {
|
||||
|
||||
/**
|
||||
* Returns the total size of the payload, or the chunk that's available.
|
||||
* <p/>
|
||||
* Chunking is only used when {@link 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 #getInput()}
|
||||
* @see javax.ws.rs.core.HttpHeaders#CONTENT_LENGTH
|
||||
* @see org.jclouds.http.options.GetOptions
|
||||
*/
|
||||
@Nullable
|
||||
Long getContentLength();
|
||||
|
||||
/**
|
||||
* Specifies presentational information for the object.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html?sec19.5.1."/>
|
||||
*/
|
||||
@Nullable
|
||||
String getContentDisposition();
|
||||
|
||||
/**
|
||||
* Specifies what content encodings have been applied to the object and thus what decoding
|
||||
* mechanisms must be applied in order to obtain the media-type referenced by the Content-Type
|
||||
* header field.
|
||||
*
|
||||
* @see <a href= "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html?sec14.11" />
|
||||
*/
|
||||
@Nullable
|
||||
String getContentEncoding();
|
||||
|
||||
/**
|
||||
*
|
||||
* 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"/>
|
||||
*/
|
||||
@Nullable
|
||||
String getContentType();
|
||||
|
||||
@Nullable
|
||||
byte[] getContentMD5();
|
||||
|
||||
/**
|
||||
* Get Content Language of the payload
|
||||
* <p/>
|
||||
* Not all providers may support it
|
||||
*/
|
||||
@Nullable
|
||||
String getContentLanguage();
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.io;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface MutableContentMetadata extends ContentMetadata {
|
||||
|
||||
void setContentLength(@Nullable Long contentLength);
|
||||
|
||||
void setContentMD5(@Nullable byte[] md5);
|
||||
|
||||
void setContentType(@Nullable String md5);
|
||||
|
||||
/**
|
||||
* Set Content Disposition of the payload
|
||||
* <p/>
|
||||
* Not all providers may support it
|
||||
*
|
||||
* @param contentDisposition
|
||||
*/
|
||||
void setContentDisposition(@Nullable String contentDisposition);
|
||||
|
||||
/**
|
||||
* Set Content Language of the payload
|
||||
* <p/>
|
||||
* Not all providers may support it
|
||||
*
|
||||
* @param contentLanguage
|
||||
*/
|
||||
void setContentLanguage(@Nullable String contentLanguage);
|
||||
|
||||
/**
|
||||
* Set Content Encoding of the payload
|
||||
* <p/>
|
||||
* Not all providers may support it
|
||||
*
|
||||
* @param contentEncoding
|
||||
*/
|
||||
void setContentEncoding(@Nullable String contentEncoding);
|
||||
|
||||
}
|
|
@ -22,8 +22,6 @@ package org.jclouds.io;
|
|||
import java.io.Closeable;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.io.InputSupplier;
|
||||
|
||||
/**
|
||||
|
@ -46,86 +44,13 @@ public interface Payload extends InputSupplier<InputStream>, WriteTo, Closeable
|
|||
*/
|
||||
boolean isRepeatable();
|
||||
|
||||
void setContentLength(@Nullable Long contentLength);
|
||||
|
||||
/**
|
||||
* Returns the total size of the payload, or the chunk that's available.
|
||||
* <p/>
|
||||
* Chunking is only used when {@link 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 #getInput()}
|
||||
* @see javax.ws.rs.core.HttpHeaders#CONTENT_LENGTH
|
||||
* @see org.jclouds.http.options.GetOptions
|
||||
*/
|
||||
@Nullable
|
||||
Long getContentLength();
|
||||
|
||||
void setContentMD5(@Nullable byte[] md5);
|
||||
|
||||
@Nullable
|
||||
byte[] getContentMD5();
|
||||
|
||||
void setContentType(@Nullable String md5);
|
||||
|
||||
@Nullable
|
||||
String getContentType();
|
||||
|
||||
/**
|
||||
* Set Content Disposition of the payload
|
||||
* <p/>
|
||||
* Not all providers may support it
|
||||
*
|
||||
* @param contentDisposition
|
||||
*/
|
||||
void setContentDisposition(@Nullable String contentDisposition);
|
||||
|
||||
/**
|
||||
* Get Content Disposition of the payload
|
||||
* <p/>
|
||||
* Not all providers may support it
|
||||
*/
|
||||
@Nullable
|
||||
String getContentDisposition();
|
||||
|
||||
/**
|
||||
* Set Content Language of the payload
|
||||
* <p/>
|
||||
* Not all providers may support it
|
||||
*
|
||||
* @param contentLanguage
|
||||
*/
|
||||
void setContentLanguage(@Nullable String contentLanguage);
|
||||
|
||||
/**
|
||||
* Get Content Language of the payload
|
||||
* <p/>
|
||||
* Not all providers may support it
|
||||
*/
|
||||
@Nullable
|
||||
String getContentLanguage();
|
||||
|
||||
/**
|
||||
* Set Content Encoding of the payload
|
||||
* <p/>
|
||||
* Not all providers may support it
|
||||
*
|
||||
* @param contentEncoding
|
||||
*/
|
||||
void setContentEncoding(@Nullable String contentEncoding);
|
||||
|
||||
/**
|
||||
* Get Content Encoding of the payload
|
||||
* <p/>
|
||||
* Not all providers may support it
|
||||
*/
|
||||
@Nullable
|
||||
String getContentEncoding();
|
||||
|
||||
/**
|
||||
* release resources used by this entity. This should be called when data is
|
||||
* discarded.
|
||||
* release resources used by this entity. This should be called when data is discarded.
|
||||
*/
|
||||
void release();
|
||||
|
||||
MutableContentMetadata getContentMetadata();
|
||||
|
||||
void setContentMetadata(MutableContentMetadata in);
|
||||
|
||||
}
|
|
@ -109,16 +109,16 @@ public class Payloads {
|
|||
public static Payload calculateMD5(Payload payload, MessageDigest md5) throws IOException {
|
||||
checkNotNull(payload, "payload");
|
||||
if (!payload.isRepeatable()) {
|
||||
String oldContentType = payload.getContentType();
|
||||
String oldContentType = payload.getContentMetadata().getContentType();
|
||||
Payload oldPayload = payload;
|
||||
try {
|
||||
payload = newByteArrayPayload(toByteArray(payload));
|
||||
} finally {
|
||||
oldPayload.release();
|
||||
}
|
||||
payload.setContentType(oldContentType);
|
||||
payload.getContentMetadata().setContentType(oldContentType);
|
||||
}
|
||||
payload.setContentMD5(CryptoStreams.digest(payload, md5));
|
||||
payload.getContentMetadata().setContentMD5(CryptoStreams.digest(payload, md5));
|
||||
return payload;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.io.payloads;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BaseImmutableContentMetadata implements ContentMetadata, Serializable {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -1445533440795766130L;
|
||||
protected String contentType;
|
||||
protected Long contentLength;
|
||||
protected byte[] contentMD5;
|
||||
protected String contentDisposition;
|
||||
protected String contentLanguage;
|
||||
protected String contentEncoding;
|
||||
|
||||
public BaseImmutableContentMetadata(String contentType, Long contentLength, byte[] contentMD5,
|
||||
String contentDisposition, String contentLanguage, String contentEncoding) {
|
||||
this.contentType = contentType;
|
||||
this.contentLength = contentLength;
|
||||
this.contentMD5 = contentMD5;
|
||||
this.contentDisposition = contentDisposition;
|
||||
this.contentLanguage = contentLanguage;
|
||||
this.contentEncoding = contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Long getContentLength() {
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentDisposition() {
|
||||
return this.contentDisposition;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentLanguage() {
|
||||
return this.contentLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getContentEncoding() {
|
||||
return this.contentEncoding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[contentType=" + contentType + ", contentLength=" + contentLength + ", contentDisposition="
|
||||
+ contentDisposition + ", contentEncoding=" + contentEncoding + ", contentLanguage=" + contentLanguage
|
||||
+ ", contentMD5=" + Arrays.toString(contentMD5) + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((contentDisposition == null) ? 0 : contentDisposition.hashCode());
|
||||
result = prime * result + ((contentEncoding == null) ? 0 : contentEncoding.hashCode());
|
||||
result = prime * result + ((contentLanguage == null) ? 0 : contentLanguage.hashCode());
|
||||
result = prime * result + ((contentLength == null) ? 0 : contentLength.hashCode());
|
||||
result = prime * result + Arrays.hashCode(contentMD5);
|
||||
result = prime * result + ((contentType == null) ? 0 : contentType.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;
|
||||
BaseImmutableContentMetadata other = (BaseImmutableContentMetadata) obj;
|
||||
if (contentDisposition == null) {
|
||||
if (other.contentDisposition != null)
|
||||
return false;
|
||||
} else if (!contentDisposition.equals(other.contentDisposition))
|
||||
return false;
|
||||
if (contentEncoding == null) {
|
||||
if (other.contentEncoding != null)
|
||||
return false;
|
||||
} else if (!contentEncoding.equals(other.contentEncoding))
|
||||
return false;
|
||||
if (contentLanguage == null) {
|
||||
if (other.contentLanguage != null)
|
||||
return false;
|
||||
} else if (!contentLanguage.equals(other.contentLanguage))
|
||||
return false;
|
||||
if (contentLength == null) {
|
||||
if (other.contentLength != null)
|
||||
return false;
|
||||
} else if (!contentLength.equals(other.contentLength))
|
||||
return false;
|
||||
if (!Arrays.equals(contentMD5, other.contentMD5))
|
||||
return false;
|
||||
if (contentType == null) {
|
||||
if (other.contentType != null)
|
||||
return false;
|
||||
} else if (!contentType.equals(other.contentType))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue