mirror of https://github.com/apache/jclouds.git
JCLOUDS-597: HashCode methods for Content-MD5
This works more naturally with Guava Hashing methods and immutability provides better safety guarantees. Also deprecate existing byte[] methods.
This commit is contained in:
parent
446671a2a7
commit
e799a7409c
|
@ -23,6 +23,8 @@ import org.jclouds.atmos.domain.MutableContentMetadata;
|
|||
import org.jclouds.io.ContentMetadataBuilder;
|
||||
import org.jclouds.io.payloads.BaseMutableContentMetadata;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
|
||||
public class DelegatingMutableContentMetadata implements MutableContentMetadata {
|
||||
private URI uri;
|
||||
private String name;
|
||||
|
@ -46,11 +48,18 @@ public class DelegatingMutableContentMetadata implements MutableContentMetadata
|
|||
return delegate.getContentLength();
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #getContentMD5AsHashCode()} instead. */
|
||||
@Deprecated
|
||||
@Override
|
||||
public byte[] getContentMD5() {
|
||||
return delegate.getContentMD5();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashCode getContentMD5AsHashCode() {
|
||||
return delegate.getContentMD5AsHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return delegate.getContentType();
|
||||
|
@ -66,11 +75,18 @@ public class DelegatingMutableContentMetadata implements MutableContentMetadata
|
|||
delegate.setContentLength(contentLength);
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #setContentMD5(HashCode)} instead. */
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setContentMD5(byte[] contentMD5) {
|
||||
delegate.setContentMD5(contentMD5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentMD5(HashCode contentMD5) {
|
||||
delegate.setContentMD5(contentMD5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String contentType) {
|
||||
delegate.setContentType(contentType);
|
||||
|
|
|
@ -201,7 +201,7 @@ public class FilesystemStorageStrategyImpl implements LocalStorageStrategy {
|
|||
Files.createParentDirs(outputFile);
|
||||
his = new HashingInputStream(Hashing.md5(), payload.openStream());
|
||||
Files.asByteSink(outputFile).writeFrom(his);
|
||||
payload.getContentMetadata().setContentMD5(his.hash().asBytes());
|
||||
payload.getContentMetadata().setContentMD5(his.hash());
|
||||
String eTag = base16().lowerCase().encode(payload.getContentMetadata().getContentMD5());
|
||||
return eTag;
|
||||
} catch (IOException ex) {
|
||||
|
|
|
@ -160,11 +160,11 @@ public class TransientStorageStrategy implements LocalStorageStrategy {
|
|||
MutableContentMetadata oldMd = in.getPayload().getContentMetadata();
|
||||
byte[] out = ByteStreams.toByteArray(in.getPayload());
|
||||
payload = Payloads.newByteArrayPayload(out);
|
||||
payload.getContentMetadata().setContentMD5(Hashing.md5().hashBytes(out).asBytes());
|
||||
HttpUtils.copy(oldMd, payload.getContentMetadata());
|
||||
payload.getContentMetadata().setContentMD5(Hashing.md5().hashBytes(out));
|
||||
} else {
|
||||
if (payload.getContentMetadata().getContentMD5() == null) {
|
||||
payload.getContentMetadata().setContentMD5(ByteStreams.hash(payload, Hashing.md5()).asBytes());
|
||||
payload.getContentMetadata().setContentMD5(ByteStreams.hash(payload, Hashing.md5()));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Map;
|
|||
import org.jclouds.blobstore.domain.internal.BlobBuilderImpl;
|
||||
import org.jclouds.io.Payload;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.common.net.MediaType;
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
@ -115,8 +116,12 @@ public interface BlobBuilder {
|
|||
|
||||
PayloadBlobBuilder contentLength(long contentLength);
|
||||
|
||||
/** @deprecated use {@link #contentMD5(HashCode)} instead. */
|
||||
@Deprecated
|
||||
PayloadBlobBuilder contentMD5(byte[] md5);
|
||||
|
||||
PayloadBlobBuilder contentMD5(HashCode md5);
|
||||
|
||||
PayloadBlobBuilder contentType(MediaType contentType);
|
||||
|
||||
PayloadBlobBuilder contentType(String contentType);
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.jclouds.io.Payload;
|
|||
import org.jclouds.io.payloads.PhantomPayload;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.common.net.MediaType;
|
||||
|
||||
|
@ -185,8 +186,15 @@ public class BlobBuilderImpl implements BlobBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #contentMD5(HashCode)} instead. */
|
||||
@Deprecated
|
||||
@Override
|
||||
public PayloadBlobBuilder contentMD5(byte[] md5) {
|
||||
return contentMD5(md5 == null ? null : HashCode.fromBytes(md5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadBlobBuilder contentMD5(HashCode md5) {
|
||||
payload.getContentMetadata().setContentMD5(md5);
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -221,7 +221,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
blobStore.putBlob(container, blobStore.blobBuilder(name)
|
||||
.payload(new InputStreamSupplierPayload(supplier))
|
||||
.contentType("text/plain")
|
||||
.contentMD5(supplier.hash(md5()).asBytes())
|
||||
.contentMD5(supplier.hash(md5()))
|
||||
.contentLength(supplier.size())
|
||||
.contentDisposition(contentDisposition)
|
||||
.build());
|
||||
|
@ -280,7 +280,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
Blob blob = blobStore
|
||||
.blobBuilder(blobName)
|
||||
.payload(payload)
|
||||
.contentMD5(contentMD5.asBytes())
|
||||
.contentMD5(contentMD5)
|
||||
.build();
|
||||
blobStore.putBlob(container, blob);
|
||||
} finally {
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Set;
|
|||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
public interface ContentMetadata {
|
||||
|
@ -79,9 +80,14 @@ public interface ContentMetadata {
|
|||
@Nullable
|
||||
String getContentType();
|
||||
|
||||
/** @deprecated use {@link #getContentMD5AsHashCode()} instead. */
|
||||
@Deprecated
|
||||
@Nullable
|
||||
byte[] getContentMD5();
|
||||
|
||||
@Nullable
|
||||
HashCode getContentMD5AsHashCode();
|
||||
|
||||
/**
|
||||
* Get Content Language of the payload
|
||||
* <p/>
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
*/
|
||||
package org.jclouds.io;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
import org.jclouds.io.payloads.BaseImmutableContentMetadata;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.hash.HashCode;
|
||||
|
||||
public class ContentMetadataBuilder {
|
||||
|
||||
|
@ -32,7 +32,7 @@ public class ContentMetadataBuilder {
|
|||
|
||||
protected String contentType = "application/unknown";
|
||||
protected Long contentLength;
|
||||
protected byte[] contentMD5;
|
||||
protected HashCode contentMD5;
|
||||
protected String contentDisposition;
|
||||
protected String contentLanguage;
|
||||
protected String contentEncoding;
|
||||
|
@ -43,14 +43,17 @@ public class ContentMetadataBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ContentMetadataBuilder contentMD5(byte[] md5) {
|
||||
if (md5 != null) {
|
||||
byte[] retval = new byte[md5.length];
|
||||
System.arraycopy(md5, 0, retval, 0, md5.length);
|
||||
this.contentMD5 = md5;
|
||||
/** @deprecated use {@link #contentMD5(HashCode)} instead. */
|
||||
@Deprecated
|
||||
public ContentMetadataBuilder contentMD5(@Nullable byte[] contentMD5) {
|
||||
return contentMD5(contentMD5 == null ? null : HashCode.fromBytes(contentMD5));
|
||||
}
|
||||
|
||||
public ContentMetadataBuilder contentMD5(@Nullable HashCode contentMD5) {
|
||||
if (contentMD5 != null) {
|
||||
this.contentMD5 = contentMD5;
|
||||
}
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
public ContentMetadataBuilder contentType(@Nullable String contentType) {
|
||||
|
@ -80,7 +83,8 @@ public class ContentMetadataBuilder {
|
|||
}
|
||||
|
||||
public ContentMetadata build() {
|
||||
return new BaseImmutableContentMetadata(contentType, contentLength, contentMD5, contentDisposition,
|
||||
return new BaseImmutableContentMetadata(contentType, contentLength,
|
||||
contentMD5 == null ? null : contentMD5.asBytes(), contentDisposition,
|
||||
contentLanguage, contentEncoding, expires);
|
||||
}
|
||||
|
||||
|
@ -109,7 +113,7 @@ public class ContentMetadataBuilder {
|
|||
Objects.equal(contentEncoding, other.contentEncoding) &&
|
||||
Objects.equal(contentLanguage, other.contentLanguage) &&
|
||||
Objects.equal(contentLength, other.contentLength) &&
|
||||
Arrays.equals(contentMD5, other.contentMD5) &&
|
||||
Objects.equal(contentMD5, other.contentMD5) &&
|
||||
Objects.equal(contentType, other.contentType) &&
|
||||
Objects.equal(expires, other.expires);
|
||||
}
|
||||
|
@ -118,6 +122,6 @@ public class ContentMetadataBuilder {
|
|||
public String toString() {
|
||||
return "[contentDisposition=" + contentDisposition + ", contentEncoding=" + contentEncoding
|
||||
+ ", contentLanguage=" + contentLanguage + ", contentLength=" + contentLength + ", contentMD5="
|
||||
+ Arrays.toString(contentMD5) + ", contentType=" + contentType + ", expires=" + expires + "]";
|
||||
+ contentMD5 + ", contentType=" + contentType + ", expires=" + expires + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,18 @@ import java.util.Date;
|
|||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
|
||||
public interface MutableContentMetadata extends ContentMetadata {
|
||||
|
||||
void setContentLength(@Nullable Long contentLength);
|
||||
|
||||
/** @deprecated use {@link #setContentMD5(HashCode)} instead. */
|
||||
@Deprecated
|
||||
void setContentMD5(@Nullable byte[] md5);
|
||||
|
||||
void setContentMD5(@Nullable HashCode md5);
|
||||
|
||||
void setContentType(@Nullable String contentType);
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.jclouds.io.payloads.InputStreamPayload;
|
|||
import org.jclouds.io.payloads.InputStreamSupplierPayload;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.io.Files;
|
||||
|
@ -113,7 +114,7 @@ public class BasePayloadSlicer implements PayloadSlicer {
|
|||
|
||||
if (content.length > 0) {
|
||||
payload = new ByteArrayPayload(content);
|
||||
ContentMetadata cm = metaData.toBuilder().contentLength((long)content.length).contentMD5(null).build();
|
||||
ContentMetadata cm = metaData.toBuilder().contentLength((long)content.length).contentMD5((HashCode) null).build();
|
||||
payload.setContentMetadata(BaseMutableContentMetadata.fromContentMetadata(cm));
|
||||
}
|
||||
|
||||
|
@ -187,7 +188,7 @@ public class BasePayloadSlicer implements PayloadSlicer {
|
|||
|
||||
protected Payload copyMetadataAndSetLength(Payload input, Payload returnVal, long length) {
|
||||
returnVal.setContentMetadata(BaseMutableContentMetadata.fromContentMetadata(input.getContentMetadata()
|
||||
.toBuilder().contentLength(length).contentMD5(null).build()));
|
||||
.toBuilder().contentLength(length).contentMD5((HashCode) null).build()));
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
|
@ -199,7 +200,7 @@ public class BasePayloadSlicer implements PayloadSlicer {
|
|||
ContentMetadata meta = BaseMutableContentMetadata.fromContentMetadata(input.getContentMetadata())
|
||||
.toBuilder()
|
||||
.contentLength(size)
|
||||
.contentMD5(null)
|
||||
.contentMD5((HashCode) null)
|
||||
.build();
|
||||
Object rawContent = input.getRawContent();
|
||||
if (rawContent instanceof File) {
|
||||
|
|
|
@ -16,19 +16,19 @@
|
|||
*/
|
||||
package org.jclouds.io.payloads;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
import org.jclouds.io.ContentMetadata;
|
||||
import org.jclouds.io.ContentMetadataBuilder;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.hash.HashCode;
|
||||
|
||||
public class BaseImmutableContentMetadata implements ContentMetadata {
|
||||
|
||||
protected String contentType;
|
||||
protected Long contentLength;
|
||||
protected byte[] contentMD5;
|
||||
protected HashCode contentMD5;
|
||||
protected String contentDisposition;
|
||||
protected String contentLanguage;
|
||||
protected String contentEncoding;
|
||||
|
@ -38,7 +38,7 @@ public class BaseImmutableContentMetadata implements ContentMetadata {
|
|||
String contentDisposition, String contentLanguage, String contentEncoding, Date expires) {
|
||||
this.contentType = contentType;
|
||||
this.contentLength = contentLength;
|
||||
this.contentMD5 = contentMD5;
|
||||
this.contentMD5 = contentMD5 == null ? null : HashCode.fromBytes(contentMD5);
|
||||
this.contentDisposition = contentDisposition;
|
||||
this.contentLanguage = contentLanguage;
|
||||
this.contentEncoding = contentEncoding;
|
||||
|
@ -53,18 +53,17 @@ public class BaseImmutableContentMetadata implements ContentMetadata {
|
|||
return contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
/** @deprecated use {@link #getContentMD5AsHashCode()} instead. */
|
||||
@Deprecated
|
||||
@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;
|
||||
}
|
||||
HashCode hashCode = getContentMD5AsHashCode();
|
||||
return hashCode == null ? null : hashCode.asBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashCode getContentMD5AsHashCode() {
|
||||
return contentMD5;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,7 +110,7 @@ public class BaseImmutableContentMetadata implements ContentMetadata {
|
|||
public String toString() {
|
||||
return "[contentType=" + contentType + ", contentLength=" + contentLength + ", contentDisposition="
|
||||
+ contentDisposition + ", contentEncoding=" + contentEncoding + ", contentLanguage=" + contentLanguage
|
||||
+ ", contentMD5=" + Arrays.toString(contentMD5) + ", expires = " + expires + "]";
|
||||
+ ", contentMD5=" + contentMD5 + ", expires = " + expires + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -149,7 +148,7 @@ public class BaseImmutableContentMetadata implements ContentMetadata {
|
|||
return false;
|
||||
} else if (!contentLength.equals(other.contentLength))
|
||||
return false;
|
||||
if (!Arrays.equals(contentMD5, other.contentMD5))
|
||||
if (!Objects.equal(contentMD5, other.contentMD5))
|
||||
return false;
|
||||
if (contentType == null) {
|
||||
if (other.contentType != null)
|
||||
|
|
|
@ -23,6 +23,8 @@ import org.jclouds.io.ContentMetadataBuilder;
|
|||
import org.jclouds.io.MutableContentMetadata;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
|
||||
public class BaseMutableContentMetadata extends ContentMetadataBuilder implements MutableContentMetadata {
|
||||
|
||||
/**
|
||||
|
@ -41,25 +43,28 @@ public class BaseMutableContentMetadata extends ContentMetadataBuilder implement
|
|||
contentLength(contentLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
/** @deprecated use {@link #getContentMD5AsHashCode()} instead. */
|
||||
@Deprecated
|
||||
@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;
|
||||
}
|
||||
HashCode hashCode = getContentMD5AsHashCode();
|
||||
return hashCode == null ? null : hashCode.asBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public HashCode getContentMD5AsHashCode() {
|
||||
return contentMD5;
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #setContentMD5(HashCode)} instead. */
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setContentMD5(byte[] md5) {
|
||||
setContentMD5(md5 == null ? null : HashCode.fromBytes(md5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentMD5(HashCode md5) {
|
||||
contentMD5(md5);
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ public class AWSS3ClientExpectTest extends BaseAWSS3ClientExpectTest {
|
|||
|
||||
final Payload requestPayload = Payloads.newStringPayload(request);
|
||||
requestPayload.getContentMetadata().setContentType("text/xml");
|
||||
requestPayload.getContentMetadata().setContentMD5(md5().hashString(request, UTF_8).asBytes());
|
||||
requestPayload.getContentMetadata().setContentMD5(md5().hashString(request, UTF_8));
|
||||
|
||||
final String response = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<DeleteResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">\n" +
|
||||
|
|
Loading…
Reference in New Issue