mirror of https://github.com/apache/jclouds.git
Issue 647: added "Expires" header for ContentMetadata
This commit is contained in:
parent
a2c8993592
commit
9aedf7b6f6
|
@ -158,6 +158,16 @@ public class DelegatingMutableContentMetadata implements MutableContentMetadata
|
|||
delegate.setPropertiesFromHttpHeaders(headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpires(String expires) {
|
||||
delegate.setExpires(expires);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpires() {
|
||||
return delegate.getExpires();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentMetadataBuilder toBuilder() {
|
||||
return delegate.toBuilder();
|
||||
|
|
|
@ -89,6 +89,7 @@ public class AtmosBlobRequestSignerTest extends BaseAsyncClientTest<AtmosAsyncCl
|
|||
blob.getPayload().getContentMetadata().setContentLength(2l);
|
||||
blob.getPayload().getContentMetadata().setContentMD5(new byte[] { 0, 2, 4, 8 });
|
||||
blob.getPayload().getContentMetadata().setContentType("text/plain");
|
||||
blob.getPayload().getContentMetadata().setExpires("Thu, 01 Dec 1994 16:00:00 GMT");
|
||||
|
||||
HttpRequest request = signer.signPutBlob("container", blob);
|
||||
|
||||
|
@ -98,7 +99,7 @@ public class AtmosBlobRequestSignerTest extends BaseAsyncClientTest<AtmosAsyncCl
|
|||
request,
|
||||
"Accept: */*\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nx-emc-signature: aLpB1oQaCA27AXT6Nzam7s0f0pI=\nx-emc-uid: identity\n");
|
||||
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 2l, new byte[] { 0, 2, 4, 8 });
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 2l, new byte[] { 0, 2, 4, 8 }, "Thu, 01 Dec 1994 16:00:00 GMT");
|
||||
|
||||
assertEquals(request.getFilters().size(), 0);
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public class BucketListObjectMetadata implements Serializable, ObjectMetadata {
|
|||
this.lastModified = lastModified;
|
||||
this.eTag = eTag;
|
||||
this.owner = owner;
|
||||
this.contentMetadata = new BaseImmutableContentMetadata(null, contentLength, md5, null, null, null);
|
||||
this.contentMetadata = new BaseImmutableContentMetadata(null, contentLength, md5, null, null, null, null);
|
||||
this.storageClass = storageClass;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ public class CopyObjectResult implements Serializable, ObjectMetadata {
|
|||
public CopyObjectResult(Date lastModified, String eTag) {
|
||||
this.lastModified = lastModified;
|
||||
this.eTag = eTag;
|
||||
this.contentMetadata = new BaseImmutableContentMetadata(null, null, null, null, null, null);
|
||||
this.contentMetadata = new BaseImmutableContentMetadata(null, null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -89,7 +89,7 @@ public class S3BlobRequestSignerTest extends BaseS3AsyncClientTest<S3AsyncClient
|
|||
public void testSignPutBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException,
|
||||
NoSuchMethodException, IOException {
|
||||
Blob blob = blobFactory.get().name("name").forSigning().contentLength(2l).contentMD5(new byte[] { 0, 2, 4, 8 }).contentType(
|
||||
"text/plain").build();
|
||||
"text/plain").expires("Thu, 01 Dec 1994 16:00:00 GMT").build();
|
||||
|
||||
HttpRequest request = signer.signPutBlob("container", blob);
|
||||
|
||||
|
@ -98,7 +98,7 @@ public class S3BlobRequestSignerTest extends BaseS3AsyncClientTest<S3AsyncClient
|
|||
request,
|
||||
"Authorization: AWS identity:j9Dy/lmmvlCKjA4lkqZenLxMkR4=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nHost: container.s3.amazonaws.com\n");
|
||||
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 2l, new byte[] { 0, 2, 4, 8 });
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 2l, new byte[] { 0, 2, 4, 8 }, "Thu, 01 Dec 1994 16:00:00 GMT");
|
||||
|
||||
assertEquals(request.getFilters().size(), 0);
|
||||
}
|
||||
|
|
|
@ -72,12 +72,13 @@ public class SwiftBlobRequestSignerTest extends CommonSwiftClientTest {
|
|||
blob.getPayload().getContentMetadata().setContentLength(2l);
|
||||
blob.getPayload().getContentMetadata().setContentMD5(new byte[] { 0, 2, 4, 8 });
|
||||
blob.getPayload().getContentMetadata().setContentType("text/plain");
|
||||
blob.getPayload().getContentMetadata().setExpires("Thu, 01 Dec 1994 16:00:00 GMT");
|
||||
|
||||
HttpRequest request = signer.signPutBlob("container", blob);
|
||||
|
||||
assertRequestLineEquals(request, "PUT http://storage/container/name HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(request, "X-Auth-Token: testtoken\n");
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 2l, new byte[] { 0, 2, 4, 8 });
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 2l, new byte[] { 0, 2, 4, 8 }, "Thu, 01 Dec 1994 16:00:00 GMT");
|
||||
|
||||
assertEquals(request.getFilters().size(), 0);
|
||||
}
|
||||
|
|
|
@ -117,6 +117,8 @@ public interface BlobBuilder {
|
|||
|
||||
PayloadBlobBuilder contentEncoding(String contentEncoding);
|
||||
|
||||
PayloadBlobBuilder expires(String expires);
|
||||
|
||||
/**
|
||||
*
|
||||
* @see Payloads#calculateMD5
|
||||
|
|
|
@ -221,6 +221,12 @@ public class BlobBuilderImpl implements BlobBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadBlobBuilder expires(String expires) {
|
||||
payload.getContentMetadata().setExpires(expires);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadBlobBuilder forSigning() {
|
||||
return builder.forSigning();
|
||||
|
|
|
@ -86,7 +86,7 @@ public class TransientBlobRequestSignerTest extends BaseAsyncClientTest<Transien
|
|||
assertNonPayloadHeadersEqual(
|
||||
request,
|
||||
"Authorization: Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==\nContent-Length: 2\nContent-MD5: AAIECA==\nContent-Type: text/plain\n");
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 2l, new byte[] { 0, 2, 4, 8 });
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 2l, new byte[] { 0, 2, 4, 8 }, null);
|
||||
|
||||
assertEquals(request.getFilters().size(), 0);
|
||||
}
|
||||
|
@ -94,9 +94,9 @@ public class TransientBlobRequestSignerTest extends BaseAsyncClientTest<Transien
|
|||
public void testSignPutBlobWithGenerate() throws ArrayIndexOutOfBoundsException, SecurityException,
|
||||
IllegalArgumentException, NoSuchMethodException, IOException {
|
||||
Blob blob = blobFactory.get().name(blobName).payload("foo").calculateMD5().contentType("text/plain").build();
|
||||
byte[] md5 = new byte[] { -84, -67, 24, -37, 76, -62, -8, 92, -19, -17, 101, 79, -52, -60, -92, -40 };
|
||||
|
||||
assertEquals(blob.getPayload().getContentMetadata().getContentMD5(), new byte[] { -84, -67, 24, -37, 76, -62, -8,
|
||||
92, -19, -17, 101, 79, -52, -60, -92, -40 });
|
||||
assertEquals(blob.getPayload().getContentMetadata().getContentMD5(), md5);
|
||||
|
||||
HttpRequest request = signer.signPutBlob(containerName, blob);
|
||||
|
||||
|
@ -104,8 +104,7 @@ public class TransientBlobRequestSignerTest extends BaseAsyncClientTest<Transien
|
|||
assertNonPayloadHeadersEqual(
|
||||
request,
|
||||
"Authorization: Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==\nContent-Length: 3\nContent-MD5: rL0Y20zC+Fzt72VPzMSk2A==\nContent-Type: text/plain\n");
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 3l, new byte[] { -84, -67, 24, -37, 76,
|
||||
-62, -8, 92, -19, -17, 101, 79, -52, -60, -92, -40 });
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 3l, md5, null);
|
||||
|
||||
assertEquals(request.getFilters().size(), 0);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ 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.EXPIRES;
|
||||
import static org.jclouds.util.Patterns.PATTERN_THAT_BREAKS_URI;
|
||||
import static org.jclouds.util.Patterns.URI_PATTERN;
|
||||
|
||||
|
@ -197,6 +198,8 @@ public class HttpUtils {
|
|||
builder.put(HttpHeaders.CONTENT_LENGTH, md.getContentLength() + "");
|
||||
if (md.getContentMD5() != null)
|
||||
builder.put("Content-MD5", CryptoStreams.base64(md.getContentMD5()));
|
||||
if (md.getExpires() != null)
|
||||
builder.put(HttpHeaders.EXPIRES, md.getExpires());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
@ -238,6 +241,7 @@ public class HttpUtils {
|
|||
toMd.setContentDisposition(fromMd.getContentDisposition());
|
||||
toMd.setContentEncoding(fromMd.getContentEncoding());
|
||||
toMd.setContentLanguage(fromMd.getContentLanguage());
|
||||
toMd.setExpires(fromMd.getExpires());
|
||||
}
|
||||
|
||||
public static URI parseEndPoint(String hostHeader) {
|
||||
|
@ -342,6 +346,9 @@ public class HttpUtils {
|
|||
if (message.getPayload().getContentMetadata().getContentLanguage() != null)
|
||||
logger.debug("%s %s: %s", prefix, CONTENT_LANGUAGE, message.getPayload().getContentMetadata()
|
||||
.getContentLanguage());
|
||||
if (message.getPayload().getContentMetadata().getExpires() != null)
|
||||
logger.debug("%s %s: %s", prefix, EXPIRES, message.getPayload().getContentMetadata()
|
||||
.getExpires());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,6 +399,10 @@ public class HttpUtils {
|
|||
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);
|
||||
checkArgument(
|
||||
message.getPayload() == null || message.getFirstHeaderOrNull(EXPIRES) == null,
|
||||
"configuration error please use request.getPayload().getContentMetadata().setExpires(value) as opposed to adding an expires header: "
|
||||
+ message);
|
||||
}
|
||||
|
||||
public static void releasePayload(HttpMessage from) {
|
||||
|
|
|
@ -224,6 +224,8 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
|
|||
connection.setRequestProperty("Content-Encoding", md.getContentEncoding());
|
||||
if (md.getContentLanguage() != null)
|
||||
connection.setRequestProperty("Content-Language", md.getContentLanguage());
|
||||
if (md.getExpires() != null)
|
||||
connection.setRequestProperty("Expires", md.getExpires());
|
||||
if (chunked) {
|
||||
connection.setChunkedStreamingMode(8196);
|
||||
} else {
|
||||
|
|
|
@ -86,6 +86,14 @@ public interface ContentMetadata {
|
|||
@Nullable
|
||||
String getContentLanguage();
|
||||
|
||||
/**
|
||||
* Gives the date/time after which the response is considered stale.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21"/>
|
||||
*/
|
||||
@Nullable
|
||||
String getExpires();
|
||||
|
||||
ContentMetadataBuilder toBuilder();
|
||||
|
||||
}
|
|
@ -51,6 +51,7 @@ public class ContentMetadataBuilder implements Serializable {
|
|||
protected String contentDisposition;
|
||||
protected String contentLanguage;
|
||||
protected String contentEncoding;
|
||||
protected String expires;
|
||||
|
||||
public ContentMetadataBuilder fromHttpHeaders(Multimap<String, String> headers) {
|
||||
boolean chunked = any(headers.entries(), new Predicate<Entry<String, String>>() {
|
||||
|
@ -72,6 +73,8 @@ public class ContentMetadataBuilder implements Serializable {
|
|||
contentEncoding(header.getValue());
|
||||
} else if ("Content-Language".equalsIgnoreCase(header.getKey())) {
|
||||
contentLanguage(header.getValue());
|
||||
} else if ("Expires".equalsIgnoreCase(header.getKey())) {
|
||||
expires(header.getValue());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
@ -113,28 +116,26 @@ public class ContentMetadataBuilder implements Serializable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ContentMetadataBuilder expires(@Nullable String expires) {
|
||||
this.expires = expires;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentMetadata build() {
|
||||
return new BaseImmutableContentMetadata(contentType, contentLength, contentMD5, contentDisposition,
|
||||
contentLanguage, contentEncoding);
|
||||
contentLanguage, contentEncoding, expires);
|
||||
}
|
||||
|
||||
public static ContentMetadataBuilder fromContentMetadata(ContentMetadata in) {
|
||||
return new ContentMetadataBuilder().contentType(in.getContentType()).contentLength(in.getContentLength())
|
||||
.contentMD5(in.getContentMD5()).contentDisposition(in.getContentDisposition()).contentLanguage(
|
||||
in.getContentLanguage()).contentEncoding(in.getContentEncoding());
|
||||
in.getContentLanguage()).contentEncoding(in.getContentEncoding()).expires(in.getExpires());
|
||||
}
|
||||
|
||||
@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;
|
||||
return Objects.hashCode(contentDisposition, contentEncoding, contentLanguage, contentLength,
|
||||
contentMD5, contentType, expires);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -151,13 +152,14 @@ public class ContentMetadataBuilder implements Serializable {
|
|||
Objects.equal(contentLanguage, other.contentLanguage) &&
|
||||
Objects.equal(contentLength, other.contentLength) &&
|
||||
Arrays.equals(contentMD5, other.contentMD5) &&
|
||||
Objects.equal(contentType, other.contentType);
|
||||
Objects.equal(contentType, other.contentType) &&
|
||||
Objects.equal(expires, other.expires);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[contentDisposition=" + contentDisposition + ", contentEncoding=" + contentEncoding
|
||||
+ ", contentLanguage=" + contentLanguage + ", contentLength=" + contentLength + ", contentMD5="
|
||||
+ Arrays.toString(contentMD5) + ", contentType=" + contentType + "]";
|
||||
+ Arrays.toString(contentMD5) + ", contentType=" + contentType + ", expires=" + expires + "]";
|
||||
}
|
||||
}
|
|
@ -66,4 +66,5 @@ public interface MutableContentMetadata extends ContentMetadata {
|
|||
*/
|
||||
void setContentEncoding(@Nullable String contentEncoding);
|
||||
|
||||
void setExpires(@Nullable String expires);
|
||||
}
|
|
@ -24,6 +24,8 @@ import java.util.Arrays;
|
|||
import org.jclouds.io.ContentMetadata;
|
||||
import org.jclouds.io.ContentMetadataBuilder;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
@ -37,15 +39,17 @@ public class BaseImmutableContentMetadata implements ContentMetadata, Serializab
|
|||
protected String contentDisposition;
|
||||
protected String contentLanguage;
|
||||
protected String contentEncoding;
|
||||
protected String expires;
|
||||
|
||||
public BaseImmutableContentMetadata(String contentType, Long contentLength, byte[] contentMD5,
|
||||
String contentDisposition, String contentLanguage, String contentEncoding) {
|
||||
String contentDisposition, String contentLanguage, String contentEncoding, String expires) {
|
||||
this.contentType = contentType;
|
||||
this.contentLength = contentLength;
|
||||
this.contentMD5 = contentMD5;
|
||||
this.contentDisposition = contentDisposition;
|
||||
this.contentLanguage = contentLanguage;
|
||||
this.contentEncoding = contentEncoding;
|
||||
this.expires = expires;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -102,24 +106,25 @@ public class BaseImmutableContentMetadata implements ContentMetadata, Serializab
|
|||
return this.contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getExpires() {
|
||||
return this.expires;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[contentType=" + contentType + ", contentLength=" + contentLength + ", contentDisposition="
|
||||
+ contentDisposition + ", contentEncoding=" + contentEncoding + ", contentLanguage=" + contentLanguage
|
||||
+ ", contentMD5=" + Arrays.toString(contentMD5) + "]";
|
||||
+ ", contentMD5=" + Arrays.toString(contentMD5) + ", expires = " + expires + "]";
|
||||
}
|
||||
|
||||
@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;
|
||||
return Objects.hashCode(contentDisposition, contentEncoding, contentLanguage, contentLength,
|
||||
contentMD5, contentType, expires);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -158,6 +163,9 @@ public class BaseImmutableContentMetadata implements ContentMetadata, Serializab
|
|||
return false;
|
||||
} else if (!contentType.equals(other.contentType))
|
||||
return false;
|
||||
if (!Objects.equal(expires, other.expires)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,22 @@ public class BaseMutableContentMetadata extends ContentMetadataBuilder implement
|
|||
return this.contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setExpires(@Nullable String expires) {
|
||||
expires(expires);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getExpires() {
|
||||
return this.expires;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseMutableContentMetadata toBuilder() {
|
||||
return BaseMutableContentMetadata.fromContentMetadata(this);
|
||||
|
@ -150,6 +166,6 @@ public class BaseMutableContentMetadata extends ContentMetadataBuilder implement
|
|||
return (BaseMutableContentMetadata) new BaseMutableContentMetadata().contentType(in.getContentType())
|
||||
.contentLength(in.getContentLength()).contentMD5(in.getContentMD5()).contentDisposition(
|
||||
in.getContentDisposition()).contentLanguage(in.getContentLanguage()).contentEncoding(
|
||||
in.getContentEncoding());
|
||||
in.getContentEncoding()).expires(in.getExpires());
|
||||
}
|
||||
}
|
|
@ -138,6 +138,7 @@ public abstract class Wire {
|
|||
wiredMd.setContentDisposition(oldMd.getContentDisposition());
|
||||
wiredMd.setContentEncoding(oldMd.getContentEncoding());
|
||||
wiredMd.setContentLanguage(oldMd.getContentLanguage());
|
||||
wiredMd.setExpires(oldMd.getExpires());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
@ -86,11 +86,22 @@ public abstract class BaseRestClientTest {
|
|||
}
|
||||
|
||||
protected void assertPayloadEquals(HttpRequest request, String toMatch, String contentType, boolean contentMD5) {
|
||||
assertPayloadEquals(request, toMatch, contentType, null, null, null, contentMD5);
|
||||
assertPayloadEquals(request, toMatch, contentType, contentMD5, null);
|
||||
}
|
||||
|
||||
protected void assertPayloadEquals(HttpRequest request, String toMatch, String contentType, boolean contentMD5, String expires) {
|
||||
assertPayloadEquals(request, toMatch, contentType, null, null, null, contentMD5, expires);
|
||||
}
|
||||
|
||||
protected void assertPayloadEquals(HttpRequest request, String toMatch, String contentType,
|
||||
String contentDispositon, String contentEncoding, String contentLanguage, boolean contentMD5) {
|
||||
assertPayloadEquals(request, toMatch, contentType, contentDispositon, contentEncoding, contentLanguage,
|
||||
contentMD5, null);
|
||||
}
|
||||
|
||||
protected void assertPayloadEquals(HttpRequest request, String toMatch, String contentType,
|
||||
String contentDispositon, String contentEncoding, String contentLanguage, boolean contentMD5,
|
||||
String expires) {
|
||||
if (request.getPayload() == null) {
|
||||
assertNull(toMatch);
|
||||
} else {
|
||||
|
@ -104,7 +115,7 @@ public abstract class BaseRestClientTest {
|
|||
Long length = new Long(payload.getBytes().length);
|
||||
try {
|
||||
assertContentHeadersEqual(request, contentType, contentDispositon, contentEncoding, contentLanguage,
|
||||
length, contentMD5 ? CryptoStreams.md5(request.getPayload()) : null);
|
||||
length, contentMD5 ? CryptoStreams.md5(request.getPayload()) : null, expires);
|
||||
} catch (IOException e) {
|
||||
propagate(e);
|
||||
}
|
||||
|
@ -112,7 +123,7 @@ public abstract class BaseRestClientTest {
|
|||
}
|
||||
|
||||
protected void assertContentHeadersEqual(HttpRequest request, String contentType, String contentDispositon,
|
||||
String contentEncoding, String contentLanguage, Long length, byte[] contentMD5) {
|
||||
String contentEncoding, String contentLanguage, Long length, byte[] contentMD5, String expires) {
|
||||
MutableContentMetadata md = request.getPayload().getContentMetadata();
|
||||
if (request.getFirstHeaderOrNull(TRANSFER_ENCODING) == null) {
|
||||
assertEquals(md.getContentLength(), length);
|
||||
|
@ -125,6 +136,7 @@ public abstract class BaseRestClientTest {
|
|||
assertEquals(md.getContentEncoding(), contentEncoding);
|
||||
assertEquals(md.getContentLanguage(), contentLanguage);
|
||||
assertEquals(md.getContentMD5(), contentMD5);
|
||||
assertEquals(md.getExpires(), expires);
|
||||
}
|
||||
|
||||
// FIXME Shouldn't be assertPayloadHeadersEqual?
|
||||
|
|
|
@ -152,6 +152,8 @@ public class ApacheHCUtils {
|
|||
apacheRequest.addHeader("Content-Encoding", payload.getContentMetadata().getContentEncoding());
|
||||
if (payload.getContentMetadata().getContentLanguage() != null)
|
||||
apacheRequest.addHeader("Content-Language", payload.getContentMetadata().getContentLanguage());
|
||||
if (payload.getContentMetadata().getExpires() != null)
|
||||
apacheRequest.addHeader("Expires", payload.getContentMetadata().getExpires());
|
||||
assert (apacheRequest.getEntity() != null);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.aws.s3.blobstore.integration;
|
||||
|
||||
import static org.jclouds.blobstore.options.CreateContainerOptions.Builder.publicRead;
|
||||
<<<<<<< HEAD
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -29,11 +30,24 @@ import java.util.Set;
|
|||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||
import org.jclouds.domain.Location;
|
||||
=======
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
>>>>>>> Issue-647: added "Expires" header for ContentMetadata
|
||||
import org.jclouds.s3.blobstore.integration.S3ContainerLiveTest;
|
||||
import org.jclouds.util.Strings2;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
<<<<<<< HEAD
|
||||
import com.google.common.base.Strings;
|
||||
=======
|
||||
import com.google.common.base.Throwables;
|
||||
>>>>>>> Issue-647: added "Expires" header for ContentMetadata
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -44,6 +58,34 @@ public class AWSS3ContainerLiveTest extends S3ContainerLiveTest {
|
|||
provider = "aws-s3";
|
||||
}
|
||||
|
||||
@Test(groups = { "live" })
|
||||
public void testCreateBlobWithExpiry() throws InterruptedException, MalformedURLException, IOException {
|
||||
final String containerName = getScratchContainerName();
|
||||
BlobStore blobStore = view.getBlobStore();
|
||||
try {
|
||||
final String RFC1123_PATTERN = "EEE, dd MMM yyyyy HH:mm:ss z";
|
||||
final String blobName = "hello";
|
||||
final String expires = new SimpleDateFormat(RFC1123_PATTERN).format(new Date(System.currentTimeMillis()+(60*1000)));
|
||||
|
||||
blobStore.createContainerInLocation(null, containerName, publicRead());
|
||||
blobStore.putBlob(containerName, blobStore.blobBuilder(blobName).payload(TEST_STRING).expires(expires).build());
|
||||
|
||||
assertConsistencyAware(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
String actualExpires = view.getBlobStore().getBlob(containerName, blobName).getPayload().getContentMetadata().getExpires();
|
||||
assert expires.equals(actualExpires) : "expires="+actualExpires+"; expected="+expires;
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} finally {
|
||||
recycleContainer(containerName);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(groups = { "live" })
|
||||
public void testCreateBlobInLocation() throws InterruptedException, MalformedURLException, IOException {
|
||||
String payload = "my data";
|
||||
|
@ -88,5 +130,4 @@ public class AWSS3ContainerLiveTest extends S3ContainerLiveTest {
|
|||
}
|
||||
throw new NoSuchElementException("No location found with id '"+id+"'; contenders were "+locs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,7 +55,8 @@ public class BlobPropertiesImpl implements Serializable, BlobProperties {
|
|||
|
||||
public BlobPropertiesImpl(BlobType type, String name, String container, 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) {
|
||||
@Nullable String contentLanguage, @Nullable String currentExpires, LeaseStatus leaseStatus,
|
||||
Map<String, String> metadata) {
|
||||
this.type = checkNotNull(type, "type");
|
||||
this.leaseStatus = checkNotNull(leaseStatus, "leaseStatus");
|
||||
this.name = checkNotNull(name, "name");
|
||||
|
@ -64,7 +65,7 @@ public class BlobPropertiesImpl implements Serializable, BlobProperties {
|
|||
this.lastModified = checkNotNull(lastModified, "lastModified");
|
||||
this.eTag = checkNotNull(eTag, "eTag");
|
||||
this.contentMetadata = new BaseImmutableContentMetadata(contentType, size, contentMD5, null, contentLanguage,
|
||||
contentMetadata);
|
||||
contentMetadata, currentExpires);
|
||||
this.metadata.putAll(checkNotNull(metadata, "metadata"));
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ public class ContainerNameEnumerationResultsHandler extends ParseSax.HandlerWith
|
|||
private String currentContentEncoding;
|
||||
private String currentContentLanguage;
|
||||
private BlobType currentBlobType;
|
||||
private String currentExpires;
|
||||
private boolean inBlob;
|
||||
private boolean inBlobPrefix;
|
||||
private boolean inMetadata;
|
||||
|
@ -131,8 +132,8 @@ public class ContainerNameEnumerationResultsHandler extends ParseSax.HandlerWith
|
|||
} else if (qName.equals("Blob")) {
|
||||
BlobProperties md = new BlobPropertiesImpl(currentBlobType, currentName, containerUrl.getPath().replace("/",
|
||||
""), currentUrl, currentLastModified, currentETag, currentSize, currentContentType,
|
||||
currentContentMD5, currentContentEncoding, currentContentLanguage, currentLeaseStatus,
|
||||
currentMetadata);
|
||||
currentContentMD5, currentContentEncoding, currentContentLanguage, currentExpires,
|
||||
currentLeaseStatus, currentMetadata);
|
||||
blobMetadata.add(md);
|
||||
currentBlobType = null;
|
||||
currentName = null;
|
||||
|
@ -145,6 +146,7 @@ public class ContainerNameEnumerationResultsHandler extends ParseSax.HandlerWith
|
|||
currentContentLanguage = null;
|
||||
currentContentMD5 = null;
|
||||
currentLeaseStatus = null;
|
||||
currentExpires = null;
|
||||
currentMetadata = Maps.newHashMap();
|
||||
} else if (qName.equals("Url")) {
|
||||
currentUrl = HttpUtils.createUri(currentText.toString().trim());
|
||||
|
@ -172,6 +174,10 @@ public class ContainerNameEnumerationResultsHandler extends ParseSax.HandlerWith
|
|||
currentContentLanguage = currentText.toString().trim();
|
||||
if (currentContentLanguage.equals(""))
|
||||
currentContentLanguage = null;
|
||||
} else if (qName.equals("Expires")) {
|
||||
currentExpires = currentText.toString().trim();
|
||||
if (currentExpires.equals(""))
|
||||
currentExpires= null;
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ public class AzureBlobRequestSignerTest extends BaseAsyncClientTest<AzureBlobAsy
|
|||
blob.getPayload().getContentMetadata().setContentLength(2l);
|
||||
blob.getPayload().getContentMetadata().setContentMD5(new byte[] { 0, 2, 4, 8 });
|
||||
blob.getPayload().getContentMetadata().setContentType("text/plain");
|
||||
blob.getPayload().getContentMetadata().setExpires("Thu, 01 Dec 1994 16:00:00 GMT");
|
||||
|
||||
HttpRequest request = signer.signPutBlob("container", blob);
|
||||
|
||||
|
@ -93,7 +94,7 @@ public class AzureBlobRequestSignerTest extends BaseAsyncClientTest<AzureBlobAsy
|
|||
assertNonPayloadHeadersEqual(
|
||||
request,
|
||||
"Authorization: SharedKeyLite identity:LT+HBNzhbRsZY07kC+/JxeuAURbxTmwJaIe464LO36c=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nx-ms-blob-type: BlockBlob\nx-ms-version: 2009-09-19\n");
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 2l, new byte[] { 0, 2, 4, 8 });
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 2l, new byte[] { 0, 2, 4, 8 }, "Thu, 01 Dec 1994 16:00:00 GMT");
|
||||
|
||||
assertEquals(request.getFilters().size(), 0);
|
||||
}
|
||||
|
|
|
@ -63,17 +63,17 @@ public class ContainerNameEnumerationResultsHandlerTest extends BaseHandlerTest
|
|||
new BlobPropertiesImpl(BlobType.BLOCK_BLOB, "blob1.txt", "mycontainer", URI
|
||||
.create("http://myaccount.blob.core.windows.net/mycontainer/blob1.txt"), dateService
|
||||
.rfc822DateParse("Thu, 18 Sep 2008 18:41:57 GMT"), "0x8CAE7D55D050B8B", 8,
|
||||
"text/plain; charset=UTF-8", null, null, null, LeaseStatus.UNLOCKED, ImmutableMap
|
||||
"text/plain; charset=UTF-8", null, null, null, null, LeaseStatus.UNLOCKED, ImmutableMap
|
||||
.<String, String> of()),
|
||||
new BlobPropertiesImpl(BlobType.BLOCK_BLOB, "blob2.txt", "mycontainer", URI
|
||||
.create("http://myaccount.blob.core.windows.net/mycontainer/blob2.txt"), dateService
|
||||
.rfc822DateParse("Thu, 18 Sep 2008 18:41:57 GMT"), "0x8CAE7D55CF6C339", 14,
|
||||
"text/plain; charset=UTF-8", null, null, null, LeaseStatus.UNLOCKED, ImmutableMap
|
||||
"text/plain; charset=UTF-8", null, null, null, null, LeaseStatus.UNLOCKED, ImmutableMap
|
||||
.<String, String> of()),
|
||||
new BlobPropertiesImpl(BlobType.PAGE_BLOB, "newblob1.txt", "mycontainer", URI
|
||||
.create("http://myaccount.blob.core.windows.net/mycontainer/newblob1.txt"), dateService
|
||||
.rfc822DateParse("Thu, 18 Sep 2008 18:41:57 GMT"), "0x8CAE7D55CF6C339", 25,
|
||||
"text/plain; charset=UTF-8", null, null, null, LeaseStatus.UNLOCKED, ImmutableMap
|
||||
"text/plain; charset=UTF-8", null, null, null, null, LeaseStatus.UNLOCKED, ImmutableMap
|
||||
.<String, String> of()));
|
||||
|
||||
ListBlobsResponse list = new HashSetListBlobsResponse(contents,
|
||||
|
@ -91,7 +91,7 @@ public class ContainerNameEnumerationResultsHandlerTest extends BaseHandlerTest
|
|||
Set<BlobProperties> contents = ImmutableSet.<BlobProperties> of(new BlobPropertiesImpl(BlobType.BLOCK_BLOB, "a",
|
||||
"adriancole-blobstore3", URI.create("https://jclouds.blob.core.windows.net/adriancole-blobstore3/a"),
|
||||
dateService.rfc822DateParse("Sat, 30 Jan 2010 17:46:15 GMT"), "0x8CC6FEB41736428", 8,
|
||||
"application/octet-stream", null, null, null, LeaseStatus.UNLOCKED, ImmutableMap.<String, String> of()));
|
||||
"application/octet-stream", null, null, null, null, LeaseStatus.UNLOCKED, ImmutableMap.<String, String> of()));
|
||||
|
||||
ListBlobsResponse list = new HashSetListBlobsResponse(contents,
|
||||
URI.create("https://jclouds.blob.core.windows.net/adriancole-blobstore3"),
|
||||
|
|
Loading…
Reference in New Issue