Merge pull request #833 from everett-toews/rax-cdn-container-2

Updates to Rackspace CDN stuff (Resubmitted)
This commit is contained in:
Adrian Cole 2012-09-11 21:44:36 -07:00
commit 01ec559d64
12 changed files with 608 additions and 57 deletions

View File

@ -19,10 +19,12 @@
package org.jclouds.cloudfiles; package org.jclouds.cloudfiles;
import java.net.URI; import java.net.URI;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.HEAD; import javax.ws.rs.HEAD;
import javax.ws.rs.HeaderParam; import javax.ws.rs.HeaderParam;
@ -33,6 +35,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.blobstore.functions.ReturnNullOnContainerNotFound; import org.jclouds.blobstore.functions.ReturnNullOnContainerNotFound;
import org.jclouds.cloudfiles.binders.BindIterableToHeadersWithPurgeCDNObjectEmail;
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata; import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
import org.jclouds.cloudfiles.functions.ParseCdnUriFromHeaders; import org.jclouds.cloudfiles.functions.ParseCdnUriFromHeaders;
import org.jclouds.cloudfiles.functions.ParseContainerCDNMetadataFromHeaders; 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.filters.AuthenticateRequest;
import org.jclouds.openstack.swift.CommonSwiftAsyncClient; import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
import org.jclouds.openstack.swift.Storage; import org.jclouds.openstack.swift.Storage;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint; import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.Headers; import org.jclouds.rest.annotations.Headers;
@ -78,9 +82,6 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient {
@Endpoint(CDNManagement.class) @Endpoint(CDNManagement.class)
ListenableFuture<? extends Set<ContainerCDNMetadata>> listCDNContainers(ListCdnContainerOptions... options); ListenableFuture<? extends Set<ContainerCDNMetadata>> listCDNContainers(ListCdnContainerOptions... options);
// TODO: Container name is not included in CDN HEAD response headers, so we
// cannot populate it
// here.
/** /**
* @see CloudFilesClient#getCDNMetadata * @see CloudFilesClient#getCDNMetadata
*/ */
@ -91,6 +92,18 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient {
@Endpoint(CDNManagement.class) @Endpoint(CDNManagement.class)
ListenableFuture<ContainerCDNMetadata> getCDNMetadata(@PathParam("container") String container); ListenableFuture<ContainerCDNMetadata> 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<URI> enableCDN(@PathParam("container") String container,
@HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl,
@HeaderParam(CloudFilesHeaders.CDN_LOG_RETENTION) boolean logRetention);
/** /**
* @see CloudFilesClient#enableCDN(String, long); * @see CloudFilesClient#enableCDN(String, long);
*/ */
@ -100,7 +113,7 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient {
@ResponseParser(ParseCdnUriFromHeaders.class) @ResponseParser(ParseCdnUriFromHeaders.class)
@Endpoint(CDNManagement.class) @Endpoint(CDNManagement.class)
ListenableFuture<URI> enableCDN(@PathParam("container") String container, ListenableFuture<URI> enableCDN(@PathParam("container") String container,
@HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl); @HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl);
/** /**
* @see CloudFilesClient#enableCDN(String) * @see CloudFilesClient#enableCDN(String)
@ -113,14 +126,35 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient {
ListenableFuture<URI> enableCDN(@PathParam("container") String container); ListenableFuture<URI> enableCDN(@PathParam("container") String container);
/** /**
* @see CloudFilesClient#updateCDN * @see CloudFilesClient#updateCDN(long, boolean)
*/ */
@POST @POST
@Path("/{container}") @Path("/{container}")
@ResponseParser(ParseCdnUriFromHeaders.class) @ResponseParser(ParseCdnUriFromHeaders.class)
@Endpoint(CDNManagement.class) @Endpoint(CDNManagement.class)
ListenableFuture<URI> updateCDN(@PathParam("container") String container, ListenableFuture<URI> 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<URI> 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<URI> updateCDN(@PathParam("container") String container,
@HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl);
/** /**
* @see CloudFilesClient#disableCDN * @see CloudFilesClient#disableCDN
@ -131,6 +165,43 @@ public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient {
@Endpoint(CDNManagement.class) @Endpoint(CDNManagement.class)
ListenableFuture<Boolean> disableCDN(@PathParam("container") String container); ListenableFuture<Boolean> 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<Boolean> purgeCDNObject(@PathParam("container") String container,
@PathParam("object") String object,
@BinderParam(BindIterableToHeadersWithPurgeCDNObjectEmail.class) Iterable<String> emails);
/**
* @see CloudFilesClient#purgeCDNObject(String, String)
*/
@DELETE
@Path("/{container}/{object}")
@Endpoint(CDNManagement.class)
ListenableFuture<Boolean> purgeCDNObject(@PathParam("container") String container,
@PathParam("object") String object);
/**
* @see CloudFilesClient#setCDNStaticWebsiteIndex
*/
@POST
@Path("/{container}")
@Headers(keys = CloudFilesHeaders.CDN_WEBSITE_INDEX, values = "{index}")
ListenableFuture<Boolean> setCDNStaticWebsiteIndex(@PathParam("container") String container,
@PathParam("index") String index);
/**
* @see CloudFilesClient#setCDNStaticWebsiteError
*/
@POST
@Path("/{container}")
@Headers(keys = CloudFilesHeaders.CDN_WEBSITE_ERROR, values = "{error}")
ListenableFuture<Boolean> setCDNStaticWebsiteError(@PathParam("container") String container,
@PathParam("error") String error);
/** /**
* @see CloudFilesClient#getTemporaryUrlKey * @see CloudFilesClient#getTemporaryUrlKey

View File

@ -40,18 +40,72 @@ import org.jclouds.openstack.swift.CommonSwiftClient;
*/ */
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
public interface CloudFilesClient extends CommonSwiftClient { public interface CloudFilesClient extends CommonSwiftClient {
/**
* See http://docs.rackspace.com/files/api/v1/cf-devguide/content/List_CDN-Enabled_Containers-d1e2414.html
*/
Set<ContainerCDNMetadata> listCDNContainers(ListCdnContainerOptions... options); Set<ContainerCDNMetadata> 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); 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); 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); 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); 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); 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<String> 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 * Retrieve the key used to generate Temporary object access URLs
* *

View File

@ -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 extends HttpRequest> R bindToRequest(R request, Object input) {
checkArgument(checkNotNull(input, "input") instanceof Iterable<?>, "this binder is only valid for Iterable!");
checkNotNull(request, "request");
Iterable<String> emails = (Iterable<String>) input;
String emailCSV = Joiner.on(", ").join((List<String>) emails);
ImmutableMultimap<String, String> headers =
ImmutableMultimap.<String, String> of(CloudFilesHeaders.CDN_CONTAINER_PURGE_OBJECT_EMAIL, emailCSV);
return (R) request.toBuilder().replaceHeaders(headers).build();
}
}

View File

@ -29,17 +29,22 @@ public class ContainerCDNMetadata implements Comparable<ContainerCDNMetadata> {
private String name; private String name;
private boolean cdn_enabled; private boolean cdn_enabled;
private boolean log_retention;
private long ttl; private long ttl;
private URI cdn_uri; private URI cdn_uri;
private URI cdn_ssl_uri;
private URI cdn_streaming_uri;
private String referrer_acl; private String referrer_acl;
private String useragent_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.name = name;
this.cdn_enabled = cdnEnabled; this.cdn_enabled = cdnEnabled;
this.log_retention = logRetention;
this.ttl = ttl; this.ttl = ttl;
this.cdn_uri = cdnUri; this.cdn_uri = cdnUri;
this.cdn_ssl_uri = cdnSslUri;
this.cdn_streaming_uri = cdnStreamingUri;
} }
public ContainerCDNMetadata() { public ContainerCDNMetadata() {
@ -53,16 +58,36 @@ public class ContainerCDNMetadata implements Comparable<ContainerCDNMetadata> {
return name; return name;
} }
public URI getCDNUri() { public boolean isCDNEnabled() {
return cdn_uri; return cdn_enabled;
}
public boolean isLogRetention() {
return log_retention;
} }
public long getTTL() { public long getTTL() {
return ttl; return ttl;
} }
public boolean isCDNEnabled() { public URI getCDNUri() {
return cdn_enabled; 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) { public int compareTo(ContainerCDNMetadata o) {
@ -87,31 +112,21 @@ public class ContainerCDNMetadata implements Comparable<ContainerCDNMetadata> {
return false; return false;
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
ContainerCDNMetadata other = (ContainerCDNMetadata) obj; ContainerCDNMetadata other = (ContainerCDNMetadata) obj;
if (cdn_uri == null) { if (cdn_uri == null) {
if (other.cdn_uri != null) if (other.cdn_uri != null)
return false; return false;
} else if (!cdn_uri.equals(other.cdn_uri)) } else if (!cdn_uri.equals(other.cdn_uri))
return false; return false;
return true; return true;
} }
public String getReferrerACL() {
return referrer_acl;
}
public String getUseragentACL() {
return useragent_acl;
}
public boolean isLogRetention() {
return log_retention;
}
@Override @Override
public String toString() { public String toString() {
return String.format( return String.format(
"[name=%s, cdn_uri=%s, cdn_enabled=%s, log_retention=%s, referrer_acl=%s, ttl=%s, useragent_acl=%s]", "[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_uri, cdn_enabled, log_retention, referrer_acl, ttl, useragent_acl); name, cdn_enabled, log_retention, ttl, cdn_uri, cdn_ssl_uri, cdn_streaming_uri, referrer_acl, useragent_acl);
} }
} }

View File

@ -45,18 +45,26 @@ public class ParseContainerCDNMetadataFromHeaders implements
* parses the http response headers to create a new {@link ContainerCDNMetadata} object. * parses the http response headers to create a new {@link ContainerCDNMetadata} object.
*/ */
public ContainerCDNMetadata apply(final HttpResponse from) { public ContainerCDNMetadata apply(final HttpResponse from) {
String cdnUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_URI), String cdnEnabled = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_ENABLED), CloudFilesHeaders.CDN_ENABLED);
CloudFilesHeaders.CDN_URI); String cdnLogRetention = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_LOG_RETENTION), CloudFilesHeaders.CDN_LOG_RETENTION);
String cdnTTL = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_TTL), String cdnTTL = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_TTL), CloudFilesHeaders.CDN_TTL);
CloudFilesHeaders.CDN_TTL); String cdnUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_URI), CloudFilesHeaders.CDN_URI);
String cdnEnabled = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_ENABLED), String cdnSslUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_SSL_URI), CloudFilesHeaders.CDN_SSL_URI);
CloudFilesHeaders.CDN_ENABLED); String cdnStreamingUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_STREAMING_URI), CloudFilesHeaders.CDN_STREAMING_URI);
if (cdnUri == null) { if (cdnUri == null) {
// CDN is not, and has never, been enabled for this container. // CDN is not, and has never, been enabled for this container.
return null; return null;
} else { }
return new ContainerCDNMetadata(request.getEndpoint().getPath(), Boolean else {
.parseBoolean(cdnEnabled), Long.parseLong(cdnTTL), URI.create(cdnUri)); return new ContainerCDNMetadata(
request.getEndpoint().getPath(),
Boolean.parseBoolean(cdnEnabled),
Boolean.parseBoolean(cdnLogRetention),
Long.parseLong(cdnTTL),
URI.create(cdnUri),
URI.create(cdnSslUri),
URI.create(cdnStreamingUri));
} }
} }

View File

@ -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 ACCOUNT_TEMPORARY_URL_KEY = "X-Account-Meta-Temp-Url-Key";
public static final String CDN_ENABLED = "X-CDN-Enabled"; 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_TTL = "X-TTL";
public static final String CDN_URI = "X-CDN-URI"; 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_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";
} }

View File

@ -18,7 +18,16 @@
*/ */
package org.jclouds.cloudfiles; 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.internal.BaseCloudFilesRestClientExpectTest;
import org.jclouds.cloudfiles.reference.CloudFilesHeaders;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -30,7 +39,8 @@ import org.testng.annotations.Test;
@Test(groups = "unit", testName = "CloudFilesClientExpectTest") @Test(groups = "unit", testName = "CloudFilesClientExpectTest")
public class CloudFilesClientExpectTest extends BaseCloudFilesRestClientExpectTest { public class CloudFilesClientExpectTest extends BaseCloudFilesRestClientExpectTest {
public void deleteContainerReturnsTrueOn200And404() { @Test
public void testDeleteContainerReturnsTrueOn200And404() {
HttpRequest deleteContainer = HttpRequest HttpRequest deleteContainer = HttpRequest
.builder() .builder()
@ -50,7 +60,194 @@ public class CloudFilesClientExpectTest extends BaseCloudFilesRestClientExpectTe
CloudFilesClient clientWhenContainerDoesntExist = requestsSendResponses(initialAuth, responseWithAuth, deleteContainer, CloudFilesClient clientWhenContainerDoesntExist = requestsSendResponses(initialAuth, responseWithAuth, deleteContainer,
containerNotFound); containerNotFound);
assert clientWhenContainerDoesntExist.deleteContainerIfEmpty("container"); 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");
}
} }

View File

@ -27,6 +27,7 @@ import java.util.Set;
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata; import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
import org.jclouds.cloudfiles.options.ListCdnContainerOptions; import org.jclouds.cloudfiles.options.ListCdnContainerOptions;
import org.jclouds.openstack.swift.CommonSwiftClientLiveTest; import org.jclouds.openstack.swift.CommonSwiftClientLiveTest;
import org.jclouds.openstack.swift.domain.ContainerMetadata;
import org.jclouds.openstack.swift.domain.SwiftObject; import org.jclouds.openstack.swift.domain.SwiftObject;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -80,9 +81,16 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest<CloudFil
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN); cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
assertTrue(cdnMetadata.isCDNEnabled()); assertTrue(cdnMetadata.isCDNEnabled());
assertEquals(cdnMetadata.getCDNUri(), cdnUri); assertEquals(cdnMetadata.getCDNUri(), cdnUri);
// Test static website metadata
getApi().setCDNStaticWebsiteIndex(containerNameWithCDN, "index.html");
getApi().setCDNStaticWebsiteError(containerNameWithCDN, "error.html");
ContainerMetadata containerMetadata = getApi().getContainerMetadata(containerNameWithCDN);
assertEquals(containerMetadata.getMetadata().get("web-index"), "index.html");
assertEquals(containerMetadata.getMetadata().get("web-error"), "error.html");
cdnMetadata = getApi().getCDNMetadata(containerNameWithoutCDN); cdnMetadata = getApi().getCDNMetadata(containerNameWithoutCDN);
assert cdnMetadata == null || !cdnMetadata.isCDNEnabled() : containerNameWithoutCDN assert cdnMetadata == null || !cdnMetadata.isCDNEnabled() : containerNameWithoutCDN
@ -97,8 +105,15 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest<CloudFil
assertTrue(cdnMetadataList.size() >= 1); assertTrue(cdnMetadataList.size() >= 1);
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN); cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
final boolean cdnEnabled = cdnMetadata.isCDNEnabled();
final boolean logRetention = cdnMetadata.isLogRetention();
final long initialTTL = cdnMetadata.getTTL(); 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 // Test listing with options
cdnMetadataList = getApi().listCDNContainers(ListCdnContainerOptions.Builder.enabledOnly()); cdnMetadataList = getApi().listCDNContainers(ListCdnContainerOptions.Builder.enabledOnly());
@ -113,10 +128,9 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest<CloudFil
containerNameWithCDN.substring(0, containerNameWithCDN.length() - 1)).maxResults(1)); containerNameWithCDN.substring(0, containerNameWithCDN.length() - 1)).maxResults(1));
assertEquals(cdnMetadataList.size(), 1); assertEquals(cdnMetadataList.size(), 1);
// Enable CDN with PUT for the same container, this time with a custom // Enable CDN with PUT for the same container, this time with a custom TTL and Log Retention
// TTL
long ttl = 4000; long ttl = 4000;
getApi().enableCDN(containerNameWithCDN, ttl); getApi().enableCDN(containerNameWithCDN, ttl, true);
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN); cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
@ -126,7 +140,7 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest<CloudFil
// Check POST by updating TTL settings // Check POST by updating TTL settings
ttl = minimumTTL; ttl = minimumTTL;
getApi().updateCDN(containerNameWithCDN, minimumTTL); getApi().updateCDN(containerNameWithCDN, minimumTTL, false);
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN); cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
assertTrue(cdnMetadata.isCDNEnabled()); assertTrue(cdnMetadata.isCDNEnabled());
@ -135,10 +149,16 @@ public class CloudFilesClientLiveTest extends CommonSwiftClientLiveTest<CloudFil
// Confirm that minimum allowed value for TTL is 3600, lower values are // Confirm that minimum allowed value for TTL is 3600, lower values are
// ignored. // ignored.
getApi().updateCDN(containerNameWithCDN, 3599L); getApi().updateCDN(containerNameWithCDN, 3599L, false);
cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN); cdnMetadata = getApi().getCDNMetadata(containerNameWithCDN);
assertEquals(cdnMetadata.getTTL(), 3599L); assertEquals(cdnMetadata.getTTL(), 3599L);
// Test purging an object from a CDN container
SwiftObject swiftObject = newSwiftObject("hello", "hello.txt");
getApi().putObject(containerNameWithCDN, swiftObject);
assertTrue(getApi().purgeCDNObject(containerNameWithCDN, swiftObject.getInfo().getName()));
// Disable CDN with POST // Disable CDN with POST
assertTrue(getApi().disableCDN(containerNameWithCDN)); assertTrue(getApi().disableCDN(containerNameWithCDN));

View File

@ -0,0 +1,76 @@
/**
* 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 org.testng.Assert.assertEquals;
import java.util.List;
import org.jclouds.cloudfiles.reference.CloudFilesHeaders;
import org.jclouds.http.HttpRequest;
import org.jclouds.openstack.swift.CommonSwiftClientTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* Tests behavior of {@code BindIterableToHeadersWithPurgeCDNObjectEmail}
*
* @author Everett Toews
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "BindIterableToHeadersWithPurgeCDNObjectEmailTest")
public class BindIterableToHeadersWithPurgeCDNObjectEmailTest extends CommonSwiftClientTest {
@Test
public void testEmailBind() {
List<String> 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<String> emails = ImmutableList.of("foo@bar.com", "bar@foo.com");
BindIterableToHeadersWithPurgeCDNObjectEmail binder =
injector.getInstance(BindIterableToHeadersWithPurgeCDNObjectEmail.class);
binder.bindToRequest(null, emails);
}
}

View File

@ -51,12 +51,32 @@ public class ParseContainerCDNMetadataListFromJsonResponseTest {
InputStream is = getClass().getResourceAsStream("/test_list_cdn.json"); InputStream is = getClass().getResourceAsStream("/test_list_cdn.json");
Set<ContainerCDNMetadata> expects = ImmutableSortedSet.of( Set<ContainerCDNMetadata> expects = ImmutableSortedSet.of(
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"))
);
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")));
ParseJson<SortedSet<ContainerCDNMetadata>> parser = i.getInstance(Key ParseJson<SortedSet<ContainerCDNMetadata>> parser = i.getInstance(Key
.get(new TypeLiteral<ParseJson<SortedSet<ContainerCDNMetadata>>>() { .get(new TypeLiteral<ParseJson<SortedSet<ContainerCDNMetadata>>>() {
})); }));

View File

@ -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-blobstore.testCDNOperationsContainerWithCDN",
{"name":"adriancole-cfcdnint.testCDNOperationsContainerWithCDN","cdn_enabled":"false","ttl":3600,"cdn_uri":"http://c0320431.cdn.cloudfiles.rackspacecloud.com","referrer_acl":"","useragent_acl":"", "log_retention":"false"} "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":""
}
] ]

View File

@ -339,7 +339,7 @@ public abstract class CommonSwiftClientLiveTest<C extends CommonSwiftClient> ext
assert contentType.startsWith("text/plain") || "application/x-www-form-urlencoded".equals(contentType): contentType; 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(); SwiftObject object = getApi().newSwiftObject();
object.getInfo().setName(key); object.getInfo().setName(key);
object.setPayload(data); object.setPayload(data);