Issue 647: added "Expires" header for ContentMetadata

This commit is contained in:
Aled Sage 2012-05-11 14:50:22 +01:00
parent a2c8993592
commit 9aedf7b6f6
24 changed files with 182 additions and 51 deletions

View File

@ -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();

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}
/**

View File

@ -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);
}

View File

@ -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);
}

View File

@ -117,6 +117,8 @@ public interface BlobBuilder {
PayloadBlobBuilder contentEncoding(String contentEncoding);
PayloadBlobBuilder expires(String expires);
/**
*
* @see Payloads#calculateMD5

View File

@ -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();

View File

@ -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();
assertEquals(blob.getPayload().getContentMetadata().getContentMD5(), new byte[] { -84, -67, 24, -37, 76, -62, -8,
92, -19, -17, 101, 79, -52, -60, -92, -40 });
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(), 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);
}

View File

@ -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) {

View File

@ -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 {

View File

@ -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();
}

View File

@ -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 + "]";
}
}
}

View File

@ -66,4 +66,5 @@ public interface MutableContentMetadata extends ContentMetadata {
*/
void setContentEncoding(@Nullable String contentEncoding);
void setExpires(@Nullable String expires);
}

View File

@ -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;
}

View File

@ -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());
}
}

View File

@ -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")

View File

@ -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?

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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"));
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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"),