diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesAsyncClient.java b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesAsyncClient.java index 9b73ad6971..aa3c9aaf8d 100644 --- a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesAsyncClient.java +++ b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesAsyncClient.java @@ -19,10 +19,12 @@ package org.jclouds.cloudfiles; import java.net.URI; +import java.util.List; import java.util.Set; import java.util.concurrent.ExecutionException; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.HEAD; import javax.ws.rs.HeaderParam; @@ -33,6 +35,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.core.MediaType; import org.jclouds.blobstore.functions.ReturnNullOnContainerNotFound; +import org.jclouds.cloudfiles.binders.BindIterableToHeadersWithPurgeCDNObjectEmail; import org.jclouds.cloudfiles.domain.ContainerCDNMetadata; import org.jclouds.cloudfiles.functions.ParseCdnUriFromHeaders; import org.jclouds.cloudfiles.functions.ParseContainerCDNMetadataFromHeaders; @@ -42,6 +45,7 @@ import org.jclouds.cloudfiles.reference.CloudFilesHeaders; import org.jclouds.openstack.filters.AuthenticateRequest; import org.jclouds.openstack.swift.CommonSwiftAsyncClient; import org.jclouds.openstack.swift.Storage; +import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Endpoint; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.Headers; @@ -78,9 +82,6 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient { @Endpoint(CDNManagement.class) ListenableFuture> listCDNContainers(ListCdnContainerOptions... options); - // TODO: Container name is not included in CDN HEAD response headers, so we - // cannot populate it - // here. /** * @see CloudFilesClient#getCDNMetadata */ @@ -91,6 +92,18 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient { @Endpoint(CDNManagement.class) ListenableFuture getCDNMetadata(@PathParam("container") String container); + /** + * @see CloudFilesClient#enableCDN(String, long, boolean); + */ + @PUT + @Path("/{container}") + @Headers(keys = CloudFilesHeaders.CDN_ENABLED, values = "True") + @ResponseParser(ParseCdnUriFromHeaders.class) + @Endpoint(CDNManagement.class) + ListenableFuture enableCDN(@PathParam("container") String container, + @HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl, + @HeaderParam(CloudFilesHeaders.CDN_LOG_RETENTION) boolean logRetention); + /** * @see CloudFilesClient#enableCDN(String, long); */ @@ -100,7 +113,7 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient { @ResponseParser(ParseCdnUriFromHeaders.class) @Endpoint(CDNManagement.class) ListenableFuture enableCDN(@PathParam("container") String container, - @HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl); + @HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl); /** * @see CloudFilesClient#enableCDN(String) @@ -113,14 +126,35 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient { ListenableFuture enableCDN(@PathParam("container") String container); /** - * @see CloudFilesClient#updateCDN + * @see CloudFilesClient#updateCDN(long, boolean) */ @POST @Path("/{container}") @ResponseParser(ParseCdnUriFromHeaders.class) @Endpoint(CDNManagement.class) ListenableFuture updateCDN(@PathParam("container") String container, - @HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl); + @HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl, + @HeaderParam(CloudFilesHeaders.CDN_LOG_RETENTION) boolean logRetention); + + /** + * @see CloudFilesClient#updateCDN(boolean) + */ + @POST + @Path("/{container}") + @ResponseParser(ParseCdnUriFromHeaders.class) + @Endpoint(CDNManagement.class) + ListenableFuture updateCDN(@PathParam("container") String container, + @HeaderParam(CloudFilesHeaders.CDN_LOG_RETENTION) boolean logRetention); + + /** + * @see CloudFilesClient#updateCDN(long) + */ + @POST + @Path("/{container}") + @ResponseParser(ParseCdnUriFromHeaders.class) + @Endpoint(CDNManagement.class) + ListenableFuture updateCDN(@PathParam("container") String container, + @HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl); /** * @see CloudFilesClient#disableCDN @@ -131,6 +165,43 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient { @Endpoint(CDNManagement.class) ListenableFuture disableCDN(@PathParam("container") String container); + /** + * @see CloudFilesClient#purgeCDNObject(String, String, List) + */ + @DELETE + @Path("/{container}/{object}") + @Headers(keys = CloudFilesHeaders.CDN_CONTAINER_PURGE_OBJECT_EMAIL, values = "{email}") + @Endpoint(CDNManagement.class) + ListenableFuture purgeCDNObject(@PathParam("container") String container, + @PathParam("object") String object, + @BinderParam(BindIterableToHeadersWithPurgeCDNObjectEmail.class) Iterable emails); + + /** + * @see CloudFilesClient#purgeCDNObject(String, String) + */ + @DELETE + @Path("/{container}/{object}") + @Endpoint(CDNManagement.class) + ListenableFuture purgeCDNObject(@PathParam("container") String container, + @PathParam("object") String object); + + /** + * @see CloudFilesClient#setCDNStaticWebsiteIndex + */ + @POST + @Path("/{container}") + @Headers(keys = CloudFilesHeaders.CDN_WEBSITE_INDEX, values = "{index}") + ListenableFuture setCDNStaticWebsiteIndex(@PathParam("container") String container, + @PathParam("index") String index); + + /** + * @see CloudFilesClient#setCDNStaticWebsiteError + */ + @POST + @Path("/{container}") + @Headers(keys = CloudFilesHeaders.CDN_WEBSITE_ERROR, values = "{error}") + ListenableFuture setCDNStaticWebsiteError(@PathParam("container") String container, + @PathParam("error") String error); /** * @see CloudFilesClient#getTemporaryUrlKey diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesClient.java b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesClient.java index f52d7b8ad8..23e3dd3abb 100644 --- a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesClient.java +++ b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesClient.java @@ -40,17 +40,71 @@ import org.jclouds.openstack.swift.CommonSwiftClient; */ @Timeout(duration = 120, timeUnit = TimeUnit.SECONDS) public interface CloudFilesClient extends CommonSwiftClient { + + /** + * See http://docs.rackspace.com/files/api/v1/cf-devguide/content/List_CDN-Enabled_Containers-d1e2414.html + */ Set listCDNContainers(ListCdnContainerOptions... options); + /** + * See http://docs.rackspace.com/files/api/v1/cf-devguide/content/List_CDN-Enabled_Container_Metadata-d1e2711.html + */ ContainerCDNMetadata getCDNMetadata(String container); + /** + * See http://docs.rackspace.com/files/api/v1/cf-devguide/content/CDN-Enabled_Container-d1e2665.html + */ + URI enableCDN(String container, long ttl, boolean logRetention); + + /** + * See http://docs.rackspace.com/files/api/v1/cf-devguide/content/CDN-Enabled_Container-d1e2665.html + */ URI enableCDN(String container, long ttl); - + + /** + * See http://docs.rackspace.com/files/api/v1/cf-devguide/content/CDN-Enabled_Container-d1e2665.html + */ URI enableCDN(String container); + + /** + * See http://docs.rackspace.com/files/api/v1/cf-devguide/content/Update_CDN-Enabled_Container_Metadata-d1e2787.html + */ + URI updateCDN(String container, long ttl, boolean logRetention); + /** + * See http://docs.rackspace.com/files/api/v1/cf-devguide/content/Update_CDN-Enabled_Container_Metadata-d1e2787.html + */ + URI updateCDN(String container, boolean logRetention); + + /** + * See http://docs.rackspace.com/files/api/v1/cf-devguide/content/Update_CDN-Enabled_Container_Metadata-d1e2787.html + */ URI updateCDN(String container, long ttl); + /** + * See http://docs.rackspace.com/files/api/v1/cf-devguide/content/CDN-Enabled_Container-d1e2665.html + */ boolean disableCDN(String container); + + /** + * See http://docs.rackspace.com/files/api/v1/cf-devguide/content/Purge_CDN-Enabled_Objects-d1e3858.html + */ + boolean purgeCDNObject(String container, String object, Iterable emails); + + /** + * See http://docs.rackspace.com/files/api/v1/cf-devguide/content/Purge_CDN-Enabled_Objects-d1e3858.html + */ + boolean purgeCDNObject(String container, String object); + + /** + * http://docs.rackspace.com/files/api/v1/cf-devguide/content/Create_Static_Website-dle4000.html + */ + boolean setCDNStaticWebsiteIndex(String container, String index); + + /* + * http://docs.rackspace.com/files/api/v1/cf-devguide/content/Set_Error_Pages_for_Static_Website-dle4005.html + */ + boolean setCDNStaticWebsiteError(String container, String error); /** * Retrieve the key used to generate Temporary object access URLs diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/binders/BindIterableToHeadersWithPurgeCDNObjectEmail.java b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/binders/BindIterableToHeadersWithPurgeCDNObjectEmail.java new file mode 100644 index 0000000000..77c36a9214 --- /dev/null +++ b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/binders/BindIterableToHeadersWithPurgeCDNObjectEmail.java @@ -0,0 +1,53 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.cloudfiles.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.List; + +import javax.inject.Singleton; + +import org.jclouds.cloudfiles.reference.CloudFilesHeaders; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableMultimap; + +/** + * @author Everett Toews + */ +@Singleton +public class BindIterableToHeadersWithPurgeCDNObjectEmail implements Binder { + @SuppressWarnings("unchecked") + @Override + public R bindToRequest(R request, Object input) { + checkArgument(checkNotNull(input, "input") instanceof Iterable, "this binder is only valid for Iterable!"); + checkNotNull(request, "request"); + + Iterable emails = (Iterable) input; + String emailCSV = Joiner.on(", ").join((List) emails); + ImmutableMultimap headers = + ImmutableMultimap. of(CloudFilesHeaders.CDN_CONTAINER_PURGE_OBJECT_EMAIL, emailCSV); + + return (R) request.toBuilder().replaceHeaders(headers).build(); + } +} diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/domain/ContainerCDNMetadata.java b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/domain/ContainerCDNMetadata.java index 727cf238a4..a885ecb3f6 100644 --- a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/domain/ContainerCDNMetadata.java +++ b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/domain/ContainerCDNMetadata.java @@ -29,17 +29,22 @@ public class ContainerCDNMetadata implements Comparable { private String name; private boolean cdn_enabled; + private boolean log_retention; private long ttl; private URI cdn_uri; + private URI cdn_ssl_uri; + private URI cdn_streaming_uri; private String referrer_acl; private String useragent_acl; - private boolean log_retention; - public ContainerCDNMetadata(String name, boolean cdnEnabled, long ttl, URI cdnUri) { + public ContainerCDNMetadata(String name, boolean cdnEnabled, boolean logRetention, long ttl, URI cdnUri, URI cdnSslUri, URI cdnStreamingUri) { this.name = name; this.cdn_enabled = cdnEnabled; + this.log_retention = logRetention; this.ttl = ttl; this.cdn_uri = cdnUri; + this.cdn_ssl_uri = cdnSslUri; + this.cdn_streaming_uri = cdnStreamingUri; } public ContainerCDNMetadata() { @@ -53,16 +58,36 @@ public class ContainerCDNMetadata implements Comparable { return name; } - public URI getCDNUri() { - return cdn_uri; + public boolean isCDNEnabled() { + return cdn_enabled; + } + + public boolean isLogRetention() { + return log_retention; } public long getTTL() { return ttl; } - public boolean isCDNEnabled() { - return cdn_enabled; + public URI getCDNUri() { + return cdn_uri; + } + + public URI getCDNSslUri() { + return cdn_ssl_uri; + } + + public URI getCDNStreamingUri() { + return cdn_streaming_uri; + } + + public String getReferrerACL() { + return referrer_acl; + } + + public String getUseragentACL() { + return useragent_acl; } public int compareTo(ContainerCDNMetadata o) { @@ -87,31 +112,21 @@ public class ContainerCDNMetadata implements Comparable { return false; if (getClass() != obj.getClass()) return false; + ContainerCDNMetadata other = (ContainerCDNMetadata) obj; if (cdn_uri == null) { if (other.cdn_uri != null) return false; } else if (!cdn_uri.equals(other.cdn_uri)) return false; + return true; } - public String getReferrerACL() { - return referrer_acl; - } - - public String getUseragentACL() { - return useragent_acl; - } - - public boolean isLogRetention() { - return log_retention; - } - @Override public String toString() { return String.format( - "[name=%s, cdn_uri=%s, cdn_enabled=%s, log_retention=%s, referrer_acl=%s, ttl=%s, useragent_acl=%s]", - name, cdn_uri, cdn_enabled, log_retention, referrer_acl, ttl, useragent_acl); + "[name=%s, cdn_enabled=%s, log_retention=%s, ttl=%s, cdn_uri=%s, cdn_ssl_uri=%s, cdn_streaming_uri=%s, referrer_acl=%s, useragent_acl=%s]", + name, cdn_enabled, log_retention, ttl, cdn_uri, cdn_ssl_uri, cdn_streaming_uri, referrer_acl, useragent_acl); } } diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/functions/ParseContainerCDNMetadataFromHeaders.java b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/functions/ParseContainerCDNMetadataFromHeaders.java index b53a4144e6..42b9f8909c 100644 --- a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/functions/ParseContainerCDNMetadataFromHeaders.java +++ b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/functions/ParseContainerCDNMetadataFromHeaders.java @@ -45,18 +45,26 @@ public class ParseContainerCDNMetadataFromHeaders implements * parses the http response headers to create a new {@link ContainerCDNMetadata} object. */ public ContainerCDNMetadata apply(final HttpResponse from) { - String cdnUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_URI), - CloudFilesHeaders.CDN_URI); - String cdnTTL = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_TTL), - CloudFilesHeaders.CDN_TTL); - String cdnEnabled = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_ENABLED), - CloudFilesHeaders.CDN_ENABLED); + String cdnEnabled = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_ENABLED), CloudFilesHeaders.CDN_ENABLED); + String cdnLogRetention = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_LOG_RETENTION), CloudFilesHeaders.CDN_LOG_RETENTION); + String cdnTTL = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_TTL), CloudFilesHeaders.CDN_TTL); + String cdnUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_URI), CloudFilesHeaders.CDN_URI); + String cdnSslUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_SSL_URI), CloudFilesHeaders.CDN_SSL_URI); + String cdnStreamingUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_STREAMING_URI), CloudFilesHeaders.CDN_STREAMING_URI); + if (cdnUri == null) { // CDN is not, and has never, been enabled for this container. return null; - } else { - return new ContainerCDNMetadata(request.getEndpoint().getPath(), Boolean - .parseBoolean(cdnEnabled), Long.parseLong(cdnTTL), URI.create(cdnUri)); + } + else { + return new ContainerCDNMetadata( + request.getEndpoint().getPath(), + Boolean.parseBoolean(cdnEnabled), + Boolean.parseBoolean(cdnLogRetention), + Long.parseLong(cdnTTL), + URI.create(cdnUri), + URI.create(cdnSslUri), + URI.create(cdnStreamingUri)); } } diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/reference/CloudFilesHeaders.java b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/reference/CloudFilesHeaders.java index 377a79f4ea..10547a5f06 100644 --- a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/reference/CloudFilesHeaders.java +++ b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/reference/CloudFilesHeaders.java @@ -33,8 +33,15 @@ public interface CloudFilesHeaders extends SwiftHeaders { public static final String ACCOUNT_TEMPORARY_URL_KEY = "X-Account-Meta-Temp-Url-Key"; public static final String CDN_ENABLED = "X-CDN-Enabled"; - public static final String CDN_REFERRER_ACL = "X-Referrer-ACL "; + public static final String CDN_LOG_RETENTION = "X-Log-Retention"; public static final String CDN_TTL = "X-TTL"; public static final String CDN_URI = "X-CDN-URI"; + public static final String CDN_SSL_URI = "X-Cdn-Ssl-Uri"; + public static final String CDN_STREAMING_URI = "X-Cdn-Streaming-Uri"; + public static final String CDN_REFERRER_ACL = "X-Referrer-ACL "; public static final String CDN_USER_AGENT_ACL = "X-User-Agent-ACL"; + + public static final String CDN_CONTAINER_PURGE_OBJECT_EMAIL = "X-Purge-Email"; + public static final String CDN_WEBSITE_INDEX = "X-Container-Meta-Web-Index"; + public static final String CDN_WEBSITE_ERROR = "X-Container-Meta-Web-Error"; } diff --git a/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/CloudFilesClientExpectTest.java b/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/CloudFilesClientExpectTest.java index f69f2c2ccc..cd9b699e68 100644 --- a/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/CloudFilesClientExpectTest.java +++ b/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/CloudFilesClientExpectTest.java @@ -18,7 +18,16 @@ */ package org.jclouds.cloudfiles; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +import java.net.URI; + +import org.jclouds.blobstore.ContainerNotFoundException; +import org.jclouds.cloudfiles.domain.ContainerCDNMetadata; import org.jclouds.cloudfiles.internal.BaseCloudFilesRestClientExpectTest; +import org.jclouds.cloudfiles.reference.CloudFilesHeaders; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.testng.annotations.Test; @@ -30,7 +39,8 @@ import org.testng.annotations.Test; @Test(groups = "unit", testName = "CloudFilesClientExpectTest") public class CloudFilesClientExpectTest extends BaseCloudFilesRestClientExpectTest { - public void deleteContainerReturnsTrueOn200And404() { + @Test + public void testDeleteContainerReturnsTrueOn200And404() { HttpRequest deleteContainer = HttpRequest .builder() @@ -50,7 +60,194 @@ public class CloudFilesClientExpectTest extends BaseCloudFilesRestClientExpectTe CloudFilesClient clientWhenContainerDoesntExist = requestsSendResponses(initialAuth, responseWithAuth, deleteContainer, containerNotFound); assert clientWhenContainerDoesntExist.deleteContainerIfEmpty("container"); - } + @Test + public void testGetCDNMetadataWhenResponseIs2xxReturnsContainerCDNMetadata() { + HttpRequest cdnContainerRequest = HttpRequest.builder() + .method("HEAD") + .endpoint("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse cdnContainerResponse = HttpResponse.builder() + .addHeader(CloudFilesHeaders.CDN_ENABLED, "True") + .addHeader(CloudFilesHeaders.CDN_LOG_RETENTION, "True") + .addHeader(CloudFilesHeaders.CDN_TTL, "259200") + .addHeader(CloudFilesHeaders.CDN_URI, "http://546406d62bf471d7435d-36c33e76d676c80251b3c13ecb603b67.r19.cf1.rackcdn.com") + .addHeader(CloudFilesHeaders.CDN_SSL_URI, "https://e9f6fe92d217dc013369-36c33e76d676c80251b3c13ecb603b67.ssl.cf1.rackcdn.com") + .addHeader(CloudFilesHeaders.CDN_STREAMING_URI, "http://0e79346bc0a2564dcc5e-36c33e76d676c80251b3c13ecb603b67.r19.stream.cf1.rackcdn.com") + .statusCode(204) + .build(); + + CloudFilesClient cdnContainerClient = requestsSendResponses( + initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse); + + ContainerCDNMetadata containerCDNMetadata = cdnContainerClient.getCDNMetadata("container"); + assertTrue(containerCDNMetadata.isCDNEnabled()); + assertTrue(containerCDNMetadata.isLogRetention()); + assertEquals(containerCDNMetadata.getTTL(), 259200); + assertEquals(containerCDNMetadata.getCDNUri().toString(), "http://546406d62bf471d7435d-36c33e76d676c80251b3c13ecb603b67.r19.cf1.rackcdn.com"); + assertEquals(containerCDNMetadata.getCDNSslUri().toString(), "https://e9f6fe92d217dc013369-36c33e76d676c80251b3c13ecb603b67.ssl.cf1.rackcdn.com"); + assertEquals(containerCDNMetadata.getCDNStreamingUri().toString(), "http://0e79346bc0a2564dcc5e-36c33e76d676c80251b3c13ecb603b67.r19.stream.cf1.rackcdn.com"); + } + + @Test + public void testGetCDNMetadataWhenResponseIs404ReturnsNull() { + HttpRequest cdnContainerRequest = HttpRequest.builder() + .method("HEAD") + .endpoint("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse cdnContainerResponse = HttpResponse.builder() + .statusCode(404) + .build(); + + CloudFilesClient cdnContainerClient = requestsSendResponses( + initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse); + + assertNull(cdnContainerClient.getCDNMetadata("container")); + } + + @Test + public void testUpdateCDNMetadataWhenResponseIs2xxReturnsURI() { + HttpRequest cdnContainerRequest = HttpRequest.builder() + .method("POST") + .endpoint("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container") + .addHeader(CloudFilesHeaders.CDN_LOG_RETENTION, "true") + .addHeader(CloudFilesHeaders.CDN_TTL, "259200") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse cdnContainerResponse = HttpResponse.builder() + .addHeader(CloudFilesHeaders.CDN_ENABLED, "True") + .addHeader(CloudFilesHeaders.CDN_LOG_RETENTION, "True") + .addHeader(CloudFilesHeaders.CDN_TTL, "259200") + .addHeader(CloudFilesHeaders.CDN_URI, "http://546406d62bf471d7435d-36c33e76d676c80251b3c13ecb603b67.r19.cf1.rackcdn.com") + .addHeader(CloudFilesHeaders.CDN_SSL_URI, "https://e9f6fe92d217dc013369-36c33e76d676c80251b3c13ecb603b67.ssl.cf1.rackcdn.com") + .addHeader(CloudFilesHeaders.CDN_STREAMING_URI, "http://0e79346bc0a2564dcc5e-36c33e76d676c80251b3c13ecb603b67.r19.stream.cf1.rackcdn.com") + .statusCode(204) + .build(); + + CloudFilesClient cdnContainerClient = requestsSendResponses( + initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse); + + URI cdnURI = cdnContainerClient.updateCDN("container", 259200, true); + assertEquals(cdnURI.toString(), "http://546406d62bf471d7435d-36c33e76d676c80251b3c13ecb603b67.r19.cf1.rackcdn.com"); + } + + @Test(expectedExceptions = ContainerNotFoundException.class) + public void testUpdateCDNMetadataWhenResponseIs404ThrowsException() { + HttpRequest cdnContainerRequest = HttpRequest.builder() + .method("POST") + .endpoint("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container") + .addHeader(CloudFilesHeaders.CDN_LOG_RETENTION, "true") + .addHeader(CloudFilesHeaders.CDN_TTL, "259200") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse cdnContainerResponse = HttpResponse.builder() + .statusCode(404) + .build(); + + CloudFilesClient cdnContainerClient = requestsSendResponses( + initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse); + + cdnContainerClient.updateCDN("container", 259200, true); + } + + @Test + public void testPurgeCDNObjectWhenResponseIs2xxReturnsTrue() { + HttpRequest cdnContainerRequest = HttpRequest.builder() + .method("DELETE") + .endpoint("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container/foo.txt") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse cdnContainerResponse = HttpResponse.builder() + .statusCode(204) + .build(); + + CloudFilesClient cdnContainerClient = requestsSendResponses( + initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse); + + assertTrue(cdnContainerClient.purgeCDNObject("container", "foo.txt")); + } + + @Test + public void testSetCDNStaticWebsiteIndexWhenResponseIs2xxReturnsTrue() { + HttpRequest cdnContainerRequest = HttpRequest.builder() + .method("POST") + .endpoint("https://storage101.lon3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container") + .addHeader(CloudFilesHeaders.CDN_WEBSITE_INDEX, "index.html") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse cdnContainerResponse = HttpResponse.builder() + .statusCode(204) + .build(); + + CloudFilesClient cdnContainerClient = requestsSendResponses( + initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse); + + assertTrue(cdnContainerClient.setCDNStaticWebsiteIndex("container", "index.html")); + } + + @Test(expectedExceptions = ContainerNotFoundException.class) + public void testSetCDNStaticWebsiteIndexWhenResponseIs404ThrowsException() { + HttpRequest cdnContainerRequest = HttpRequest.builder() + .method("POST") + .endpoint("https://storage101.lon3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container") + .addHeader(CloudFilesHeaders.CDN_WEBSITE_INDEX, "index.html") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse cdnContainerResponse = HttpResponse.builder() + .statusCode(404) + .build(); + + CloudFilesClient cdnContainerClient = requestsSendResponses( + initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse); + + cdnContainerClient.setCDNStaticWebsiteIndex("container", "index.html"); + } + + @Test + public void testSetCDNStaticWebsiteErrorWhenResponseIs2xxReturnsTrue() { + HttpRequest cdnContainerRequest = HttpRequest.builder() + .method("POST") + .endpoint("https://storage101.lon3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container") + .addHeader(CloudFilesHeaders.CDN_WEBSITE_ERROR, "error.html") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse cdnContainerResponse = HttpResponse.builder() + .statusCode(204) + .build(); + + CloudFilesClient cdnContainerClient = requestsSendResponses( + initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse); + + assertTrue(cdnContainerClient.setCDNStaticWebsiteError("container", "error.html")); + } + + @Test(expectedExceptions = ContainerNotFoundException.class) + public void testSetCDNStaticWebsiteErrorWhenResponseIs404ThrowsException() { + HttpRequest cdnContainerRequest = HttpRequest.builder() + .method("POST") + .endpoint("https://storage101.lon3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953/container") + .addHeader(CloudFilesHeaders.CDN_WEBSITE_ERROR, "error.html") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse cdnContainerResponse = HttpResponse.builder() + .statusCode(404) + .build(); + + CloudFilesClient cdnContainerClient = requestsSendResponses( + initialAuth, responseWithAuth, cdnContainerRequest, cdnContainerResponse); + + cdnContainerClient.setCDNStaticWebsiteError("container", "error.html"); + } } \ No newline at end of file diff --git a/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/CloudFilesClientLiveTest.java b/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/CloudFilesClientLiveTest.java index b39533b149..b7a22c9eae 100644 --- a/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/CloudFilesClientLiveTest.java +++ b/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/CloudFilesClientLiveTest.java @@ -27,6 +27,7 @@ import java.util.Set; import org.jclouds.cloudfiles.domain.ContainerCDNMetadata; import org.jclouds.cloudfiles.options.ListCdnContainerOptions; import org.jclouds.openstack.swift.CommonSwiftClientLiveTest; +import org.jclouds.openstack.swift.domain.ContainerMetadata; import org.jclouds.openstack.swift.domain.SwiftObject; import org.testng.annotations.Test; @@ -80,16 +81,23 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest= 1); cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN); + final boolean cdnEnabled = cdnMetadata.isCDNEnabled(); + final boolean logRetention = cdnMetadata.isLogRetention(); final long initialTTL = cdnMetadata.getTTL(); - assertTrue(cdnMetadataList.contains(new ContainerCDNMetadata(containerNameWithCDN, true, initialTTL, cdnUri))); + final URI cdnSslUri = cdnMetadata.getCDNSslUri(); + final URI cdnStreamingUri = cdnMetadata.getCDNStreamingUri(); + assertTrue(cdnMetadataList.contains(new ContainerCDNMetadata( + containerNameWithCDN, cdnEnabled, logRetention, initialTTL, cdnUri, cdnSslUri, cdnStreamingUri))); + + // Test listing with options cdnMetadataList = getApi().listCDNContainers(ListCdnContainerOptions.Builder.enabledOnly()); assertTrue(Iterables.all(cdnMetadataList, new Predicate() { @@ -113,10 +128,9 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest emails = ImmutableList.of("foo@bar.com", "bar@foo.com"); + + HttpRequest request = HttpRequest.builder().method("DELETE").endpoint("http://localhost").build(); + BindIterableToHeadersWithPurgeCDNObjectEmail binder = + injector.getInstance(BindIterableToHeadersWithPurgeCDNObjectEmail.class); + + HttpRequest actualRequest = binder.bindToRequest(request, emails); + HttpRequest expectedRequest = HttpRequest.builder() + .method("DELETE") + .endpoint("http://localhost") + .addHeader(CloudFilesHeaders.CDN_CONTAINER_PURGE_OBJECT_EMAIL, "foo@bar.com, bar@foo.com") + .build(); + + assertEquals(actualRequest, expectedRequest); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testNullListIsBad() { + HttpRequest request = HttpRequest.builder().method("DELETE").endpoint("http://localhost").build(); + BindIterableToHeadersWithPurgeCDNObjectEmail binder = + injector.getInstance(BindIterableToHeadersWithPurgeCDNObjectEmail.class); + + binder.bindToRequest(request, null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testNullRequestIsBad() { + List emails = ImmutableList.of("foo@bar.com", "bar@foo.com"); + BindIterableToHeadersWithPurgeCDNObjectEmail binder = + injector.getInstance(BindIterableToHeadersWithPurgeCDNObjectEmail.class); + + binder.bindToRequest(null, emails); + } +} diff --git a/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/functions/ParseContainerCDNMetadataListFromJsonResponseTest.java b/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/functions/ParseContainerCDNMetadataListFromJsonResponseTest.java index 42837baebf..235fb278d4 100644 --- a/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/functions/ParseContainerCDNMetadataListFromJsonResponseTest.java +++ b/apis/cloudfiles/src/test/java/org/jclouds/cloudfiles/functions/ParseContainerCDNMetadataListFromJsonResponseTest.java @@ -51,12 +51,32 @@ public class ParseContainerCDNMetadataListFromJsonResponseTest { InputStream is = getClass().getResourceAsStream("/test_list_cdn.json"); Set expects = ImmutableSortedSet.of( - - new ContainerCDNMetadata("adriancole-blobstore.testCDNOperationsContainerWithCDN", false, 3600, URI - .create("http://c0354712.cdn.cloudfiles.rackspacecloud.com")), new ContainerCDNMetadata( - "adriancole-blobstore5", true, 28800, URI.create("http://c0404671.cdn.cloudfiles.rackspacecloud.com")), - new ContainerCDNMetadata("adriancole-cfcdnint.testCDNOperationsContainerWithCDN", false, 3600, URI - .create("http://c0320431.cdn.cloudfiles.rackspacecloud.com"))); + new ContainerCDNMetadata( + "adriancole-blobstore.testCDNOperationsContainerWithCDN", + false, + false, + 3600, + URI.create("http://c0354712.cdn.cloudfiles.rackspacecloud.com"), + URI.create("https://c0354712.cdn.ssl.cloudfiles.rackspacecloud.com"), + URI.create("http://c0354712.cdn.stream.cloudfiles.rackspacecloud.com")), + new ContainerCDNMetadata( + "adriancole-blobstore5", + true, + false, + 28800, + URI.create("http://c0404671.cdn.cloudfiles.rackspacecloud.com"), + URI.create("https://c0404671.cdn.ssl.cloudfiles.rackspacecloud.com"), + URI.create("http://c0404671.cdn.stream.cloudfiles.rackspacecloud.com")), + new ContainerCDNMetadata( + "adriancole-cfcdnint.testCDNOperationsContainerWithCDN", + false, + false, + 3600, + URI.create("http://c0320431.cdn.cloudfiles.rackspacecloud.com"), + URI.create("https://c0320431.cdn.ssl.cloudfiles.rackspacecloud.com"), + URI.create("http://c0320431.cdn.stream.cloudfiles.rackspacecloud.com")) + ); + ParseJson> parser = i.getInstance(Key .get(new TypeLiteral>>() { })); diff --git a/apis/cloudfiles/src/test/resources/test_list_cdn.json b/apis/cloudfiles/src/test/resources/test_list_cdn.json index bea7be869e..9562816160 100644 --- a/apis/cloudfiles/src/test/resources/test_list_cdn.json +++ b/apis/cloudfiles/src/test/resources/test_list_cdn.json @@ -1,5 +1,35 @@ [ -{"name":"adriancole-blobstore.testCDNOperationsContainerWithCDN","cdn_enabled":"false","ttl":3600,"cdn_uri":"http://c0354712.cdn.cloudfiles.rackspacecloud.com","referrer_acl":"","useragent_acl":"", "log_retention":"false"}, -{"name":"adriancole-blobstore5","cdn_enabled":"true","ttl":28800,"cdn_uri":"http://c0404671.cdn.cloudfiles.rackspacecloud.com","referrer_acl":"","useragent_acl":"", "log_retention":"false"}, -{"name":"adriancole-cfcdnint.testCDNOperationsContainerWithCDN","cdn_enabled":"false","ttl":3600,"cdn_uri":"http://c0320431.cdn.cloudfiles.rackspacecloud.com","referrer_acl":"","useragent_acl":"", "log_retention":"false"} + { + "name":"adriancole-blobstore.testCDNOperationsContainerWithCDN", + "cdn_enabled":"false", + "log_retention":"false", + "ttl":3600, + "cdn_uri":"http://c0354712.cdn.cloudfiles.rackspacecloud.com", + "cdn_ssl_uri":"https://c0354712.cdn.ssl.cloudfiles.rackspacecloud.com", + "cdn_streaming_uri":"http://c0354712.cdn.stream.cloudfiles.rackspacecloud.com", + "referrer_acl":"", + "useragent_acl":"" + }, + { + "name":"adriancole-blobstore5", + "cdn_enabled":"true", + "log_retention":"false", + "ttl":28800, + "cdn_uri":"http://c0404671.cdn.cloudfiles.rackspacecloud.com", + "cdn_ssl_uri":"https://c0404671.cdn.ssl.cloudfiles.rackspacecloud.com", + "cdn_streaming_uri":"http://c0404671.cdn.stream.cloudfiles.rackspacecloud.com", + "referrer_acl":"", + "useragent_acl":"" + }, + { + "name":"adriancole-cfcdnint.testCDNOperationsContainerWithCDN", + "cdn_enabled":"false", + "log_retention":"false", + "ttl":3600, + "cdn_uri":"http://c0320431.cdn.cloudfiles.rackspacecloud.com", + "cdn_ssl_uri":"https://c0320431.cdn.ssl.cloudfiles.rackspacecloud.com", + "cdn_streaming_uri":"http://c0320431.cdn.stream.cloudfiles.rackspacecloud.com", + "referrer_acl":"", + "useragent_acl":"" + } ] \ No newline at end of file diff --git a/apis/swift/src/test/java/org/jclouds/openstack/swift/CommonSwiftClientLiveTest.java b/apis/swift/src/test/java/org/jclouds/openstack/swift/CommonSwiftClientLiveTest.java index d1a214ea2a..23fbe2d8ec 100644 --- a/apis/swift/src/test/java/org/jclouds/openstack/swift/CommonSwiftClientLiveTest.java +++ b/apis/swift/src/test/java/org/jclouds/openstack/swift/CommonSwiftClientLiveTest.java @@ -339,7 +339,7 @@ public abstract class CommonSwiftClientLiveTest ext assert contentType.startsWith("text/plain") || "application/x-www-form-urlencoded".equals(contentType): contentType; } - private SwiftObject newSwiftObject(String data, String key) throws IOException { + protected SwiftObject newSwiftObject(String data, String key) throws IOException { SwiftObject object = getApi().newSwiftObject(); object.getInfo().setName(key); object.setPayload(data);