JCLOUDS-948: Portable Cache-Control support

Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/5fd7b1aa
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/5fd7b1aa
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/5fd7b1aa

Branch: refs/heads/master
Commit: 5fd7b1aa782399958e90ed9a16a3b20a0fc35d07
Parents: 8bddbb4
Author: Andrew Gaul <[email protected]>
Authored: Thu Jan 14 15:52:46 2016 -0800
Committer: Andrew Gaul <[email protected]>
Committed: Fri Jan 15 04:41:01 2016 -0800

----------------------------------------------------------------------
 .../blobstore/config/LocalBlobStore.java        | 11 +++++++++-
 .../jclouds/blobstore/domain/BlobBuilder.java   |  2 ++
 .../domain/internal/BlobBuilderImpl.java        |  6 +++++
 .../blobstore/internal/BaseBlobStore.java       |  1 +
 .../internal/BaseBlobIntegrationTest.java       |  9 ++++++++
 .../main/java/org/jclouds/http/HttpUtils.java   |  8 +++++++
 .../java/org/jclouds/io/ContentMetadata.java    | 15 +++++++++++--
 .../org/jclouds/io/ContentMetadataBuilder.java  | 17 +++++++++++----
 .../org/jclouds/io/ContentMetadataCodec.java    |  7 +++++-
 .../org/jclouds/io/MutableContentMetadata.java  |  2 ++
 .../payloads/BaseImmutableContentMetadata.java  | 19 +++++++++++++++-
 .../io/payloads/BaseMutableContentMetadata.java | 23 ++++++++++++++++----
 .../java/org/jclouds/logging/internal/Wire.java |  1 +
 13 files changed, 108 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java
----------------------------------------------------------------------
diff --git 
a/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java 
b/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java
index 06b3367..9c06f21 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/config/LocalBlobStore.java
@@ -544,6 +544,10 @@ public final class LocalBlobStore implements BlobStore {
 
          if (options.getContentMetadata().isPresent()) {
             ContentMetadata contentMetadata = 
options.getContentMetadata().get();
+            String cacheControl = contentMetadata.getCacheControl();
+            if (cacheControl != null) {
+               builder.cacheControl(cacheControl);
+            }
             String contentDisposition = 
contentMetadata.getContentDisposition();
             if (contentDisposition != null) {
                builder.contentDisposition(contentDisposition);
@@ -561,7 +565,8 @@ public final class LocalBlobStore implements BlobStore {
                builder.contentType(contentType);
             }
          } else {
-            builder.contentDisposition(metadata.getContentDisposition())
+            builder.cacheControl(metadata.getCacheControl())
+                   .contentDisposition(metadata.getContentDisposition())
                    .contentEncoding(metadata.getContentEncoding())
                    .contentLanguage(metadata.getContentLanguage())
                    .contentType(metadata.getContentType());
@@ -782,6 +787,10 @@ public final class LocalBlobStore implements BlobStore {
             .userMetadata(mpu.blobMetadata().getUserMetadata())
             .payload(new 
SequenceInputStream(Iterators.asEnumeration(streams.build().iterator())))
             .contentLength(contentLength);
+      String cacheControl = 
mpu.blobMetadata().getContentMetadata().getCacheControl();
+      if (cacheControl != null) {
+         blobBuilder.cacheControl(cacheControl);
+      }
       String contentDisposition = 
mpu.blobMetadata().getContentMetadata().getContentDisposition();
       if (contentDisposition != null) {
          blobBuilder.contentDisposition(contentDisposition);

http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java
----------------------------------------------------------------------
diff --git 
a/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java 
b/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java
index e2d4c62..5d0bb0f 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java
@@ -108,6 +108,8 @@ public interface BlobBuilder {
 
    public interface PayloadBlobBuilder extends BlobBuilder {
 
+      PayloadBlobBuilder cacheControl(String cacheControl);
+
       PayloadBlobBuilder contentLength(long contentLength);
 
       /** @deprecated use {@link #contentMD5(HashCode)} instead. */

http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java
----------------------------------------------------------------------
diff --git 
a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java
 
b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java
index e6d94e1..e819001 100644
--- 
a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java
+++ 
b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java
@@ -180,6 +180,12 @@ public class BlobBuilderImpl implements BlobBuilder {
       }
 
       @Override
+      public PayloadBlobBuilder cacheControl(String cacheControl) {
+         payload.getContentMetadata().setCacheControl(cacheControl);
+         return this;
+      }
+
+      @Override
       public PayloadBlobBuilder contentLength(long contentLength) {
          checkArgument(contentLength >= 0, "content length must be 
non-negative, was: %s", contentLength);
          payload.getContentMetadata().setContentLength(contentLength);

http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java
----------------------------------------------------------------------
diff --git 
a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java 
b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java
index a608b18..782d60b 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java
@@ -265,6 +265,7 @@ public abstract class BaseBlobStore implements BlobStore {
          ContentMetadata metadata = blob.getMetadata().getContentMetadata();
          BlobBuilder.PayloadBlobBuilder builder = blobBuilder(toName)
                .payload(is)
+               .cacheControl(metadata.getCacheControl())
                .contentDisposition(metadata.getContentDisposition())
                .contentEncoding(metadata.getContentEncoding())
                .contentLanguage(metadata.getContentLanguage())

http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java
----------------------------------------------------------------------
diff --git 
a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java
 
b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java
index 0240602..1732e67 100644
--- 
a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java
+++ 
b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java
@@ -756,6 +756,7 @@ public class BaseBlobIntegrationTest extends 
BaseBlobStoreIntegrationTest {
    }
 
    protected void checkContentMetadata(Blob blob) {
+      checkCacheControl(blob, "max-age=3600");
       checkContentType(blob, "text/csv");
       checkContentDisposition(blob, "attachment; filename=photo.jpg");
       checkContentEncoding(blob, "gzip");
@@ -763,12 +764,18 @@ public class BaseBlobIntegrationTest extends 
BaseBlobStoreIntegrationTest {
    }
 
    protected void addContentMetadata(PayloadBlobBuilder blobBuilder) {
+      blobBuilder.cacheControl("max-age=3600");
       blobBuilder.contentType("text/csv");
       blobBuilder.contentDisposition("attachment; filename=photo.jpg");
       blobBuilder.contentEncoding("gzip");
       blobBuilder.contentLanguage("en");
    }
 
+   protected void checkCacheControl(Blob blob, String cacheControl) {
+      
assertThat(blob.getPayload().getContentMetadata().getCacheControl()).isEqualTo(cacheControl);
+      
assertThat(blob.getMetadata().getContentMetadata().getCacheControl()).isEqualTo(cacheControl);
+   }
+
    protected void checkContentType(Blob blob, String contentType) {
       assert 
blob.getPayload().getContentMetadata().getContentType().startsWith(contentType) 
: blob.getPayload()
                .getContentMetadata().getContentType();
@@ -893,6 +900,7 @@ public class BaseBlobIntegrationTest extends 
BaseBlobStoreIntegrationTest {
             .blobBuilder(fromName)
             .userMetadata(ImmutableMap.of("key1", "value1", "key2", "value2"))
             .payload(payload)
+            .cacheControl("max-age=1800")
             .contentLength(payload.size())
             .contentDisposition("attachment; filename=original.jpg")
             .contentEncoding("compress")
@@ -908,6 +916,7 @@ public class BaseBlobIntegrationTest extends 
BaseBlobStoreIntegrationTest {
          Map<String, String> userMetadata = ImmutableMap.of("key3", "value3", 
"key4", "value4");
          blobStore.copyBlob(fromContainer, fromName, toContainer, toName, 
CopyOptions.builder()
                .contentMetadata(ContentMetadataBuilder.create()
+                     .cacheControl("max-age=3600")
                      .contentType("text/csv")
                      .contentDisposition("attachment; filename=photo.jpg")
                      .contentEncoding("gzip")

http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/core/src/main/java/org/jclouds/http/HttpUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/http/HttpUtils.java 
b/core/src/main/java/org/jclouds/http/HttpUtils.java
index 5c026de..5b636a9 100644
--- a/core/src/main/java/org/jclouds/http/HttpUtils.java
+++ b/core/src/main/java/org/jclouds/http/HttpUtils.java
@@ -30,6 +30,7 @@ import static com.google.common.collect.Iterables.size;
 import static com.google.common.collect.Multimaps.filterKeys;
 import static com.google.common.io.BaseEncoding.base64;
 import static com.google.common.io.ByteStreams.toByteArray;
+import static com.google.common.net.HttpHeaders.CACHE_CONTROL;
 import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
 import static com.google.common.net.HttpHeaders.CONTENT_ENCODING;
 import static com.google.common.net.HttpHeaders.CONTENT_LANGUAGE;
@@ -168,6 +169,7 @@ public class HttpUtils {
    }
 
    public static void copy(ContentMetadata fromMd, MutableContentMetadata 
toMd) {
+      toMd.setCacheControl(fromMd.getCacheControl());
       toMd.setContentLength(fromMd.getContentLength());
       toMd.setContentMD5(fromMd.getContentMD5());
       toMd.setContentType(fromMd.getContentType());
@@ -190,6 +192,8 @@ public class HttpUtils {
             logger.debug("%s %s: %s", prefix, header.getKey(), 
header.getValue());
       }
       if (message.getPayload() != null) {
+         if (message.getPayload().getContentMetadata().getCacheControl() != 
null)
+            logger.debug("%s %s: %s", prefix, CACHE_CONTROL, 
message.getPayload().getContentMetadata().getCacheControl());
          if (message.getPayload().getContentMetadata().getContentType() != 
null)
             logger.debug("%s %s: %s", prefix, CONTENT_TYPE, 
message.getPayload().getContentMetadata().getContentType());
          if (message.getPayload().getContentMetadata().getContentLength() != 
null)
@@ -221,6 +225,10 @@ public class HttpUtils {
 
    public void checkRequestHasRequiredProperties(HttpRequest message) {
       checkArgument(
+            message.getPayload() == null || 
message.getFirstHeaderOrNull(CACHE_CONTROL) == null,
+            "configuration error please use 
request.getPayload().getContentMetadata().setCacheControl(value) as opposed to 
adding a cache control header: %s",
+                  message);
+      checkArgument(
             message.getPayload() == null || 
message.getFirstHeaderOrNull(CONTENT_TYPE) == null,
             "configuration error please use 
request.getPayload().getContentMetadata().setContentType(value) as opposed to 
adding a content type header: %s",
                   message);

http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/core/src/main/java/org/jclouds/io/ContentMetadata.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/io/ContentMetadata.java 
b/core/src/main/java/org/jclouds/io/ContentMetadata.java
index 316567e..382d6b5 100644
--- a/core/src/main/java/org/jclouds/io/ContentMetadata.java
+++ b/core/src/main/java/org/jclouds/io/ContentMetadata.java
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 package org.jclouds.io;
+import static com.google.common.net.HttpHeaders.CACHE_CONTROL;
 import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
 import static com.google.common.net.HttpHeaders.CONTENT_ENCODING;
 import static com.google.common.net.HttpHeaders.CONTENT_LANGUAGE;
@@ -32,13 +33,23 @@ import com.google.common.hash.HashCode;
 import com.google.common.collect.ImmutableSet;
 
 public interface ContentMetadata {
-   Set<String> HTTP_HEADERS = ImmutableSet.of(CONTENT_LENGTH, CONTENT_MD5, 
CONTENT_TYPE,
-            CONTENT_DISPOSITION, CONTENT_ENCODING, CONTENT_LANGUAGE, EXPIRES);
+   Set<String> HTTP_HEADERS = ImmutableSet.of(
+         CACHE_CONTROL,
+         CONTENT_LENGTH,
+         CONTENT_MD5,
+         CONTENT_TYPE,
+         CONTENT_DISPOSITION,
+         CONTENT_ENCODING,
+         CONTENT_LANGUAGE,
+         EXPIRES);
 
    // See 
http://stackoverflow.com/questions/10584647/simpledateformat-parse-is-one-hour-out-using-rfc-1123-gmt-in-summer
    // for why not using "zzz"
    String RFC1123_DATE_PATTERN = "EEE, dd MMM yyyyy HH:mm:ss Z";
    
+   @Nullable
+   String getCacheControl();
+
    /**
     * Returns the total size of the payload, or the chunk that's available.
     * <p/>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/core/src/main/java/org/jclouds/io/ContentMetadataBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/io/ContentMetadataBuilder.java 
b/core/src/main/java/org/jclouds/io/ContentMetadataBuilder.java
index 48d3eff..c63e052 100644
--- a/core/src/main/java/org/jclouds/io/ContentMetadataBuilder.java
+++ b/core/src/main/java/org/jclouds/io/ContentMetadataBuilder.java
@@ -31,6 +31,7 @@ public class ContentMetadataBuilder {
       return new ContentMetadataBuilder();
    }
 
+   protected String cacheControl;
    protected String contentType = "application/unknown";
    protected Long contentLength;
    protected HashCode contentMD5;
@@ -39,6 +40,11 @@ public class ContentMetadataBuilder {
    protected String contentEncoding;
    protected Date expires;
 
+   public ContentMetadataBuilder cacheControl(@Nullable String cacheControl) {
+      this.cacheControl = cacheControl;
+      return this;
+   }
+
    public ContentMetadataBuilder contentLength(@Nullable Long contentLength) {
       this.contentLength = contentLength;
       return this;
@@ -85,13 +91,14 @@ public class ContentMetadataBuilder {
    }
 
    public ContentMetadata build() {
-      return new BaseImmutableContentMetadata(contentType, contentLength,
+      return new BaseImmutableContentMetadata(cacheControl, contentType, 
contentLength,
                contentMD5 == null ? null : contentMD5.asBytes(), 
contentDisposition,
                contentLanguage, contentEncoding, expires);
    }
 
    public static ContentMetadataBuilder fromContentMetadata(ContentMetadata 
in) {
-      return new 
ContentMetadataBuilder().contentType(in.getContentType()).contentLength(in.getContentLength())
+      return new ContentMetadataBuilder()
+               
.cacheControl(in.getCacheControl()).contentType(in.getContentType()).contentLength(in.getContentLength())
                
.contentMD5(in.getContentMD5()).contentDisposition(in.getContentDisposition()).contentLanguage(
                         
in.getContentLanguage()).contentEncoding(in.getContentEncoding()).expires(in.getExpires());
    }
@@ -111,7 +118,8 @@ public class ContentMetadataBuilder {
       if (getClass() != obj.getClass())
          return false;
       ContentMetadataBuilder other = (ContentMetadataBuilder) obj;
-      return Objects.equal(contentDisposition, other.contentDisposition) &&
+      return Objects.equal(cacheControl, other.cacheControl) &&
+             Objects.equal(contentDisposition, other.contentDisposition) &&
              Objects.equal(contentEncoding, other.contentEncoding) &&
              Objects.equal(contentLanguage, other.contentLanguage) &&
              Objects.equal(contentLength, other.contentLength) &&
@@ -122,7 +130,8 @@ public class ContentMetadataBuilder {
 
    @Override
    public String toString() {
-      return "[contentDisposition=" + contentDisposition + ", 
contentEncoding=" + contentEncoding
+      return "[cacheControl=" + cacheControl
+               + ", contentDisposition=" + contentDisposition + ", 
contentEncoding=" + contentEncoding
                + ", contentLanguage=" + contentLanguage + ", contentLength=" + 
contentLength + ", contentMD5="
                + contentMD5 + ", contentType=" + contentType + ", expires=" + 
expires + "]";
    }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/core/src/main/java/org/jclouds/io/ContentMetadataCodec.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/io/ContentMetadataCodec.java 
b/core/src/main/java/org/jclouds/io/ContentMetadataCodec.java
index 5bc607d..05de972 100644
--- a/core/src/main/java/org/jclouds/io/ContentMetadataCodec.java
+++ b/core/src/main/java/org/jclouds/io/ContentMetadataCodec.java
@@ -18,6 +18,7 @@ package org.jclouds.io;
 
 import static com.google.common.collect.Iterables.any;
 import static com.google.common.io.BaseEncoding.base64;
+import static com.google.common.net.HttpHeaders.CACHE_CONTROL;
 import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
 import static com.google.common.net.HttpHeaders.CONTENT_ENCODING;
 import static com.google.common.net.HttpHeaders.CONTENT_LANGUAGE;
@@ -85,6 +86,8 @@ public interface ContentMetadataCodec {
       @Override
       public Multimap<String, String> toHeaders(ContentMetadata md) {
          Builder<String, String> builder = ImmutableMultimap.builder();
+         if (md.getCacheControl() != null)
+            builder.put(CACHE_CONTROL, md.getCacheControl());
          if (md.getContentType() != null)
             builder.put(CONTENT_TYPE, md.getContentType());
          if (md.getContentDisposition() != null)
@@ -111,7 +114,9 @@ public interface ContentMetadataCodec {
             }
          });
          for (Entry<String, String> header : headers.entries()) {
-            if (!chunked && CONTENT_LENGTH.equalsIgnoreCase(header.getKey())) {
+            if (CACHE_CONTROL.equalsIgnoreCase(header.getKey())) {
+               contentMetadata.setCacheControl(header.getValue());
+            } else if (!chunked && 
CONTENT_LENGTH.equalsIgnoreCase(header.getKey())) {
                
contentMetadata.setContentLength(Long.valueOf(header.getValue()));
             } else if (CONTENT_MD5.equalsIgnoreCase(header.getKey())) {
                
contentMetadata.setContentMD5(base64().decode(header.getValue()));

http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/core/src/main/java/org/jclouds/io/MutableContentMetadata.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/io/MutableContentMetadata.java 
b/core/src/main/java/org/jclouds/io/MutableContentMetadata.java
index 6efa771..6fb0a74 100644
--- a/core/src/main/java/org/jclouds/io/MutableContentMetadata.java
+++ b/core/src/main/java/org/jclouds/io/MutableContentMetadata.java
@@ -24,6 +24,8 @@ import com.google.common.hash.HashCode;
 
 public interface MutableContentMetadata extends ContentMetadata {
 
+   void setCacheControl(@Nullable String cacheControl);
+
    void setContentLength(@Nullable Long contentLength);
 
    /** @deprecated use {@link #setContentMD5(HashCode)} instead. */

http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/core/src/main/java/org/jclouds/io/payloads/BaseImmutableContentMetadata.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/jclouds/io/payloads/BaseImmutableContentMetadata.java 
b/core/src/main/java/org/jclouds/io/payloads/BaseImmutableContentMetadata.java
index 9624717..8578687 100644
--- 
a/core/src/main/java/org/jclouds/io/payloads/BaseImmutableContentMetadata.java
+++ 
b/core/src/main/java/org/jclouds/io/payloads/BaseImmutableContentMetadata.java
@@ -26,6 +26,7 @@ import com.google.common.hash.HashCode;
 
 public class BaseImmutableContentMetadata implements ContentMetadata {
 
+   protected String cacheControl;
    protected String contentType;
    protected Long contentLength;
    protected HashCode contentMD5;
@@ -34,8 +35,15 @@ public class BaseImmutableContentMetadata implements 
ContentMetadata {
    protected String contentEncoding;
    protected Date expires;
 
+   @Deprecated
    public BaseImmutableContentMetadata(String contentType, Long contentLength, 
byte[] contentMD5,
             String contentDisposition, String contentLanguage, String 
contentEncoding, Date expires) {
+      this(null, contentType, contentLength, contentMD5, contentDisposition, 
contentLanguage, contentEncoding, expires);
+   }
+
+   public BaseImmutableContentMetadata(String cacheControl, String 
contentType, Long contentLength, byte[] contentMD5,
+            String contentDisposition, String contentLanguage, String 
contentEncoding, Date expires) {
+      this.cacheControl = cacheControl;
       this.contentType = contentType;
       this.contentLength = contentLength;
       this.contentMD5 = contentMD5 == null ? null : 
HashCode.fromBytes(contentMD5);
@@ -45,6 +53,11 @@ public class BaseImmutableContentMetadata implements 
ContentMetadata {
       this.expires = expires;
    }
 
+   @Override
+   public String getCacheControl() {
+      return cacheControl;
+   }
+
    /**
     * {@inheritDoc}
     */
@@ -108,7 +121,8 @@ public class BaseImmutableContentMetadata implements 
ContentMetadata {
 
    @Override
    public String toString() {
-      return "[contentType=" + contentType + ", contentLength=" + 
contentLength + ", contentDisposition="
+      return "[cacheControl=" + cacheControl
+               + "contentType=" + contentType + ", contentLength=" + 
contentLength + ", contentDisposition="
                + contentDisposition + ", contentEncoding=" + contentEncoding + 
", contentLanguage=" + contentLanguage
                + ", contentMD5=" + contentMD5 + ", expires = " + expires + "]";
    }
@@ -128,6 +142,9 @@ public class BaseImmutableContentMetadata implements 
ContentMetadata {
       if (getClass() != obj.getClass())
          return false;
       BaseImmutableContentMetadata other = (BaseImmutableContentMetadata) obj;
+      if (!Objects.equal(cacheControl, other.cacheControl)) {
+         return false;
+      }
       if (contentDisposition == null) {
          if (other.contentDisposition != null)
             return false;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/core/src/main/java/org/jclouds/io/payloads/BaseMutableContentMetadata.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/jclouds/io/payloads/BaseMutableContentMetadata.java 
b/core/src/main/java/org/jclouds/io/payloads/BaseMutableContentMetadata.java
index 33e1793..5fd2880 100644
--- a/core/src/main/java/org/jclouds/io/payloads/BaseMutableContentMetadata.java
+++ b/core/src/main/java/org/jclouds/io/payloads/BaseMutableContentMetadata.java
@@ -27,6 +27,16 @@ import com.google.common.hash.HashCode;
 
 public class BaseMutableContentMetadata extends ContentMetadataBuilder 
implements MutableContentMetadata {
 
+   @Override
+   public String getCacheControl() {
+      return cacheControl;
+   }
+
+   @Override
+   public void setCacheControl(@Nullable String cacheControl) {
+      cacheControl(cacheControl);
+   }
+
    /**
     * {@inheritDoc}
     */
@@ -154,9 +164,14 @@ public class BaseMutableContentMetadata extends 
ContentMetadataBuilder implement
    }
 
    public static BaseMutableContentMetadata 
fromContentMetadata(ContentMetadata in) {
-      return (BaseMutableContentMetadata) new 
BaseMutableContentMetadata().contentType(in.getContentType())
-               
.contentLength(in.getContentLength()).contentMD5(in.getContentMD5()).contentDisposition(
-                        
in.getContentDisposition()).contentLanguage(in.getContentLanguage()).contentEncoding(
-                        in.getContentEncoding()).expires(in.getExpires());
+      return (BaseMutableContentMetadata) new BaseMutableContentMetadata()
+               .cacheControl(in.getCacheControl())
+               .contentDisposition(in.getContentDisposition())
+               .contentEncoding(in.getContentEncoding())
+               .contentLanguage(in.getContentLanguage())
+               .contentLength(in.getContentLength())
+               .contentMD5(in.getContentMD5())
+               .contentType(in.getContentType())
+               .expires(in.getExpires());
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/5fd7b1aa/core/src/main/java/org/jclouds/logging/internal/Wire.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/logging/internal/Wire.java 
b/core/src/main/java/org/jclouds/logging/internal/Wire.java
index 8c20c2d..b58a680 100644
--- a/core/src/main/java/org/jclouds/logging/internal/Wire.java
+++ b/core/src/main/java/org/jclouds/logging/internal/Wire.java
@@ -159,6 +159,7 @@ public abstract class Wire {
       MutableContentMetadata wiredMd = wiredPayload.getContentMetadata();
       if (oldMd.getContentLength() != null)
          wiredMd.setContentLength(oldMd.getContentLength());
+      wiredMd.setCacheControl(oldMd.getCacheControl());
       wiredMd.setContentType(oldMd.getContentType());
       wiredMd.setContentMD5(oldMd.getContentMD5());
       wiredMd.setContentDisposition(oldMd.getContentDisposition());

Reply via email to