mirror of https://github.com/apache/jclouds.git
Issue 429: pulled cloudfiles-specific logic apart from swift
This commit is contained in:
parent
e68a67042e
commit
17629960cd
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.rackspace;
|
||||
package org.jclouds.cloudfiles;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
@ -36,6 +36,6 @@ import javax.inject.Qualifier;
|
|||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||
@Qualifier
|
||||
public @interface CloudFilesCDN {
|
||||
public @interface CDNManagement {
|
||||
|
||||
}
|
|
@ -20,12 +20,10 @@
|
|||
package org.jclouds.cloudfiles;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
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;
|
||||
|
@ -35,45 +33,22 @@ import javax.ws.rs.Path;
|
|||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.blobstore.binders.BindMapToHeadersWithPrefix;
|
||||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.blobstore.functions.ReturnFalseOnContainerNotFound;
|
||||
import org.jclouds.blobstore.functions.ReturnFalseOnKeyNotFound;
|
||||
import org.jclouds.blobstore.functions.ReturnNullOnKeyNotFound;
|
||||
import org.jclouds.blobstore.functions.ThrowContainerNotFoundOn404;
|
||||
import org.jclouds.http.functions.ParseETagHeader;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.rackspace.CloudFiles;
|
||||
import org.jclouds.rackspace.CloudFilesCDN;
|
||||
import org.jclouds.cloudfiles.binders.BindCFObjectMetadataToRequest;
|
||||
import org.jclouds.cloudfiles.domain.AccountMetadata;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ContainerMetadata;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.cloudfiles.functions.ObjectName;
|
||||
import org.jclouds.cloudfiles.functions.ParseAccountMetadataResponseFromHeaders;
|
||||
import org.jclouds.cloudfiles.functions.ParseCdnUriFromHeaders;
|
||||
import org.jclouds.cloudfiles.functions.ParseContainerCDNMetadataFromHeaders;
|
||||
import org.jclouds.cloudfiles.functions.ParseObjectFromHeadersAndHttpContent;
|
||||
import org.jclouds.cloudfiles.functions.ParseObjectInfoFromHeaders;
|
||||
import org.jclouds.cloudfiles.functions.ParseObjectInfoListFromJsonResponse;
|
||||
import org.jclouds.cloudfiles.functions.ReturnTrueOn404FalseOn409;
|
||||
import org.jclouds.cloudfiles.options.ListCdnContainerOptions;
|
||||
import org.jclouds.cloudfiles.options.ListContainerOptions;
|
||||
import org.jclouds.cloudfiles.reference.CloudFilesHeaders;
|
||||
import org.jclouds.rackspace.filters.AuthenticateRequest;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||
import org.jclouds.openstack.swift.Storage;
|
||||
import org.jclouds.openstack.swift.functions.ParseContainerCDNMetadataFromHeaders;
|
||||
import org.jclouds.rest.annotations.Endpoint;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.Headers;
|
||||
import org.jclouds.rest.annotations.ParamParser;
|
||||
import org.jclouds.rest.annotations.QueryParams;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
|
@ -90,35 +65,8 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
*/
|
||||
@SkipEncoding('/')
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@Endpoint(CloudFiles.class)
|
||||
public interface CloudFilesAsyncClient {
|
||||
|
||||
CFObject newCFObject();
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#getAccountStatistics
|
||||
*/
|
||||
@HEAD
|
||||
@ResponseParser(ParseAccountMetadataResponseFromHeaders.class)
|
||||
@Path("/")
|
||||
ListenableFuture<AccountMetadata> getAccountStatistics();
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#listContainers
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@QueryParams(keys = "format", values = "json")
|
||||
@Path("/")
|
||||
ListenableFuture<? extends Set<ContainerMetadata>> listContainers(ListContainerOptions... options);
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#setObjectInfo
|
||||
*/
|
||||
@POST
|
||||
@Path("/{container}/{name}")
|
||||
ListenableFuture<Boolean> setObjectInfo(@PathParam("container") String container, @PathParam("name") String name,
|
||||
@BinderParam(BindMapToHeadersWithPrefix.class) Map<String, String> userMetadata);
|
||||
@Endpoint(Storage.class)
|
||||
public interface CloudFilesAsyncClient extends CommonSwiftAsyncClient {
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#listCDNContainers
|
||||
|
@ -127,7 +75,7 @@ public interface CloudFilesAsyncClient {
|
|||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@QueryParams(keys = "format", values = "json")
|
||||
@Path("/")
|
||||
@Endpoint(CloudFilesCDN.class)
|
||||
@Endpoint(CDNManagement.class)
|
||||
ListenableFuture<? extends Set<ContainerCDNMetadata>> listCDNContainers(ListCdnContainerOptions... options);
|
||||
|
||||
// TODO: Container name is not included in CDN HEAD response headers, so we
|
||||
|
@ -140,7 +88,7 @@ public interface CloudFilesAsyncClient {
|
|||
@ResponseParser(ParseContainerCDNMetadataFromHeaders.class)
|
||||
@ExceptionParser(ThrowContainerNotFoundOn404.class)
|
||||
@Path("/{container}")
|
||||
@Endpoint(CloudFilesCDN.class)
|
||||
@Endpoint(CDNManagement.class)
|
||||
ListenableFuture<ContainerCDNMetadata> getCDNMetadata(@PathParam("container") String container);
|
||||
|
||||
/**
|
||||
|
@ -150,7 +98,7 @@ public interface CloudFilesAsyncClient {
|
|||
@Path("/{container}")
|
||||
@Headers(keys = CloudFilesHeaders.CDN_ENABLED, values = "True")
|
||||
@ResponseParser(ParseCdnUriFromHeaders.class)
|
||||
@Endpoint(CloudFilesCDN.class)
|
||||
@Endpoint(CDNManagement.class)
|
||||
ListenableFuture<URI> enableCDN(@PathParam("container") String container,
|
||||
@HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl);
|
||||
|
||||
|
@ -161,7 +109,7 @@ public interface CloudFilesAsyncClient {
|
|||
@Path("/{container}")
|
||||
@Headers(keys = CloudFilesHeaders.CDN_ENABLED, values = "True")
|
||||
@ResponseParser(ParseCdnUriFromHeaders.class)
|
||||
@Endpoint(CloudFilesCDN.class)
|
||||
@Endpoint(CDNManagement.class)
|
||||
ListenableFuture<URI> enableCDN(@PathParam("container") String container);
|
||||
|
||||
/**
|
||||
|
@ -170,7 +118,7 @@ public interface CloudFilesAsyncClient {
|
|||
@POST
|
||||
@Path("/{container}")
|
||||
@ResponseParser(ParseCdnUriFromHeaders.class)
|
||||
@Endpoint(CloudFilesCDN.class)
|
||||
@Endpoint(CDNManagement.class)
|
||||
ListenableFuture<URI> updateCDN(@PathParam("container") String container,
|
||||
@HeaderParam(CloudFilesHeaders.CDN_TTL) long ttl);
|
||||
|
||||
|
@ -180,86 +128,7 @@ public interface CloudFilesAsyncClient {
|
|||
@POST
|
||||
@Path("/{container}")
|
||||
@Headers(keys = CloudFilesHeaders.CDN_ENABLED, values = "False")
|
||||
@Endpoint(CloudFilesCDN.class)
|
||||
@Endpoint(CDNManagement.class)
|
||||
ListenableFuture<Boolean> disableCDN(@PathParam("container") String container);
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#createContainer
|
||||
*/
|
||||
@PUT
|
||||
@Path("/{container}")
|
||||
ListenableFuture<Boolean> createContainer(@PathParam("container") String container);
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#deleteContainerIfEmpty
|
||||
*/
|
||||
@DELETE
|
||||
@ExceptionParser(ReturnTrueOn404FalseOn409.class)
|
||||
@Path("/{container}")
|
||||
ListenableFuture<Boolean> deleteContainerIfEmpty(@PathParam("container") String container);
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#listObjects
|
||||
*/
|
||||
@GET
|
||||
@QueryParams(keys = "format", values = "json")
|
||||
@ResponseParser(ParseObjectInfoListFromJsonResponse.class)
|
||||
@Path("/{container}")
|
||||
ListenableFuture<PageSet<ObjectInfo>> listObjects(@PathParam("container") String container,
|
||||
ListContainerOptions... options);
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#containerExists
|
||||
*/
|
||||
@HEAD
|
||||
@Path("/{container}")
|
||||
@ExceptionParser(ReturnFalseOnContainerNotFound.class)
|
||||
ListenableFuture<Boolean> containerExists(@PathParam("container") String container);
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#putObject
|
||||
*/
|
||||
@PUT
|
||||
@Path("/{container}/{name}")
|
||||
@ResponseParser(ParseETagHeader.class)
|
||||
ListenableFuture<String> putObject(
|
||||
@PathParam("container") String container,
|
||||
@PathParam("name") @ParamParser(ObjectName.class) @BinderParam(BindCFObjectMetadataToRequest.class) CFObject object);
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#getObject
|
||||
*/
|
||||
@GET
|
||||
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
|
||||
@ExceptionParser(ReturnNullOnKeyNotFound.class)
|
||||
@Path("/{container}/{name}")
|
||||
ListenableFuture<CFObject> getObject(@PathParam("container") String container, @PathParam("name") String name,
|
||||
GetOptions... options);
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#getObjectInfo
|
||||
*/
|
||||
@HEAD
|
||||
@ResponseParser(ParseObjectInfoFromHeaders.class)
|
||||
@ExceptionParser(ReturnNullOnKeyNotFound.class)
|
||||
@Path("/{container}/{name}")
|
||||
ListenableFuture<MutableObjectInfoWithMetadata> getObjectInfo(@PathParam("container") String container,
|
||||
@PathParam("name") String name);
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#objectExists
|
||||
*/
|
||||
@HEAD
|
||||
@ExceptionParser(ReturnFalseOnKeyNotFound.class)
|
||||
@Path("/{container}/{name}")
|
||||
ListenableFuture<Boolean> objectExists(@PathParam("container") String container, @PathParam("name") String name);
|
||||
|
||||
/**
|
||||
* @see CloudFilesClient#removeObject
|
||||
*/
|
||||
@DELETE
|
||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||
@Path("/{container}/{name}")
|
||||
ListenableFuture<Void> removeObject(@PathParam("container") String container, @PathParam("name") String name);
|
||||
|
||||
}
|
||||
|
|
|
@ -20,84 +20,27 @@
|
|||
package org.jclouds.cloudfiles;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.cloudfiles.domain.AccountMetadata;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ContainerMetadata;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.cloudfiles.options.ListCdnContainerOptions;
|
||||
import org.jclouds.cloudfiles.options.ListContainerOptions;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.swift.CommonSwiftClient;
|
||||
|
||||
/**
|
||||
* Provides access to Cloud Files via their REST API.
|
||||
* <p/>
|
||||
* All commands return a Future of the result from Cloud Files. Any exceptions incurred
|
||||
* during processing will be wrapped in an {@link ExecutionException} as documented in
|
||||
* {@link Future#get()}.
|
||||
* All commands return a Future of the result from Cloud Files. Any exceptions incurred during
|
||||
* processing will be wrapped in an {@link ExecutionException} as documented in {@link Future#get()}.
|
||||
*
|
||||
* @see <a href="http://www.rackspacecloud.com/cf-devguide-20090812.pdf" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
|
||||
public interface CloudFilesClient {
|
||||
|
||||
CFObject newCFObject();
|
||||
|
||||
/**
|
||||
* HEAD operations against an identity are performed to retrieve the number of Containers and the
|
||||
* total bytes stored in Cloud Files for the identity.
|
||||
* <p/>
|
||||
* Determine the number of Containers within the identity and the total bytes stored. Since the
|
||||
* storage system is designed to store large amounts of data, care should be taken when
|
||||
* representing the total bytes response as an integer; when possible, convert it to a 64-bit
|
||||
* unsigned integer if your platform supports that primitive flavor.
|
||||
*/
|
||||
AccountMetadata getAccountStatistics();
|
||||
|
||||
/**
|
||||
* GET operations against the X-Storage-Url for an identity are performed to retrieve a list of
|
||||
* existing storage
|
||||
* <p/>
|
||||
* Containers ordered by name. The following list describes the optional query parameters that
|
||||
* are supported with this request.
|
||||
* <ul>
|
||||
* <li>limit - For an integer value N, limits the number of results to at most N values.</li>
|
||||
* <li>marker - Given a string value X, return Object names greater in value than the specied
|
||||
* marker.</li>
|
||||
* <li>format - Specify either json or xml to return the respective serialized response.</li>
|
||||
* </ul>
|
||||
* <p/>
|
||||
* At this time, a prex query parameter is not supported at the Account level.
|
||||
*
|
||||
*<h4>Large Container Lists</h4>
|
||||
* The system will return a maximum of 10,000 Container names per request. To retrieve subsequent
|
||||
* container names, another request must be made with a marker parameter. The marker indicates
|
||||
* where the last list left off and the system will return container names greater than this
|
||||
* marker, up to 10,000 again. Note that the marker value should be URL encoded prior to sending
|
||||
* the HTTP request.
|
||||
* <p/>
|
||||
* If 10,000 is larger than desired, a limit parameter may be given.
|
||||
* <p/>
|
||||
* If the number of container names returned equals the limit given (or 10,000 if no limit is
|
||||
* given), it can be assumed there are more container names to be listed. If the container name
|
||||
* list is exactly divisible by the limit, the last request will simply have no content.
|
||||
*/
|
||||
Set<ContainerMetadata> listContainers(ListContainerOptions... options);
|
||||
|
||||
boolean setObjectInfo(String container, String name, Map<String, String> userMetadata);
|
||||
|
||||
public interface CloudFilesClient extends CommonSwiftClient {
|
||||
Set<ContainerCDNMetadata> listCDNContainers(ListCdnContainerOptions... options);
|
||||
|
||||
ContainerCDNMetadata getCDNMetadata(String container);
|
||||
|
@ -110,28 +53,4 @@ public interface CloudFilesClient {
|
|||
|
||||
boolean disableCDN(String container);
|
||||
|
||||
boolean createContainer(String container);
|
||||
|
||||
boolean deleteContainerIfEmpty(String container);
|
||||
|
||||
PageSet<ObjectInfo> listObjects(String container, ListContainerOptions... options);
|
||||
|
||||
boolean containerExists(String container);
|
||||
|
||||
@Timeout(duration = 5 * 1024 * 1024 / 128, timeUnit = TimeUnit.SECONDS)
|
||||
String putObject(String container, CFObject object);
|
||||
|
||||
@Timeout(duration = 5 * 1024 * 1024 / 512, timeUnit = TimeUnit.SECONDS)
|
||||
CFObject getObject(String container, String name, GetOptions... options);
|
||||
|
||||
MutableObjectInfoWithMetadata getObjectInfo(String container, String name);
|
||||
|
||||
void removeObject(String container, String name);
|
||||
|
||||
/**
|
||||
* @throws ContainerNotFoundException
|
||||
* if the container is not present.
|
||||
*/
|
||||
boolean objectExists(String container, String name);
|
||||
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import java.util.Properties;
|
|||
import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.cloudfiles.blobstore.config.CloudFilesBlobStoreContextModule;
|
||||
import org.jclouds.openstack.swift.blobstore.config.SwiftBlobStoreContextModule;
|
||||
import org.jclouds.cloudfiles.config.CloudFilesRestClientModule;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
|
@ -53,7 +53,7 @@ public class CloudFilesContextBuilder extends
|
|||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new CloudFilesBlobStoreContextModule());
|
||||
modules.add(new SwiftBlobStoreContextModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,22 +19,27 @@
|
|||
|
||||
package org.jclouds.cloudfiles;
|
||||
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.rackspace.RackspacePropertiesBuilder;
|
||||
import org.jclouds.openstack.OpenStackAuthAsyncClient;
|
||||
import org.jclouds.openstack.swift.SwiftPropertiesBuilder;
|
||||
|
||||
/**
|
||||
* Builds properties used in CloudFiles Connections
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CloudFilesPropertiesBuilder extends RackspacePropertiesBuilder {
|
||||
public class CloudFilesPropertiesBuilder extends SwiftPropertiesBuilder {
|
||||
@Override
|
||||
protected Properties defaultProperties() {
|
||||
Properties properties = super.defaultProperties();
|
||||
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "X-Object-Meta-");
|
||||
properties.setProperty(PROPERTY_REGIONS, "US");
|
||||
properties.setProperty(PROPERTY_ENDPOINT, "https://auth.api.rackspacecloud.com");
|
||||
properties.setProperty(PROPERTY_API_VERSION, OpenStackAuthAsyncClient.VERSION);
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
@ -42,8 +47,4 @@ public class CloudFilesPropertiesBuilder extends RackspacePropertiesBuilder {
|
|||
super(properties);
|
||||
}
|
||||
|
||||
protected CloudFilesPropertiesBuilder withMetaPrefix(String prefix) {
|
||||
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, prefix);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,19 +19,22 @@
|
|||
|
||||
package org.jclouds.cloudfiles.config;
|
||||
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.cloudfiles.CDNManagement;
|
||||
import org.jclouds.cloudfiles.CloudFilesAsyncClient;
|
||||
import org.jclouds.cloudfiles.CloudFilesClient;
|
||||
import org.jclouds.cloudfiles.handlers.ParseCloudFilesErrorFromHttpResponse;
|
||||
import org.jclouds.rackspace.config.RackspaceAuthenticationRestModule;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
|
||||
import org.jclouds.openstack.reference.AuthHeaders;
|
||||
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||
import org.jclouds.openstack.swift.CommonSwiftClient;
|
||||
import org.jclouds.openstack.swift.config.BaseSwiftRestClientModule;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -39,33 +42,28 @@ import com.google.inject.Module;
|
|||
*/
|
||||
@ConfiguresRestClient
|
||||
@RequiresHttp
|
||||
public class CloudFilesRestClientModule extends
|
||||
RestClientModule<CloudFilesClient, CloudFilesAsyncClient> {
|
||||
private Module authModule;
|
||||
public class CloudFilesRestClientModule extends BaseSwiftRestClientModule<CloudFilesClient, CloudFilesAsyncClient> {
|
||||
|
||||
public CloudFilesRestClientModule() {
|
||||
this(new RackspaceAuthenticationRestModule());
|
||||
}
|
||||
|
||||
public CloudFilesRestClientModule(Module authModule) {
|
||||
super(CloudFilesClient.class, CloudFilesAsyncClient.class);
|
||||
this.authModule = authModule;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(authModule);
|
||||
install(new CFObjectModule());
|
||||
super.configure();
|
||||
@Provides
|
||||
@Singleton
|
||||
CommonSwiftClient provideCommonSwiftClient(CloudFilesClient in) {
|
||||
return in;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
|
||||
ParseCloudFilesErrorFromHttpResponse.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(
|
||||
ParseCloudFilesErrorFromHttpResponse.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(
|
||||
ParseCloudFilesErrorFromHttpResponse.class);
|
||||
@Provides
|
||||
@Singleton
|
||||
CommonSwiftAsyncClient provideCommonSwiftClient(CloudFilesAsyncClient in) {
|
||||
return in;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@CDNManagement
|
||||
protected URI provideCDNUrl(AuthenticationResponse response) {
|
||||
return response.getServices().get(AuthHeaders.CDN_MANAGEMENT_URL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.net.URI;
|
||||
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.cloudfiles.domain.AccountMetadata;
|
||||
import org.jclouds.openstack.swift.domain.AccountMetadata;
|
||||
import org.jclouds.cloudfiles.reference.CloudFilesHeaders;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
package org.jclouds.cloudfiles.reference;
|
||||
|
||||
import org.jclouds.openstack.swift.reference.SwiftHeaders;
|
||||
|
||||
|
||||
/**
|
||||
* Additional headers specified by Rackspace Cloud Files REST API.
|
||||
|
@ -27,16 +29,11 @@ package org.jclouds.cloudfiles.reference;
|
|||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface CloudFilesHeaders {
|
||||
public interface CloudFilesHeaders extends SwiftHeaders {
|
||||
|
||||
public static final String ACCOUNT_BYTES_USED = "X-Account-Bytes-Used";
|
||||
public static final String ACCOUNT_CONTAINER_COUNT = "X-Account-Container-Count";
|
||||
public static final String CDN_ENABLED = "X-CDN-Enabled";
|
||||
public static final String CDN_REFERRER_ACL = "X-Referrer-ACL ";
|
||||
public static final String CDN_TTL = "X-TTL";
|
||||
public static final String CDN_URI = "X-CDN-URI";
|
||||
public static final String CDN_USER_AGENT_ACL = "X-User-Agent-ACL";
|
||||
public static final String CONTAINER_BYTES_USED = "X-Container-Bytes-Used";
|
||||
public static final String CONTAINER_OBJECT_COUNT = "X-Container-Object-Count";
|
||||
public static final String USER_METADATA_PREFIX = "X-Object-Meta-";
|
||||
}
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift;
|
||||
|
||||
import java.util.Map;
|
||||
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.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.blobstore.binders.BindMapToHeadersWithPrefix;
|
||||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.blobstore.functions.ReturnFalseOnContainerNotFound;
|
||||
import org.jclouds.blobstore.functions.ReturnFalseOnKeyNotFound;
|
||||
import org.jclouds.blobstore.functions.ReturnNullOnKeyNotFound;
|
||||
import org.jclouds.http.functions.ParseETagHeader;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.swift.binders.BindSwiftObjectMetadataToRequest;
|
||||
import org.jclouds.openstack.swift.domain.AccountMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ContainerMetadata;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
import org.jclouds.openstack.swift.functions.ObjectName;
|
||||
import org.jclouds.openstack.swift.functions.ParseAccountMetadataResponseFromHeaders;
|
||||
import org.jclouds.openstack.swift.functions.ParseObjectFromHeadersAndHttpContent;
|
||||
import org.jclouds.openstack.swift.functions.ParseObjectInfoFromHeaders;
|
||||
import org.jclouds.openstack.swift.functions.ParseObjectInfoListFromJsonResponse;
|
||||
import org.jclouds.openstack.swift.functions.ReturnTrueOn404FalseOn409;
|
||||
import org.jclouds.openstack.swift.options.ListContainerOptions;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.Endpoint;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.ParamParser;
|
||||
import org.jclouds.rest.annotations.QueryParams;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Cloud Files via their REST API.
|
||||
* <p/>
|
||||
* All commands return a ListenableFuture of the result from Cloud Files. Any exceptions incurred
|
||||
* during processing will be wrapped in an {@link ExecutionException} as documented in
|
||||
* {@link ListenableFuture#get()}.
|
||||
*
|
||||
* @see CommonSwiftClient
|
||||
* @see <a href="http://www.rackspacecloud.com/cf-devguide-20090812.pdf" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@SkipEncoding('/')
|
||||
@RequestFilters(AuthenticateRequest.class)
|
||||
@Endpoint(Storage.class)
|
||||
public interface CommonSwiftAsyncClient {
|
||||
|
||||
SwiftObject newSwiftObject();
|
||||
|
||||
/**
|
||||
* @see CommonSwiftClient#getAccountStatistics
|
||||
*/
|
||||
@HEAD
|
||||
@ResponseParser(ParseAccountMetadataResponseFromHeaders.class)
|
||||
@Path("/")
|
||||
ListenableFuture<AccountMetadata> getAccountStatistics();
|
||||
|
||||
/**
|
||||
* @see CommonSwiftClient#listContainers
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@QueryParams(keys = "format", values = "json")
|
||||
@Path("/")
|
||||
ListenableFuture<? extends Set<ContainerMetadata>> listContainers(ListContainerOptions... options);
|
||||
|
||||
/**
|
||||
* @see CommonSwiftClient#setObjectInfo
|
||||
*/
|
||||
@POST
|
||||
@Path("/{container}/{name}")
|
||||
ListenableFuture<Boolean> setObjectInfo(@PathParam("container") String container, @PathParam("name") String name,
|
||||
@BinderParam(BindMapToHeadersWithPrefix.class) Map<String, String> userMetadata);
|
||||
|
||||
/**
|
||||
* @see CommonSwiftClient#createContainer
|
||||
*/
|
||||
@PUT
|
||||
@Path("/{container}")
|
||||
ListenableFuture<Boolean> createContainer(@PathParam("container") String container);
|
||||
|
||||
/**
|
||||
* @see CommonSwiftClient#deleteContainerIfEmpty
|
||||
*/
|
||||
@DELETE
|
||||
@ExceptionParser(ReturnTrueOn404FalseOn409.class)
|
||||
@Path("/{container}")
|
||||
ListenableFuture<Boolean> deleteContainerIfEmpty(@PathParam("container") String container);
|
||||
|
||||
/**
|
||||
* @see CommonSwiftClient#listObjects
|
||||
*/
|
||||
@GET
|
||||
@QueryParams(keys = "format", values = "json")
|
||||
@ResponseParser(ParseObjectInfoListFromJsonResponse.class)
|
||||
@Path("/{container}")
|
||||
ListenableFuture<PageSet<ObjectInfo>> listObjects(@PathParam("container") String container,
|
||||
ListContainerOptions... options);
|
||||
|
||||
/**
|
||||
* @see CommonSwiftClient#containerExists
|
||||
*/
|
||||
@HEAD
|
||||
@Path("/{container}")
|
||||
@ExceptionParser(ReturnFalseOnContainerNotFound.class)
|
||||
ListenableFuture<Boolean> containerExists(@PathParam("container") String container);
|
||||
|
||||
/**
|
||||
* @see CommonSwiftClient#putObject
|
||||
*/
|
||||
@PUT
|
||||
@Path("/{container}/{name}")
|
||||
@ResponseParser(ParseETagHeader.class)
|
||||
ListenableFuture<String> putObject(
|
||||
@PathParam("container") String container,
|
||||
@PathParam("name") @ParamParser(ObjectName.class) @BinderParam(BindSwiftObjectMetadataToRequest.class) SwiftObject object);
|
||||
|
||||
/**
|
||||
* @see CommonSwiftClient#getObject
|
||||
*/
|
||||
@GET
|
||||
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
|
||||
@ExceptionParser(ReturnNullOnKeyNotFound.class)
|
||||
@Path("/{container}/{name}")
|
||||
ListenableFuture<SwiftObject> getObject(@PathParam("container") String container, @PathParam("name") String name,
|
||||
GetOptions... options);
|
||||
|
||||
/**
|
||||
* @see CommonSwiftClient#getObjectInfo
|
||||
*/
|
||||
@HEAD
|
||||
@ResponseParser(ParseObjectInfoFromHeaders.class)
|
||||
@ExceptionParser(ReturnNullOnKeyNotFound.class)
|
||||
@Path("/{container}/{name}")
|
||||
ListenableFuture<MutableObjectInfoWithMetadata> getObjectInfo(@PathParam("container") String container,
|
||||
@PathParam("name") String name);
|
||||
|
||||
/**
|
||||
* @see CommonSwiftClient#objectExists
|
||||
*/
|
||||
@HEAD
|
||||
@ExceptionParser(ReturnFalseOnKeyNotFound.class)
|
||||
@Path("/{container}/{name}")
|
||||
ListenableFuture<Boolean> objectExists(@PathParam("container") String container, @PathParam("name") String name);
|
||||
|
||||
/**
|
||||
* @see CommonSwiftClient#removeObject
|
||||
*/
|
||||
@DELETE
|
||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||
@Path("/{container}/{name}")
|
||||
ListenableFuture<Void> removeObject(@PathParam("container") String container, @PathParam("name") String name);
|
||||
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.openstack.swift.domain.AccountMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ContainerMetadata;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
import org.jclouds.openstack.swift.options.ListContainerOptions;
|
||||
|
||||
/**
|
||||
* Provides access to Cloud Files via their REST API.
|
||||
* <p/>
|
||||
* All commands return a Future of the result from Cloud Files. Any exceptions incurred
|
||||
* during processing will be wrapped in an {@link ExecutionException} as documented in
|
||||
* {@link Future#get()}.
|
||||
*
|
||||
* @see <a href="http://www.rackspacecloud.com/cf-devguide-20090812.pdf" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
|
||||
public interface CommonSwiftClient {
|
||||
|
||||
SwiftObject newSwiftObject();
|
||||
|
||||
/**
|
||||
* HEAD operations against an identity are performed to retrieve the number of Containers and the
|
||||
* total bytes stored in Cloud Files for the identity.
|
||||
* <p/>
|
||||
* Determine the number of Containers within the identity and the total bytes stored. Since the
|
||||
* storage system is designed to store large amounts of data, care should be taken when
|
||||
* representing the total bytes response as an integer; when possible, convert it to a 64-bit
|
||||
* unsigned integer if your platform supports that primitive flavor.
|
||||
*/
|
||||
AccountMetadata getAccountStatistics();
|
||||
|
||||
/**
|
||||
* GET operations against the X-Storage-Url for an identity are performed to retrieve a list of
|
||||
* existing storage
|
||||
* <p/>
|
||||
* Containers ordered by name. The following list describes the optional query parameters that
|
||||
* are supported with this request.
|
||||
* <ul>
|
||||
* <li>limit - For an integer value N, limits the number of results to at most N values.</li>
|
||||
* <li>marker - Given a string value X, return Object names greater in value than the specied
|
||||
* marker.</li>
|
||||
* <li>format - Specify either json or xml to return the respective serialized response.</li>
|
||||
* </ul>
|
||||
* <p/>
|
||||
* At this time, a prex query parameter is not supported at the Account level.
|
||||
*
|
||||
*<h4>Large Container Lists</h4>
|
||||
* The system will return a maximum of 10,000 Container names per request. To retrieve subsequent
|
||||
* container names, another request must be made with a marker parameter. The marker indicates
|
||||
* where the last list left off and the system will return container names greater than this
|
||||
* marker, up to 10,000 again. Note that the marker value should be URL encoded prior to sending
|
||||
* the HTTP request.
|
||||
* <p/>
|
||||
* If 10,000 is larger than desired, a limit parameter may be given.
|
||||
* <p/>
|
||||
* If the number of container names returned equals the limit given (or 10,000 if no limit is
|
||||
* given), it can be assumed there are more container names to be listed. If the container name
|
||||
* list is exactly divisible by the limit, the last request will simply have no content.
|
||||
*/
|
||||
Set<ContainerMetadata> listContainers(ListContainerOptions... options);
|
||||
|
||||
boolean setObjectInfo(String container, String name, Map<String, String> userMetadata);
|
||||
|
||||
boolean createContainer(String container);
|
||||
|
||||
boolean deleteContainerIfEmpty(String container);
|
||||
|
||||
PageSet<ObjectInfo> listObjects(String container, ListContainerOptions... options);
|
||||
|
||||
boolean containerExists(String container);
|
||||
|
||||
@Timeout(duration = 5 * 1024 * 1024 / 128, timeUnit = TimeUnit.SECONDS)
|
||||
String putObject(String container, SwiftObject object);
|
||||
|
||||
@Timeout(duration = 5 * 1024 * 1024 / 512, timeUnit = TimeUnit.SECONDS)
|
||||
SwiftObject getObject(String container, String name, GetOptions... options);
|
||||
|
||||
MutableObjectInfoWithMetadata getObjectInfo(String container, String name);
|
||||
|
||||
void removeObject(String container, String name);
|
||||
|
||||
/**
|
||||
* @throws ContainerNotFoundException
|
||||
* if the container is not present.
|
||||
*/
|
||||
boolean objectExists(String container, String name);
|
||||
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.rackspace;
|
||||
package org.jclouds.openstack.swift;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
@ -36,6 +36,6 @@ import javax.inject.Qualifier;
|
|||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||
@Qualifier
|
||||
public @interface CloudFiles {
|
||||
public @interface Storage {
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.blobstore.BlobStoreContextBuilder;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.openstack.swift.blobstore.config.SwiftBlobStoreContextModule;
|
||||
import org.jclouds.openstack.swift.config.BaseSwiftRestClientModule;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Creates {@link CloudFilesBlobStoreContext} or {@link Injector} instances based on the most
|
||||
* commonly requested arguments.
|
||||
* <p/>
|
||||
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @see CloudFilesBlobStoreContext
|
||||
*/
|
||||
public class SwiftContextBuilder extends BlobStoreContextBuilder<CommonSwiftClient, CommonSwiftAsyncClient> {
|
||||
|
||||
public SwiftContextBuilder(Properties props) {
|
||||
super(CommonSwiftClient.class, CommonSwiftAsyncClient.class, props);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new SwiftBlobStoreContextModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addClientModule(List<Module> modules) {
|
||||
modules.add(new BaseSwiftRestClientModule<CommonSwiftClient, CommonSwiftAsyncClient>(CommonSwiftClient.class,
|
||||
CommonSwiftAsyncClient.class));
|
||||
}
|
||||
}
|
|
@ -17,33 +17,33 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.rackspace;
|
||||
package org.jclouds.openstack.swift;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
||||
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.PropertiesBuilder;
|
||||
|
||||
/**
|
||||
* Builds properties used in Rackspace Connections
|
||||
* Builds properties used in CloudFiles Connections
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RackspacePropertiesBuilder extends PropertiesBuilder {
|
||||
public class SwiftPropertiesBuilder extends PropertiesBuilder {
|
||||
@Override
|
||||
protected Properties defaultProperties() {
|
||||
Properties properties = super.defaultProperties();
|
||||
properties.setProperty(PROPERTY_REGIONS, "US");
|
||||
properties.setProperty(PROPERTY_ENDPOINT, "https://auth.api.rackspacecloud.com");
|
||||
properties.setProperty(PROPERTY_API_VERSION, RackspaceAuthAsyncClient.VERSION);
|
||||
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "X-Object-Meta-");
|
||||
return properties;
|
||||
}
|
||||
|
||||
public RackspacePropertiesBuilder(Properties properties) {
|
||||
public SwiftPropertiesBuilder(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
protected SwiftPropertiesBuilder withMetaPrefix(String prefix) {
|
||||
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, prefix);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.binders;
|
||||
package org.jclouds.openstack.swift.binders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
@ -29,28 +29,28 @@ import javax.ws.rs.core.MediaType;
|
|||
import org.jclouds.blobstore.binders.BindUserMetadataToHeadersWithPrefix;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.utils.ModifyRequest;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ObjectToBlob;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlob;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
import org.jclouds.rest.Binder;
|
||||
|
||||
@Singleton
|
||||
public class BindCFObjectMetadataToRequest implements Binder {
|
||||
public class BindSwiftObjectMetadataToRequest implements Binder {
|
||||
|
||||
private final BindUserMetadataToHeadersWithPrefix mdBinder;
|
||||
private final ObjectToBlob object2Blob;
|
||||
|
||||
@Inject
|
||||
public BindCFObjectMetadataToRequest(ObjectToBlob object2Blob, BindUserMetadataToHeadersWithPrefix mdBinder) {
|
||||
public BindSwiftObjectMetadataToRequest(ObjectToBlob object2Blob, BindUserMetadataToHeadersWithPrefix mdBinder) {
|
||||
this.mdBinder = mdBinder;
|
||||
this.object2Blob = object2Blob;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
|
||||
checkArgument(checkNotNull(input, "input") instanceof CFObject, "this binder is only valid for CFObject!");
|
||||
checkArgument(checkNotNull(input, "input") instanceof SwiftObject, "this binder is only valid for SwiftObject!");
|
||||
checkNotNull(request, "request");
|
||||
|
||||
CFObject object = (CFObject) input;
|
||||
SwiftObject object = (SwiftObject) input;
|
||||
if (object.getPayload().getContentMetadata().getContentType() == null)
|
||||
object.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore;
|
||||
package org.jclouds.openstack.swift.blobstore;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.blobstore.util.BlobStoreUtils.createParentIfNeededAsync;
|
||||
|
@ -46,18 +46,18 @@ import org.jclouds.collect.Memoized;
|
|||
import org.jclouds.concurrent.Futures;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.cloudfiles.CloudFilesAsyncClient;
|
||||
import org.jclouds.cloudfiles.CloudFilesClient;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.BlobStoreListContainerOptionsToListContainerOptions;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ContainerToResourceList;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ContainerToResourceMetadata;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ObjectToBlob;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ObjectToBlobMetadata;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.cloudfiles.domain.ContainerMetadata;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||
import org.jclouds.openstack.swift.CommonSwiftClient;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.BlobStoreListContainerOptionsToListContainerOptions;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ContainerToResourceList;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ContainerToResourceMetadata;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlob;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlobMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ContainerMetadata;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -69,9 +69,9 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore {
|
||||
private final CloudFilesClient sync;
|
||||
private final CloudFilesAsyncClient async;
|
||||
public class SwiftAsyncBlobStore extends BaseAsyncBlobStore {
|
||||
private final CommonSwiftClient sync;
|
||||
private final CommonSwiftAsyncClient async;
|
||||
private final ContainerToResourceMetadata container2ResourceMd;
|
||||
private final BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions;
|
||||
private final ContainerToResourceList container2ResourceList;
|
||||
|
@ -82,9 +82,9 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
private final Provider<FetchBlobMetadata> fetchBlobMetadataProvider;
|
||||
|
||||
@Inject
|
||||
CloudFilesAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils,
|
||||
SwiftAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier<Location> defaultLocation,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, CloudFilesClient sync, CloudFilesAsyncClient async,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, CommonSwiftClient sync, CommonSwiftAsyncClient async,
|
||||
ContainerToResourceMetadata container2ResourceMd,
|
||||
BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions,
|
||||
ContainerToResourceList container2ResourceList, ObjectToBlob object2Blob, BlobToObject blob2Object,
|
||||
|
@ -104,7 +104,7 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesAsyncClient#listContainers}
|
||||
* This implementation invokes {@link CommonSwiftAsyncClient#listContainers}
|
||||
*/
|
||||
@Override
|
||||
public ListenableFuture<PageSet<? extends StorageMetadata>> list() {
|
||||
|
@ -118,7 +118,7 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesAsyncClient#containerExists}
|
||||
* This implementation invokes {@link CommonSwiftAsyncClient#containerExists}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
||||
|
@ -137,14 +137,14 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesAsyncClient#listBucket}
|
||||
* This implementation invokes {@link CommonSwiftAsyncClient#listBucket}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
||||
*/
|
||||
@Override
|
||||
public ListenableFuture<PageSet<? extends StorageMetadata>> list(String container, ListContainerOptions options) {
|
||||
org.jclouds.cloudfiles.options.ListContainerOptions httpOptions = container2ContainerListOptions
|
||||
org.jclouds.openstack.swift.options.ListContainerOptions httpOptions = container2ContainerListOptions
|
||||
.apply(options);
|
||||
ListenableFuture<PageSet<ObjectInfo>> returnVal = async.listObjects(container, httpOptions);
|
||||
ListenableFuture<PageSet<? extends StorageMetadata>> list = Futures.compose(returnVal, container2ResourceList,
|
||||
|
@ -154,7 +154,7 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesAsyncClient#objectExists}
|
||||
* This implementation invokes {@link CommonSwiftAsyncClient#objectExists}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
||||
|
@ -167,7 +167,7 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesAsyncClient#headObject}
|
||||
* This implementation invokes {@link CommonSwiftAsyncClient#headObject}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
||||
|
@ -188,7 +188,7 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesAsyncClient#getObject}
|
||||
* This implementation invokes {@link CommonSwiftAsyncClient#getObject}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
||||
|
@ -198,12 +198,12 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
@Override
|
||||
public ListenableFuture<Blob> getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) {
|
||||
GetOptions httpOptions = blob2ObjectGetOptions.apply(options);
|
||||
ListenableFuture<CFObject> returnVal = async.getObject(container, key, httpOptions);
|
||||
ListenableFuture<SwiftObject> returnVal = async.getObject(container, key, httpOptions);
|
||||
return Futures.compose(returnVal, object2Blob, service);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesAsyncClient#putObject}
|
||||
* This implementation invokes {@link CommonSwiftAsyncClient#putObject}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
||||
|
@ -217,7 +217,7 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesAsyncClient#removeObject}
|
||||
* This implementation invokes {@link CommonSwiftAsyncClient#removeObject}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore;
|
||||
package org.jclouds.openstack.swift.blobstore;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.blobstore.util.BlobStoreUtils.cleanRequest;
|
||||
|
@ -31,9 +31,9 @@ import org.jclouds.blobstore.BlobRequestSigner;
|
|||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.cloudfiles.CloudFilesAsyncClient;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||
|
||||
/**
|
||||
|
@ -41,21 +41,21 @@ import org.jclouds.rest.internal.RestAnnotationProcessor;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CloudFilesBlobRequestSigner implements BlobRequestSigner {
|
||||
private final RestAnnotationProcessor<CloudFilesAsyncClient> processor;
|
||||
public class SwiftBlobRequestSigner implements BlobRequestSigner {
|
||||
private final RestAnnotationProcessor<CommonSwiftAsyncClient> processor;
|
||||
private final BlobToObject blobToObject;
|
||||
private final Method getMethod;
|
||||
private final Method deleteMethod;
|
||||
private final Method createMethod;
|
||||
|
||||
@Inject
|
||||
public CloudFilesBlobRequestSigner(RestAnnotationProcessor<CloudFilesAsyncClient> processor, BlobToObject blobToObject)
|
||||
public SwiftBlobRequestSigner(RestAnnotationProcessor<CommonSwiftAsyncClient> processor, BlobToObject blobToObject)
|
||||
throws SecurityException, NoSuchMethodException {
|
||||
this.processor = checkNotNull(processor, "processor");
|
||||
this.blobToObject = checkNotNull(blobToObject, "blobToObject");
|
||||
this.getMethod = CloudFilesAsyncClient.class.getMethod("getObject", String.class, String.class, GetOptions[].class);
|
||||
this.deleteMethod = CloudFilesAsyncClient.class.getMethod("removeObject", String.class, String.class);
|
||||
this.createMethod = CloudFilesAsyncClient.class.getMethod("putObject", String.class, CFObject.class);
|
||||
this.getMethod = CommonSwiftAsyncClient.class.getMethod("getObject", String.class, String.class, GetOptions[].class);
|
||||
this.deleteMethod = CommonSwiftAsyncClient.class.getMethod("removeObject", String.class, String.class);
|
||||
this.createMethod = CommonSwiftAsyncClient.class.getMethod("putObject", String.class, SwiftObject.class);
|
||||
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore;
|
||||
package org.jclouds.openstack.swift.blobstore;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.blobstore.util.BlobStoreUtils.createParentIfNeededAsync;
|
||||
|
@ -42,14 +42,14 @@ import org.jclouds.blobstore.util.BlobUtils;
|
|||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.cloudfiles.CloudFilesClient;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.BlobStoreListContainerOptionsToListContainerOptions;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ContainerToResourceList;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ContainerToResourceMetadata;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ObjectToBlob;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ObjectToBlobMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ContainerMetadata;
|
||||
import org.jclouds.openstack.swift.CommonSwiftClient;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.BlobStoreListContainerOptionsToListContainerOptions;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ContainerToResourceList;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ContainerToResourceMetadata;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlob;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlobMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ContainerMetadata;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -60,8 +60,8 @@ import com.google.common.collect.Iterables;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CloudFilesBlobStore extends BaseBlobStore {
|
||||
private final CloudFilesClient sync;
|
||||
public class SwiftBlobStore extends BaseBlobStore {
|
||||
private final CommonSwiftClient sync;
|
||||
private final ContainerToResourceMetadata container2ResourceMd;
|
||||
private final BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions;
|
||||
private final ContainerToResourceList container2ResourceList;
|
||||
|
@ -72,8 +72,8 @@ public class CloudFilesBlobStore extends BaseBlobStore {
|
|||
private final Provider<FetchBlobMetadata> fetchBlobMetadataProvider;
|
||||
|
||||
@Inject
|
||||
CloudFilesBlobStore(BlobStoreContext context, BlobUtils blobUtils, Supplier<Location> defaultLocation,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, CloudFilesClient sync,
|
||||
SwiftBlobStore(BlobStoreContext context, BlobUtils blobUtils, Supplier<Location> defaultLocation,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, CommonSwiftClient sync,
|
||||
ContainerToResourceMetadata container2ResourceMd,
|
||||
BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions,
|
||||
ContainerToResourceList container2ResourceList, ObjectToBlob object2Blob, BlobToObject blob2Object,
|
||||
|
@ -92,7 +92,7 @@ public class CloudFilesBlobStore extends BaseBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesClient#listContainers}
|
||||
* This implementation invokes {@link CommonSwiftClient#listContainers}
|
||||
*/
|
||||
@Override
|
||||
public PageSet<? extends StorageMetadata> list() {
|
||||
|
@ -104,7 +104,7 @@ public class CloudFilesBlobStore extends BaseBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesClient#containerExists}
|
||||
* This implementation invokes {@link CommonSwiftClient#containerExists}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
||||
|
@ -115,7 +115,7 @@ public class CloudFilesBlobStore extends BaseBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesClient#putBucketInRegion}
|
||||
* This implementation invokes {@link CommonSwiftClient#putBucketInRegion}
|
||||
*
|
||||
* @param location
|
||||
* currently ignored
|
||||
|
@ -128,21 +128,21 @@ public class CloudFilesBlobStore extends BaseBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesClient#listObjects}
|
||||
* This implementation invokes {@link CommonSwiftClient#listObjects}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
||||
*/
|
||||
@Override
|
||||
public PageSet<? extends StorageMetadata> list(String container, ListContainerOptions options) {
|
||||
org.jclouds.cloudfiles.options.ListContainerOptions httpOptions = container2ContainerListOptions
|
||||
org.jclouds.openstack.swift.options.ListContainerOptions httpOptions = container2ContainerListOptions
|
||||
.apply(options);
|
||||
PageSet<? extends StorageMetadata> list = container2ResourceList.apply(sync.listObjects(container, httpOptions));
|
||||
return options.isDetailed() ? fetchBlobMetadataProvider.get().setContainerName(container).apply(list) : list;
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesClient#blobExists}
|
||||
* This implementation invokes {@link CommonSwiftClient#blobExists}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
||||
|
@ -155,7 +155,7 @@ public class CloudFilesBlobStore extends BaseBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesClient#getObjectInfo}
|
||||
* This implementation invokes {@link CommonSwiftClient#getObjectInfo}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
||||
|
@ -168,7 +168,7 @@ public class CloudFilesBlobStore extends BaseBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesClient#getObject}
|
||||
* This implementation invokes {@link CommonSwiftClient#getObject}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
||||
|
@ -182,7 +182,7 @@ public class CloudFilesBlobStore extends BaseBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesClient#putObject}
|
||||
* This implementation invokes {@link CommonSwiftClient#putObject}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
||||
|
@ -196,7 +196,7 @@ public class CloudFilesBlobStore extends BaseBlobStore {
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation invokes {@link CloudFilesClient#removeObject}
|
||||
* This implementation invokes {@link CommonSwiftClient#removeObject}
|
||||
*
|
||||
* @param container
|
||||
* container name
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore.config;
|
||||
package org.jclouds.openstack.swift.blobstore.config;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -32,14 +32,14 @@ import org.jclouds.blobstore.config.BlobStoreMapModule;
|
|||
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.cloudfiles.CloudFilesAsyncClient;
|
||||
import org.jclouds.cloudfiles.CloudFilesClient;
|
||||
import org.jclouds.cloudfiles.blobstore.CloudFilesAsyncBlobStore;
|
||||
import org.jclouds.cloudfiles.blobstore.CloudFilesBlobRequestSigner;
|
||||
import org.jclouds.cloudfiles.blobstore.CloudFilesBlobStore;
|
||||
import org.jclouds.location.Region;
|
||||
import org.jclouds.location.config.ProvideRegionsViaProperties;
|
||||
import org.jclouds.location.suppliers.SupplyPredefinedRegions;
|
||||
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||
import org.jclouds.openstack.swift.CommonSwiftClient;
|
||||
import org.jclouds.openstack.swift.blobstore.SwiftAsyncBlobStore;
|
||||
import org.jclouds.openstack.swift.blobstore.SwiftBlobRequestSigner;
|
||||
import org.jclouds.openstack.swift.blobstore.SwiftBlobStore;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
@ -50,12 +50,12 @@ import com.google.inject.Scopes;
|
|||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Configures the {@link CloudFilesBlobStoreContext}; requires {@link CloudFilesAsyncBlobStore}
|
||||
* Configures the {@link CloudFilesBlobStoreContext}; requires {@link SwiftAsyncBlobStore}
|
||||
* bound.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CloudFilesBlobStoreContextModule extends AbstractModule {
|
||||
public class SwiftBlobStoreContextModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
@ -63,15 +63,15 @@ public class CloudFilesBlobStoreContextModule extends AbstractModule {
|
|||
bind(new TypeLiteral<Supplier<Set<? extends Location>>>() {
|
||||
}).annotatedWith(Memoized.class).to(new TypeLiteral<SupplyPredefinedRegions>() {
|
||||
});
|
||||
|
||||
bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT);
|
||||
bind(AsyncBlobStore.class).to(CloudFilesAsyncBlobStore.class).in(Scopes.SINGLETON);
|
||||
bind(BlobStore.class).to(CloudFilesBlobStore.class).in(Scopes.SINGLETON);
|
||||
bind(BlobStoreContext.class).to(new TypeLiteral<BlobStoreContextImpl<CloudFilesClient, CloudFilesAsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(BlobRequestSigner.class).to(CloudFilesBlobRequestSigner.class);
|
||||
bind(new TypeLiteral<Set<String>>() {
|
||||
}).annotatedWith(Region.class).toProvider(ProvideRegionsViaProperties.class).in(Scopes.SINGLETON);
|
||||
|
||||
bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT);
|
||||
bind(AsyncBlobStore.class).to(SwiftAsyncBlobStore.class).in(Scopes.SINGLETON);
|
||||
bind(BlobStore.class).to(SwiftBlobStore.class).in(Scopes.SINGLETON);
|
||||
bind(BlobStoreContext.class).to(new TypeLiteral<BlobStoreContextImpl<CommonSwiftClient, CommonSwiftAsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(BlobRequestSigner.class).to(SwiftBlobRequestSigner.class);
|
||||
}
|
||||
|
||||
@Provides
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore.functions;
|
||||
package org.jclouds.openstack.swift.blobstore.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
@ -33,11 +33,11 @@ import com.google.common.base.Function;
|
|||
@Singleton
|
||||
public class BlobStoreListContainerOptionsToListContainerOptions
|
||||
implements
|
||||
Function<ListContainerOptions, org.jclouds.cloudfiles.options.ListContainerOptions> {
|
||||
public org.jclouds.cloudfiles.options.ListContainerOptions apply(
|
||||
Function<ListContainerOptions, org.jclouds.openstack.swift.options.ListContainerOptions> {
|
||||
public org.jclouds.openstack.swift.options.ListContainerOptions apply(
|
||||
ListContainerOptions from) {
|
||||
checkNotNull(from, "set options to instance NONE instead of passing null");
|
||||
org.jclouds.cloudfiles.options.ListContainerOptions options = new org.jclouds.cloudfiles.options.ListContainerOptions();
|
||||
org.jclouds.openstack.swift.options.ListContainerOptions options = new org.jclouds.openstack.swift.options.ListContainerOptions();
|
||||
if ((from.getDir() == null) && (from.isRecursive())) {
|
||||
options.withPrefix("");
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
s * Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore.functions;
|
||||
package org.jclouds.openstack.swift.blobstore.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
@ -25,7 +25,7 @@ import javax.inject.Inject;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
@ -33,20 +33,20 @@ import com.google.common.base.Function;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class BlobToObject implements Function<Blob, CFObject> {
|
||||
public class BlobToObject implements Function<Blob, SwiftObject> {
|
||||
private final ResourceToObjectInfo blob2ObjectMd;
|
||||
private final CFObject.Factory objectProvider;
|
||||
private final SwiftObject.Factory objectProvider;
|
||||
|
||||
@Inject
|
||||
BlobToObject(ResourceToObjectInfo blob2ObjectMd, CFObject.Factory objectProvider) {
|
||||
BlobToObject(ResourceToObjectInfo blob2ObjectMd, SwiftObject.Factory objectProvider) {
|
||||
this.blob2ObjectMd = blob2ObjectMd;
|
||||
this.objectProvider = objectProvider;
|
||||
}
|
||||
|
||||
public CFObject apply(Blob from) {
|
||||
public SwiftObject apply(Blob from) {
|
||||
if (from == null)
|
||||
return null;
|
||||
CFObject object = objectProvider.create(blob2ObjectMd.apply(from.getMetadata()));
|
||||
SwiftObject object = objectProvider.create(blob2ObjectMd.apply(from.getMetadata()));
|
||||
object.setPayload(checkNotNull(from.getPayload(), "payload: " + from));
|
||||
object.setAllHeaders(from.getAllHeaders());
|
||||
return object;
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore.functions;
|
||||
package org.jclouds.openstack.swift.blobstore.functions;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore.functions;
|
||||
package org.jclouds.openstack.swift.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -28,7 +28,7 @@ import org.jclouds.blobstore.domain.StorageMetadata;
|
|||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.blobstore.domain.internal.PageSetImpl;
|
||||
import org.jclouds.blobstore.domain.internal.StorageMetadataImpl;
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore.functions;
|
||||
package org.jclouds.openstack.swift.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -27,7 +27,7 @@ import org.jclouds.blobstore.domain.StorageMetadata;
|
|||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.cloudfiles.domain.ContainerMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ContainerMetadata;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore.functions;
|
||||
package org.jclouds.openstack.swift.blobstore.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
@ -26,7 +26,7 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.Blob.Factory;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
@ -34,7 +34,7 @@ import com.google.common.base.Function;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ObjectToBlob implements Function<CFObject, Blob> {
|
||||
public class ObjectToBlob implements Function<SwiftObject, Blob> {
|
||||
private final Blob.Factory blobFactory;
|
||||
private final ObjectToBlobMetadata object2BlobMd;
|
||||
|
||||
|
@ -44,7 +44,7 @@ public class ObjectToBlob implements Function<CFObject, Blob> {
|
|||
this.object2BlobMd = object2BlobMd;
|
||||
}
|
||||
|
||||
public Blob apply(CFObject from) {
|
||||
public Blob apply(SwiftObject from) {
|
||||
if (from == null)
|
||||
return null;
|
||||
Blob blob = blobFactory.create(object2BlobMd.apply(from.getInfo()));
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore.functions;
|
||||
package org.jclouds.openstack.swift.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -27,8 +27,8 @@ import org.jclouds.blobstore.domain.StorageType;
|
|||
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
|
||||
import org.jclouds.blobstore.strategy.IfDirectoryReturnNameStrategy;
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore.functions;
|
||||
package org.jclouds.openstack.swift.blobstore.functions;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
@ -27,8 +27,8 @@ import org.jclouds.blobstore.domain.BlobMetadata;
|
|||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
import org.jclouds.blobstore.domain.StorageType;
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.cloudfiles.domain.internal.MutableObjectInfoWithMetadataImpl;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.internal.MutableObjectInfoWithMetadataImpl;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift.config;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
|
||||
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
|
||||
import org.jclouds.openstack.reference.AuthHeaders;
|
||||
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||
import org.jclouds.openstack.swift.CommonSwiftClient;
|
||||
import org.jclouds.openstack.swift.Storage;
|
||||
import org.jclouds.openstack.swift.handlers.ParseSwiftErrorFromHttpResponse;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@ConfiguresRestClient
|
||||
@RequiresHttp
|
||||
public class BaseSwiftRestClientModule<S extends CommonSwiftClient, A extends CommonSwiftAsyncClient> extends
|
||||
RestClientModule<S, A> {
|
||||
private final OpenStackAuthenticationModule module;
|
||||
|
||||
public BaseSwiftRestClientModule(Class<S> syncClientType, Class<A> asyncClientType) {
|
||||
this(new OpenStackAuthenticationModule(), syncClientType, asyncClientType);
|
||||
}
|
||||
|
||||
public BaseSwiftRestClientModule(OpenStackAuthenticationModule module, Class<S> syncClientType,
|
||||
Class<A> asyncClientType) {
|
||||
super(syncClientType, asyncClientType);
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(module);
|
||||
install(new SwiftObjectModule());
|
||||
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||
super.configure();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseSwiftErrorFromHttpResponse.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseSwiftErrorFromHttpResponse.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseSwiftErrorFromHttpResponse.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Storage
|
||||
protected URI provideStorageUrl(AuthenticationResponse response) {
|
||||
return response.getServices().get(AuthHeaders.STORAGE_URL);
|
||||
}
|
||||
}
|
|
@ -17,15 +17,15 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.config;
|
||||
package org.jclouds.openstack.swift.config;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.blobstore.config.BlobStoreObjectModule;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.cloudfiles.domain.internal.CFObjectImpl;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
import org.jclouds.openstack.swift.domain.internal.SwiftObjectImpl;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -36,7 +36,7 @@ import com.google.inject.Scopes;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CFObjectModule extends AbstractModule {
|
||||
public class SwiftObjectModule extends AbstractModule {
|
||||
|
||||
/**
|
||||
* explicit factories are created here as it has been shown that Assisted Inject is extremely
|
||||
|
@ -46,20 +46,20 @@ public class CFObjectModule extends AbstractModule {
|
|||
protected void configure() {
|
||||
// for converters to work.
|
||||
install(new BlobStoreObjectModule());
|
||||
bind(CFObject.Factory.class).to(CFObjectFactory.class).in(Scopes.SINGLETON);
|
||||
bind(SwiftObject.Factory.class).to(SwiftObjectFactory.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
|
||||
private static class CFObjectFactory implements CFObject.Factory {
|
||||
private static class SwiftObjectFactory implements SwiftObject.Factory {
|
||||
@Inject
|
||||
Provider<MutableObjectInfoWithMetadata> metadataProvider;
|
||||
|
||||
public CFObject create(MutableObjectInfoWithMetadata metadata) {
|
||||
return new CFObjectImpl(metadata != null ? metadata : metadataProvider.get());
|
||||
public SwiftObject create(MutableObjectInfoWithMetadata metadata) {
|
||||
return new SwiftObjectImpl(metadata != null ? metadata : metadataProvider.get());
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
CFObject provideCFObject(CFObject.Factory factory) {
|
||||
SwiftObject provideSwiftObject(SwiftObject.Factory factory) {
|
||||
return factory.create(null);
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.domain;
|
||||
package org.jclouds.openstack.swift.domain;
|
||||
|
||||
/**
|
||||
*
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.domain;
|
||||
package org.jclouds.openstack.swift.domain;
|
||||
|
||||
|
||||
/**
|
|
@ -17,12 +17,12 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.domain;
|
||||
package org.jclouds.openstack.swift.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.cloudfiles.domain.internal.MutableObjectInfoWithMetadataImpl;
|
||||
import org.jclouds.openstack.swift.domain.internal.MutableObjectInfoWithMetadataImpl;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.domain;
|
||||
package org.jclouds.openstack.swift.domain;
|
||||
|
||||
import java.util.Date;
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.domain;
|
||||
package org.jclouds.openstack.swift.domain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -29,9 +29,9 @@ import com.google.common.collect.Multimap;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface CFObject extends PayloadEnclosing, Comparable<CFObject> {
|
||||
public interface SwiftObject extends PayloadEnclosing, Comparable<SwiftObject> {
|
||||
public interface Factory {
|
||||
CFObject create(@Nullable MutableObjectInfoWithMetadata info);
|
||||
SwiftObject create(@Nullable MutableObjectInfoWithMetadata info);
|
||||
}
|
||||
|
||||
/**
|
|
@ -17,14 +17,14 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.domain.internal;
|
||||
package org.jclouds.openstack.swift.domain.internal;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.io.payloads.BaseMutableContentMetadata;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
|
||||
/**
|
||||
*
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.domain.internal;
|
||||
package org.jclouds.openstack.swift.domain.internal;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
@ -25,8 +25,8 @@ import java.util.Map;
|
|||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
|
@ -17,12 +17,12 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.domain.internal;
|
||||
package org.jclouds.openstack.swift.domain.internal;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
|
||||
public class ObjectInfoImpl implements ObjectInfo {
|
||||
String name;
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.domain.internal;
|
||||
package org.jclouds.openstack.swift.domain.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
@ -26,24 +26,24 @@ import javax.inject.Inject;
|
|||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.internal.PayloadEnclosingImpl;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
* Default Implementation of {@link CFObject}.
|
||||
* Default Implementation of {@link SwiftObject}.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CFObjectImpl extends PayloadEnclosingImpl implements CFObject, Comparable<CFObject> {
|
||||
public class SwiftObjectImpl extends PayloadEnclosingImpl implements SwiftObject, Comparable<SwiftObject> {
|
||||
|
||||
private final DelegatingMutableObjectInfoWithMetadata info;
|
||||
private Multimap<String, String> allHeaders = LinkedHashMultimap.create();
|
||||
|
||||
@Inject
|
||||
public CFObjectImpl(MutableObjectInfoWithMetadata info) {
|
||||
public SwiftObjectImpl(MutableObjectInfoWithMetadata info) {
|
||||
super();
|
||||
this.info = new DelegatingMutableObjectInfoWithMetadata(info);
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ public class CFObjectImpl extends PayloadEnclosingImpl implements CFObject, Comp
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(CFObject o) {
|
||||
public int compareTo(SwiftObject o) {
|
||||
if (getInfo().getName() == null)
|
||||
return -1;
|
||||
return (this == o) ? 0 : getInfo().getName().compareTo(o.getInfo().getName());
|
||||
|
@ -98,7 +98,7 @@ public class CFObjectImpl extends PayloadEnclosingImpl implements CFObject, Comp
|
|||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CFObjectImpl other = (CFObjectImpl) obj;
|
||||
SwiftObjectImpl other = (SwiftObjectImpl) obj;
|
||||
if (info == null) {
|
||||
if (other.info != null)
|
||||
return false;
|
|
@ -17,9 +17,9 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.functions;
|
||||
package org.jclouds.openstack.swift.functions;
|
||||
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
@ -30,7 +30,7 @@ import com.google.common.base.Function;
|
|||
public class ObjectName implements Function<Object, String> {
|
||||
|
||||
public String apply(Object from) {
|
||||
return ((CFObject) from).getInfo().getName();
|
||||
return ((SwiftObject) from).getInfo().getName();
|
||||
}
|
||||
|
||||
}
|
|
@ -17,12 +17,12 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.functions;
|
||||
package org.jclouds.openstack.swift.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.cloudfiles.domain.AccountMetadata;
|
||||
import org.jclouds.openstack.swift.domain.AccountMetadata;
|
||||
import org.jclouds.cloudfiles.reference.CloudFilesHeaders;
|
||||
|
||||
import com.google.common.base.Function;
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.functions;
|
||||
package org.jclouds.openstack.swift.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
@ -25,9 +25,9 @@ import java.net.URI;
|
|||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.cloudfiles.domain.AccountMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
|
||||
import org.jclouds.cloudfiles.reference.CloudFilesHeaders;
|
||||
import org.jclouds.openstack.swift.domain.AccountMetadata;
|
||||
import org.jclouds.rest.InvocationContext;
|
||||
|
||||
import com.google.common.base.Function;
|
|
@ -17,42 +17,42 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.functions;
|
||||
package org.jclouds.openstack.swift.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
import org.jclouds.rest.InvocationContext;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* Parses response headers and creates a new CFObject from them and the HTTP content.
|
||||
* Parses response headers and creates a new SwiftObject from them and the HTTP content.
|
||||
*
|
||||
* @see ParseMetadataFromHeaders
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ParseObjectFromHeadersAndHttpContent implements Function<HttpResponse, CFObject>,
|
||||
public class ParseObjectFromHeadersAndHttpContent implements Function<HttpResponse, SwiftObject>,
|
||||
InvocationContext<ParseObjectFromHeadersAndHttpContent> {
|
||||
|
||||
private final ParseObjectInfoFromHeaders infoParser;
|
||||
private final CFObject.Factory objectProvider;
|
||||
private final SwiftObject.Factory objectProvider;
|
||||
|
||||
@Inject
|
||||
public ParseObjectFromHeadersAndHttpContent(ParseObjectInfoFromHeaders infoParser,
|
||||
CFObject.Factory objectProvider) {
|
||||
SwiftObject.Factory objectProvider) {
|
||||
this.infoParser = infoParser;
|
||||
this.objectProvider = objectProvider;
|
||||
}
|
||||
|
||||
public CFObject apply(HttpResponse from) {
|
||||
public SwiftObject apply(HttpResponse from) {
|
||||
MutableObjectInfoWithMetadata metadata = infoParser.apply(from);
|
||||
if (metadata.getHash() != null)
|
||||
from.getPayload().getContentMetadata().setContentMD5(metadata.getHash());
|
||||
CFObject object = objectProvider.create(metadata);
|
||||
SwiftObject object = objectProvider.create(metadata);
|
||||
object.getAllHeaders().putAll(from.getHeaders());
|
||||
object.setPayload(from.getPayload());
|
||||
return object;
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.functions;
|
||||
package org.jclouds.openstack.swift.functions;
|
||||
|
||||
import static org.jclouds.http.HttpUtils.attemptToParseSizeAndRangeFromHeaders;
|
||||
|
||||
|
@ -28,8 +28,8 @@ import org.jclouds.blobstore.functions.ParseSystemAndUserMetadataFromHeaders;
|
|||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ResourceToObjectInfo;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ResourceToObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.rest.InvocationContext;
|
||||
|
||||
import com.google.common.base.Function;
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.functions;
|
||||
package org.jclouds.openstack.swift.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
@ -34,9 +34,9 @@ import org.jclouds.blobstore.domain.internal.PageSetImpl;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.json.Json;
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.cloudfiles.domain.internal.ObjectInfoImpl;
|
||||
import org.jclouds.cloudfiles.options.ListContainerOptions;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.internal.ObjectInfoImpl;
|
||||
import org.jclouds.openstack.swift.options.ListContainerOptions;
|
||||
import org.jclouds.rest.InvocationContext;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.functions;
|
||||
package org.jclouds.openstack.swift.functions;
|
||||
|
||||
import static com.google.common.base.Predicates.in;
|
||||
import static com.google.common.collect.ImmutableSet.of;
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.handlers;
|
||||
package org.jclouds.openstack.swift.handlers;
|
||||
|
||||
import static org.jclouds.http.HttpUtils.releasePayload;
|
||||
|
||||
|
@ -43,7 +43,7 @@ import org.jclouds.util.Strings2;
|
|||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public class ParseCloudFilesErrorFromHttpResponse implements HttpErrorHandler {
|
||||
public class ParseSwiftErrorFromHttpResponse implements HttpErrorHandler {
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
public static final String PREFIX = "^/v[0-9][^/]*/[a-zA-Z]+_[^/]+/";
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.options;
|
||||
package org.jclouds.openstack.swift.options;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.reference;
|
||||
package org.jclouds.openstack.swift.reference;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@ package org.jclouds.cloudfiles.reference;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface CloudFilesConstants {
|
||||
public interface SwiftConstants {
|
||||
/**
|
||||
* For an integer value N, limits the number of results to at most N values.
|
||||
*/
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift.reference;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public interface SwiftHeaders {
|
||||
|
||||
public static final String ACCOUNT_BYTES_USED = "X-Account-Bytes-Used";
|
||||
public static final String ACCOUNT_CONTAINER_COUNT = "X-Account-Container-Count";
|
||||
public static final String CONTAINER_BYTES_USED = "X-Container-Bytes-Used";
|
||||
public static final String CONTAINER_OBJECT_COUNT = "X-Container-Object-Count";
|
||||
public static final String USER_METADATA_PREFIX = "X-Object-Meta-";
|
||||
}
|
|
@ -19,40 +19,21 @@
|
|||
|
||||
package org.jclouds.cloudfiles;
|
||||
|
||||
import static org.jclouds.cloudfiles.options.ListContainerOptions.Builder.underPath;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.cloudfiles.domain.AccountMetadata;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ContainerMetadata;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.cloudfiles.options.ListCdnContainerOptions;
|
||||
import org.jclouds.cloudfiles.options.ListContainerOptions;
|
||||
import org.jclouds.util.Strings2;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.openstack.swift.SwiftClientLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code JaxrsAnnotationProcessor}
|
||||
|
@ -60,20 +41,13 @@ import com.google.common.collect.Maps;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||
public class CloudFilesClientLiveTest extends SwiftClientLiveTest {
|
||||
|
||||
@Override
|
||||
public CloudFilesClient getApi() {
|
||||
return (CloudFilesClient) context.getProviderSpecificContext().getApi();
|
||||
}
|
||||
|
||||
/**
|
||||
* this method overrides containerName to ensure it isn't found
|
||||
*/
|
||||
@Test(groups = { "integration", "live" })
|
||||
public void deleteContainerIfEmptyNotFound() throws Exception {
|
||||
assert getApi().deleteContainerIfEmpty("dbienf");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCDNOperations() throws Exception {
|
||||
final long minimumTTL = 60 * 60; // The minimum TTL is 1 hour
|
||||
|
@ -174,219 +148,4 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListOwnedContainers() throws Exception {
|
||||
String containerPrefix = getContainerName();
|
||||
try {
|
||||
Set<ContainerMetadata> response = getApi().listContainers();
|
||||
assertNotNull(response);
|
||||
long initialContainerCount = response.size();
|
||||
assertTrue(initialContainerCount >= 0);
|
||||
|
||||
// Create test containers
|
||||
String[] containerNames = new String[] { containerPrefix + ".testListOwnedContainers1",
|
||||
containerPrefix + ".testListOwnedContainers2" };
|
||||
assertTrue(getApi().createContainer(containerNames[0]));
|
||||
assertTrue(getApi().createContainer(containerNames[1]));
|
||||
|
||||
// Test default listing
|
||||
response = getApi().listContainers();
|
||||
// assertEquals(response.size(), initialContainerCount + 2);// if the
|
||||
// containers already
|
||||
// exist, this will fail
|
||||
|
||||
// Test listing with options
|
||||
response = getApi().listContainers(
|
||||
ListContainerOptions.Builder.afterMarker(
|
||||
containerNames[0].substring(0, containerNames[0].length() - 1)).maxResults(1));
|
||||
assertEquals(response.size(), 1);
|
||||
assertEquals(Iterables.get(response, 0).getName(), containerNames[0]);
|
||||
|
||||
response = getApi().listContainers(ListContainerOptions.Builder.afterMarker(containerNames[0]).maxResults(1));
|
||||
assertEquals(response.size(), 1);
|
||||
assertEquals(Iterables.get(response, 0).getName(), containerNames[1]);
|
||||
|
||||
// Cleanup and test containers have been removed
|
||||
assertTrue(getApi().deleteContainerIfEmpty(containerNames[0]));
|
||||
assertTrue(getApi().deleteContainerIfEmpty(containerNames[1]));
|
||||
response = getApi().listContainers();
|
||||
// assertEquals(response.size(), initialContainerCount + 2);// if the
|
||||
// containers already
|
||||
// exist, this will fail
|
||||
} finally {
|
||||
returnContainer(containerPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeadAccountMetadata() throws Exception {
|
||||
String containerPrefix = getContainerName();
|
||||
String containerName = containerPrefix + ".testHeadAccountMetadata";
|
||||
try {
|
||||
AccountMetadata metadata = getApi().getAccountStatistics();
|
||||
assertNotNull(metadata);
|
||||
long initialContainerCount = metadata.getContainerCount();
|
||||
|
||||
assertTrue(getApi().createContainer(containerName));
|
||||
|
||||
metadata = getApi().getAccountStatistics();
|
||||
assertNotNull(metadata);
|
||||
assertTrue(metadata.getContainerCount() >= initialContainerCount);
|
||||
|
||||
assertTrue(getApi().deleteContainerIfEmpty(containerName));
|
||||
} finally {
|
||||
returnContainer(containerPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutContainers() throws Exception {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
String containerName1 = containerName + ".hello";
|
||||
assertTrue(getApi().createContainer(containerName1));
|
||||
// List only the container just created, using a marker with the
|
||||
// container name less 1 char
|
||||
Set<ContainerMetadata> response = getApi().listContainers(
|
||||
ListContainerOptions.Builder.afterMarker(containerName1.substring(0, containerName1.length() - 1))
|
||||
.maxResults(1));
|
||||
assertNotNull(response);
|
||||
assertEquals(response.size(), 1);
|
||||
assertEquals(Iterables.get(response, 0).getName(), containerName + ".hello");
|
||||
|
||||
String containerName2 = containerName + "?should-be-illegal-question-char";
|
||||
assert getApi().createContainer(containerName2);
|
||||
|
||||
assert getApi().createContainer(containerName + "/illegal-slash-char");
|
||||
|
||||
assertTrue(getApi().deleteContainerIfEmpty(containerName1));
|
||||
assertTrue(getApi().deleteContainerIfEmpty(containerName2));
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListContainerPath() throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
|
||||
String data = "foo";
|
||||
|
||||
getApi().putObject(containerName, newCFObject(data, "foo"));
|
||||
getApi().putObject(containerName, newCFObject(data, "path/bar"));
|
||||
|
||||
PageSet<ObjectInfo> container = getApi().listObjects(containerName, underPath(""));
|
||||
assert container.getNextMarker() == null;
|
||||
assertEquals(container.size(), 1);
|
||||
assertEquals(Iterables.get(container, 0).getName(), "foo");
|
||||
container = getApi().listObjects(containerName, underPath("path"));
|
||||
assert container.getNextMarker() == null;
|
||||
assertEquals(container.size(), 1);
|
||||
assertEquals(Iterables.get(container, 0).getName(), "path/bar");
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObjectOperations() throws Exception {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
// Test PUT with string data, ETag hash, and a piece of metadata
|
||||
String data = "Here is my data";
|
||||
String key = "object";
|
||||
CFObject object = newCFObject(data, key);
|
||||
byte[] md5 = object.getPayload().getContentMetadata().getContentMD5();
|
||||
String newEtag = getApi().putObject(containerName, object);
|
||||
assert newEtag != null;
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(object.getPayload().getContentMetadata().getContentMD5()));
|
||||
|
||||
// Test HEAD of missing object
|
||||
assert getApi().getObjectInfo(containerName, "non-existent-object") == null;
|
||||
|
||||
// Test HEAD of object
|
||||
MutableObjectInfoWithMetadata metadata = getApi().getObjectInfo(containerName, object.getInfo().getName());
|
||||
assertEquals(metadata.getName(), object.getInfo().getName());
|
||||
|
||||
assertEquals(metadata.getBytes(), new Long(data.length()));
|
||||
assertEquals(metadata.getContentType(), "text/plain; charset=UTF-8");
|
||||
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(metadata.getHash()));
|
||||
assertEquals(metadata.getHash(), CryptoStreams.hex(newEtag));
|
||||
assertEquals(metadata.getMetadata().entrySet().size(), 1);
|
||||
assertEquals(metadata.getMetadata().get("metadata"), "metadata-value");
|
||||
|
||||
// // Test POST to update object's metadata
|
||||
Map<String, String> userMetadata = Maps.newHashMap();
|
||||
userMetadata.put("New-Metadata-1", "value-1");
|
||||
userMetadata.put("New-Metadata-2", "value-2");
|
||||
assertTrue(getApi().setObjectInfo(containerName, object.getInfo().getName(), userMetadata));
|
||||
|
||||
// Test GET of missing object
|
||||
assert getApi().getObject(containerName, "non-existent-object") == null;
|
||||
// Test GET of object (including updated metadata)
|
||||
CFObject getBlob = getApi().getObject(containerName, object.getInfo().getName());
|
||||
assertEquals(Strings2.toStringAndClose(getBlob.getPayload().getInput()), data);
|
||||
// TODO assertEquals(getBlob.getName(),
|
||||
// object.getMetadata().getName());
|
||||
assertEquals(getBlob.getInfo().getBytes(), new Long(data.length()));
|
||||
assertEquals(getBlob.getInfo().getContentType(), "text/plain; charset=UTF-8");
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getInfo().getHash()));
|
||||
assertEquals(CryptoStreams.hex(newEtag), getBlob.getInfo().getHash());
|
||||
assertEquals(getBlob.getInfo().getMetadata().entrySet().size(), 2);
|
||||
assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-1"), "value-1");
|
||||
assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-2"), "value-2");
|
||||
|
||||
// Test PUT with invalid ETag (as if object's data was corrupted in
|
||||
// transit)
|
||||
String correctEtag = newEtag;
|
||||
String incorrectEtag = "0" + correctEtag.substring(1);
|
||||
object.getInfo().setHash(CryptoStreams.hex(incorrectEtag));
|
||||
try {
|
||||
getApi().putObject(containerName, object);
|
||||
} catch (HttpResponseException e) {
|
||||
assertEquals(e.getResponse().getStatusCode(), 422);
|
||||
}
|
||||
|
||||
// Test PUT chunked/streamed upload with data of "unknown" length
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes("UTF-8"));
|
||||
CFObject blob = getApi().newCFObject();
|
||||
blob.getInfo().setName("chunked-object");
|
||||
blob.setPayload(bais);
|
||||
newEtag = getApi().putObject(containerName, blob);
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getInfo().getHash()));
|
||||
|
||||
// Test GET with options
|
||||
// Non-matching ETag
|
||||
try {
|
||||
getApi()
|
||||
.getObject(containerName, object.getInfo().getName(),
|
||||
GetOptions.Builder.ifETagDoesntMatch(newEtag));
|
||||
} catch (HttpResponseException e) {
|
||||
assertEquals(e.getResponse().getStatusCode(), 304);
|
||||
}
|
||||
|
||||
// Matching ETag
|
||||
getBlob = getApi().getObject(containerName, object.getInfo().getName(),
|
||||
GetOptions.Builder.ifETagMatches(newEtag));
|
||||
assertEquals(getBlob.getInfo().getHash(), CryptoStreams.hex(newEtag));
|
||||
getBlob = getApi().getObject(containerName, object.getInfo().getName(), GetOptions.Builder.startAt(8));
|
||||
assertEquals(Strings2.toStringAndClose(getBlob.getPayload().getInput()), data.substring(8));
|
||||
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
}
|
||||
|
||||
private CFObject newCFObject(String data, String key) throws IOException {
|
||||
CFObject object = getApi().newCFObject();
|
||||
object.getInfo().setName(key);
|
||||
object.setPayload(data);
|
||||
Payloads.calculateMD5(object);
|
||||
object.getInfo().setContentType("text/plain");
|
||||
object.getInfo().getMetadata().put("Metadata", "metadata-value");
|
||||
return object;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,36 +19,15 @@
|
|||
|
||||
package org.jclouds.cloudfiles.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
|
||||
import org.jclouds.openstack.swift.blobstore.integration.SwiftBlobIntegrationLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author James Murty
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class CloudFilesBlobIntegrationLiveTest extends BaseBlobIntegrationTest {
|
||||
public class CloudFilesBlobIntegrationLiveTest extends SwiftBlobIntegrationLiveTest {
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testGetTwoRanges() {
|
||||
// not supported in cloud files
|
||||
}
|
||||
|
||||
// not supported
|
||||
@Override
|
||||
protected void checkContentDisposition(Blob blob, String contentDisposition) {
|
||||
assert blob.getPayload().getContentMetadata().getContentDisposition() == null;
|
||||
assert blob.getMetadata().getContentMetadata().getContentDisposition() == null;
|
||||
}
|
||||
|
||||
// not supported
|
||||
@Override
|
||||
protected void checkContentLanguage(Blob blob, String contentLanguage) {
|
||||
assert blob.getPayload().getContentMetadata().getContentLanguage() == null;
|
||||
assert blob.getMetadata().getContentMetadata().getContentLanguage() == null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,15 +19,14 @@
|
|||
|
||||
package org.jclouds.cloudfiles.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobLiveTest;
|
||||
import org.jclouds.openstack.swift.blobstore.integration.SwiftBlobLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author James Murty
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "live" })
|
||||
public class CloudFilesBlobLiveTest extends BaseBlobLiveTest {
|
||||
public class CloudFilesBlobLiveTest extends SwiftBlobLiveTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
|
||||
package org.jclouds.cloudfiles.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobMapIntegrationTest;
|
||||
import org.jclouds.openstack.swift.blobstore.integration.SwiftBlobMapIntegrationLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class CloudFilesBlobMapIntegrationLiveTest extends BaseBlobMapIntegrationTest {
|
||||
public class CloudFilesBlobMapIntegrationLiveTest extends SwiftBlobMapIntegrationLiveTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
package org.jclouds.cloudfiles.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobSignerLiveTest;
|
||||
import org.jclouds.openstack.swift.blobstore.integration.SwiftBlobSignerLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
|
@ -27,6 +27,6 @@ import org.testng.annotations.Test;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "live" })
|
||||
public class CloudFilesBlobSignerLiveTest extends BaseBlobSignerLiveTest {
|
||||
public class CloudFilesBlobSignerLiveTest extends SwiftBlobSignerLiveTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -19,14 +19,13 @@
|
|||
|
||||
package org.jclouds.cloudfiles.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
|
||||
import org.jclouds.openstack.swift.blobstore.integration.SwiftContainerIntegrationLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author James Murty
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class CloudFilesContainerIntegrationLiveTest extends BaseContainerIntegrationTest {
|
||||
public class CloudFilesContainerIntegrationLiveTest extends SwiftContainerIntegrationLiveTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -19,14 +19,13 @@
|
|||
|
||||
package org.jclouds.cloudfiles.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest;
|
||||
import org.jclouds.openstack.swift.blobstore.integration.SwiftContainerLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author James Murty
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "live" })
|
||||
public class CloudFilesContainerLiveTest extends BaseContainerLiveTest {
|
||||
public class CloudFilesContainerLiveTest extends SwiftContainerLiveTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
|
||||
package org.jclouds.cloudfiles.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseInputStreamMapIntegrationTest;
|
||||
import org.jclouds.openstack.swift.blobstore.integration.SwiftInputStreamMapIntegrationLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class CloudFilesInputStreamMapIntegrationLiveTest extends BaseInputStreamMapIntegrationTest {
|
||||
public class CloudFilesInputStreamMapIntegrationLiveTest extends SwiftInputStreamMapIntegrationLiveTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
|
||||
package org.jclouds.cloudfiles.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseServiceIntegrationTest;
|
||||
import org.jclouds.openstack.swift.blobstore.integration.SwiftServiceIntegrationLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class CloudFilesServiceIntegrationLiveTest extends BaseServiceIntegrationTest {
|
||||
public class CloudFilesServiceIntegrationLiveTest extends SwiftServiceIntegrationLiveTest {
|
||||
|
||||
}
|
||||
|
|
|
@ -19,31 +19,17 @@
|
|||
|
||||
package org.jclouds.cloudfiles.blobstore.integration;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.BlobStoreContextFactory;
|
||||
import org.jclouds.blobstore.integration.TransientBlobStoreTestInitializer;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
import org.jclouds.openstack.swift.blobstore.integration.SwiftTestInitializer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CloudFilesTestInitializer extends TransientBlobStoreTestInitializer {
|
||||
public class CloudFilesTestInitializer extends SwiftTestInitializer {
|
||||
|
||||
public CloudFilesTestInitializer() {
|
||||
provider = "cloudfiles";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiversion,
|
||||
String app, String identity, String credential) throws IOException {
|
||||
return new BlobStoreContextFactory().createContext(provider, ImmutableSet.of(configurationModule,
|
||||
new Log4JLoggingModule()), setupProperties(endpoint, apiversion, identity, credential));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,12 +26,11 @@ import java.net.URI;
|
|||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
|
@ -47,7 +46,7 @@ import com.google.inject.TypeLiteral;
|
|||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ParseContainerCDNMetadataListFromJsonResponseTest {
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new GsonModule());
|
||||
|
||||
@Test
|
||||
public void testApplyInputStream() {
|
||||
|
|
|
@ -0,0 +1,289 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift;
|
||||
|
||||
import static org.jclouds.openstack.swift.options.ListContainerOptions.Builder.underPath;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
||||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.openstack.swift.CommonSwiftClient;
|
||||
import org.jclouds.openstack.swift.domain.AccountMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ContainerMetadata;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
import org.jclouds.openstack.swift.options.ListContainerOptions;
|
||||
import org.jclouds.util.Strings2;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code JaxrsAnnotationProcessor}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class SwiftClientLiveTest extends BaseBlobStoreIntegrationTest {
|
||||
|
||||
public CommonSwiftClient getApi() {
|
||||
return (CommonSwiftClient) context.getProviderSpecificContext().getApi();
|
||||
}
|
||||
|
||||
/**
|
||||
* this method overrides containerName to ensure it isn't found
|
||||
*/
|
||||
@Test(groups = { "integration", "live" })
|
||||
public void deleteContainerIfEmptyNotFound() throws Exception {
|
||||
assert getApi().deleteContainerIfEmpty("dbienf");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListOwnedContainers() throws Exception {
|
||||
String containerPrefix = getContainerName();
|
||||
try {
|
||||
Set<ContainerMetadata> response = getApi().listContainers();
|
||||
assertNotNull(response);
|
||||
long initialContainerCount = response.size();
|
||||
assertTrue(initialContainerCount >= 0);
|
||||
|
||||
// Create test containers
|
||||
String[] containerNames = new String[] { containerPrefix + ".testListOwnedContainers1",
|
||||
containerPrefix + ".testListOwnedContainers2" };
|
||||
assertTrue(getApi().createContainer(containerNames[0]));
|
||||
assertTrue(getApi().createContainer(containerNames[1]));
|
||||
|
||||
// Test default listing
|
||||
response = getApi().listContainers();
|
||||
// assertEquals(response.size(), initialContainerCount + 2);// if the
|
||||
// containers already
|
||||
// exist, this will fail
|
||||
|
||||
// Test listing with options
|
||||
response = getApi().listContainers(
|
||||
ListContainerOptions.Builder.afterMarker(
|
||||
containerNames[0].substring(0, containerNames[0].length() - 1)).maxResults(1));
|
||||
assertEquals(response.size(), 1);
|
||||
assertEquals(Iterables.get(response, 0).getName(), containerNames[0]);
|
||||
|
||||
response = getApi().listContainers(ListContainerOptions.Builder.afterMarker(containerNames[0]).maxResults(1));
|
||||
assertEquals(response.size(), 1);
|
||||
assertEquals(Iterables.get(response, 0).getName(), containerNames[1]);
|
||||
|
||||
// Cleanup and test containers have been removed
|
||||
assertTrue(getApi().deleteContainerIfEmpty(containerNames[0]));
|
||||
assertTrue(getApi().deleteContainerIfEmpty(containerNames[1]));
|
||||
response = getApi().listContainers();
|
||||
// assertEquals(response.size(), initialContainerCount + 2);// if the
|
||||
// containers already
|
||||
// exist, this will fail
|
||||
} finally {
|
||||
returnContainer(containerPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeadAccountMetadata() throws Exception {
|
||||
String containerPrefix = getContainerName();
|
||||
String containerName = containerPrefix + ".testHeadAccountMetadata";
|
||||
try {
|
||||
AccountMetadata metadata = getApi().getAccountStatistics();
|
||||
assertNotNull(metadata);
|
||||
long initialContainerCount = metadata.getContainerCount();
|
||||
|
||||
assertTrue(getApi().createContainer(containerName));
|
||||
|
||||
metadata = getApi().getAccountStatistics();
|
||||
assertNotNull(metadata);
|
||||
assertTrue(metadata.getContainerCount() >= initialContainerCount);
|
||||
|
||||
assertTrue(getApi().deleteContainerIfEmpty(containerName));
|
||||
} finally {
|
||||
returnContainer(containerPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutContainers() throws Exception {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
String containerName1 = containerName + ".hello";
|
||||
assertTrue(getApi().createContainer(containerName1));
|
||||
// List only the container just created, using a marker with the
|
||||
// container name less 1 char
|
||||
Set<ContainerMetadata> response = getApi().listContainers(
|
||||
ListContainerOptions.Builder.afterMarker(containerName1.substring(0, containerName1.length() - 1))
|
||||
.maxResults(1));
|
||||
assertNotNull(response);
|
||||
assertEquals(response.size(), 1);
|
||||
assertEquals(Iterables.get(response, 0).getName(), containerName + ".hello");
|
||||
|
||||
String containerName2 = containerName + "?should-be-illegal-question-char";
|
||||
assert getApi().createContainer(containerName2);
|
||||
|
||||
assert getApi().createContainer(containerName + "/illegal-slash-char");
|
||||
|
||||
assertTrue(getApi().deleteContainerIfEmpty(containerName1));
|
||||
assertTrue(getApi().deleteContainerIfEmpty(containerName2));
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListContainerPath() throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
|
||||
String data = "foo";
|
||||
|
||||
getApi().putObject(containerName, newSwiftObject(data, "foo"));
|
||||
getApi().putObject(containerName, newSwiftObject(data, "path/bar"));
|
||||
|
||||
PageSet<ObjectInfo> container = getApi().listObjects(containerName, underPath(""));
|
||||
assert container.getNextMarker() == null;
|
||||
assertEquals(container.size(), 1);
|
||||
assertEquals(Iterables.get(container, 0).getName(), "foo");
|
||||
container = getApi().listObjects(containerName, underPath("path"));
|
||||
assert container.getNextMarker() == null;
|
||||
assertEquals(container.size(), 1);
|
||||
assertEquals(Iterables.get(container, 0).getName(), "path/bar");
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObjectOperations() throws Exception {
|
||||
String containerName = getContainerName();
|
||||
try {
|
||||
// Test PUT with string data, ETag hash, and a piece of metadata
|
||||
String data = "Here is my data";
|
||||
String key = "object";
|
||||
SwiftObject object = newSwiftObject(data, key);
|
||||
byte[] md5 = object.getPayload().getContentMetadata().getContentMD5();
|
||||
String newEtag = getApi().putObject(containerName, object);
|
||||
assert newEtag != null;
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(object.getPayload().getContentMetadata()
|
||||
.getContentMD5()));
|
||||
|
||||
// Test HEAD of missing object
|
||||
assert getApi().getObjectInfo(containerName, "non-existent-object") == null;
|
||||
|
||||
// Test HEAD of object
|
||||
MutableObjectInfoWithMetadata metadata = getApi().getObjectInfo(containerName, object.getInfo().getName());
|
||||
assertEquals(metadata.getName(), object.getInfo().getName());
|
||||
|
||||
assertEquals(metadata.getBytes(), new Long(data.length()));
|
||||
assertEquals(metadata.getContentType(), "text/plain; charset=UTF-8");
|
||||
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(metadata.getHash()));
|
||||
assertEquals(metadata.getHash(), CryptoStreams.hex(newEtag));
|
||||
assertEquals(metadata.getMetadata().entrySet().size(), 1);
|
||||
assertEquals(metadata.getMetadata().get("metadata"), "metadata-value");
|
||||
|
||||
// // Test POST to update object's metadata
|
||||
Map<String, String> userMetadata = Maps.newHashMap();
|
||||
userMetadata.put("New-Metadata-1", "value-1");
|
||||
userMetadata.put("New-Metadata-2", "value-2");
|
||||
assertTrue(getApi().setObjectInfo(containerName, object.getInfo().getName(), userMetadata));
|
||||
|
||||
// Test GET of missing object
|
||||
assert getApi().getObject(containerName, "non-existent-object") == null;
|
||||
// Test GET of object (including updated metadata)
|
||||
SwiftObject getBlob = getApi().getObject(containerName, object.getInfo().getName());
|
||||
assertEquals(Strings2.toStringAndClose(getBlob.getPayload().getInput()), data);
|
||||
// TODO assertEquals(getBlob.getName(),
|
||||
// object.getMetadata().getName());
|
||||
assertEquals(getBlob.getInfo().getBytes(), new Long(data.length()));
|
||||
assertEquals(getBlob.getInfo().getContentType(), "text/plain; charset=UTF-8");
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getInfo().getHash()));
|
||||
assertEquals(CryptoStreams.hex(newEtag), getBlob.getInfo().getHash());
|
||||
assertEquals(getBlob.getInfo().getMetadata().entrySet().size(), 2);
|
||||
assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-1"), "value-1");
|
||||
assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-2"), "value-2");
|
||||
|
||||
// Test PUT with invalid ETag (as if object's data was corrupted in
|
||||
// transit)
|
||||
String correctEtag = newEtag;
|
||||
String incorrectEtag = "0" + correctEtag.substring(1);
|
||||
object.getInfo().setHash(CryptoStreams.hex(incorrectEtag));
|
||||
try {
|
||||
getApi().putObject(containerName, object);
|
||||
} catch (HttpResponseException e) {
|
||||
assertEquals(e.getResponse().getStatusCode(), 422);
|
||||
}
|
||||
|
||||
// Test PUT chunked/streamed upload with data of "unknown" length
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes("UTF-8"));
|
||||
SwiftObject blob = getApi().newSwiftObject();
|
||||
blob.getInfo().setName("chunked-object");
|
||||
blob.setPayload(bais);
|
||||
newEtag = getApi().putObject(containerName, blob);
|
||||
assertEquals(CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getInfo().getHash()));
|
||||
|
||||
// Test GET with options
|
||||
// Non-matching ETag
|
||||
try {
|
||||
getApi()
|
||||
.getObject(containerName, object.getInfo().getName(),
|
||||
GetOptions.Builder.ifETagDoesntMatch(newEtag));
|
||||
} catch (HttpResponseException e) {
|
||||
assertEquals(e.getResponse().getStatusCode(), 304);
|
||||
}
|
||||
|
||||
// Matching ETag
|
||||
getBlob = getApi().getObject(containerName, object.getInfo().getName(),
|
||||
GetOptions.Builder.ifETagMatches(newEtag));
|
||||
assertEquals(getBlob.getInfo().getHash(), CryptoStreams.hex(newEtag));
|
||||
getBlob = getApi().getObject(containerName, object.getInfo().getName(), GetOptions.Builder.startAt(8));
|
||||
assertEquals(Strings2.toStringAndClose(getBlob.getPayload().getInput()), data.substring(8));
|
||||
|
||||
} finally {
|
||||
returnContainer(containerName);
|
||||
}
|
||||
}
|
||||
|
||||
private SwiftObject newSwiftObject(String data, String key) throws IOException {
|
||||
SwiftObject object = getApi().newSwiftObject();
|
||||
object.getInfo().setName(key);
|
||||
object.setPayload(data);
|
||||
Payloads.calculateMD5(object);
|
||||
object.getInfo().setContentType("text/plain");
|
||||
object.getInfo().getMetadata().put("Metadata", "metadata-value");
|
||||
return object;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.openstack.TestOpenStackAuthenticationModule;
|
||||
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
|
||||
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||
import org.jclouds.openstack.swift.CommonSwiftClient;
|
||||
import org.jclouds.openstack.swift.config.BaseSwiftRestClientModule;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.RestClientTest;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
import org.jclouds.rest.RestContextSpec;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code BindSwiftObjectMetadataToRequest}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
|
||||
@Test(groups = "unit", testName = "SwiftClientTest")
|
||||
public abstract class SwiftClientTest<A extends CommonSwiftAsyncClient> extends RestClientTest<A> {
|
||||
|
||||
@Override
|
||||
protected void checkFilters(HttpRequest request) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module createModule() {
|
||||
return new TestSwiftRestClientModule();
|
||||
}
|
||||
|
||||
@ConfiguresRestClient
|
||||
@RequiresHttp
|
||||
protected static class TestSwiftRestClientModule extends
|
||||
BaseSwiftRestClientModule<CommonSwiftClient, CommonSwiftAsyncClient> {
|
||||
private TestSwiftRestClientModule() {
|
||||
super(new TestOpenStackAuthenticationModule(), CommonSwiftClient.class, CommonSwiftAsyncClient.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URI provideStorageUrl(AuthenticationResponse response) {
|
||||
return URI.create("http://storage");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String provider = "swift";
|
||||
|
||||
@Override
|
||||
public RestContextSpec<CommonSwiftClient, CommonSwiftAsyncClient> createContextSpec() {
|
||||
return new RestContextFactory().createContextSpec(provider, "user", "password", new Properties());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Properties getProperties() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(PROPERTY_REGIONS, "US");
|
||||
properties.setProperty(PROPERTY_ENDPOINT, "https://auth");
|
||||
properties.setProperty(PROPERTY_API_VERSION, "1");
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
|
@ -17,24 +17,21 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.binders;
|
||||
package org.jclouds.openstack.swift.binders;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.cloudfiles.CloudFilesAsyncClient;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.rest.RestClientTest;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
import org.jclouds.rest.RestContextSpec;
|
||||
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||
import org.jclouds.openstack.swift.SwiftClientTest;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -43,32 +40,37 @@ import com.google.common.collect.ImmutableMultimap;
|
|||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code BindCFObjectMetadataToRequest}
|
||||
* Tests behavior of {@code BindSwiftObjectMetadataToRequest}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
|
||||
@Test(groups = "unit", testName = "BindCFObjectMetadataToRequestTest")
|
||||
public class BindCFObjectMetadataToRequestTest extends RestClientTest<CloudFilesAsyncClient> {
|
||||
@Test(groups = "unit", testName = "BindSwiftObjectMetadataToRequestTest")
|
||||
public class BindSwiftObjectMetadataToRequestTest extends SwiftClientTest<CommonSwiftAsyncClient> {
|
||||
@Override
|
||||
protected TypeLiteral<RestAnnotationProcessor<CommonSwiftAsyncClient>> createTypeLiteral() {
|
||||
return new TypeLiteral<RestAnnotationProcessor<CommonSwiftAsyncClient>>() {
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPassWithMinimumDetailsAndPayload5GB() {
|
||||
CFObject object = injector.getInstance(CFObject.Factory.class).create(null);
|
||||
SwiftObject object = injector.getInstance(SwiftObject.Factory.class).create(null);
|
||||
Payload payload = Payloads.newStringPayload("");
|
||||
payload.getContentMetadata().setContentLength(5 * 1024 * 1024 * 1024l);
|
||||
object.setPayload(payload);
|
||||
object.getInfo().setName("foo");
|
||||
|
||||
HttpRequest request = HttpRequest.builder().method("PUT").endpoint(URI.create("http://localhost")).build();
|
||||
BindCFObjectMetadataToRequest binder = injector.getInstance(BindCFObjectMetadataToRequest.class);
|
||||
BindSwiftObjectMetadataToRequest binder = injector.getInstance(BindSwiftObjectMetadataToRequest.class);
|
||||
|
||||
assertEquals(binder.bindToRequest(request, object),
|
||||
HttpRequest.builder().method("PUT").endpoint(URI.create("http://localhost")).build());
|
||||
assertEquals(binder.bindToRequest(request, object), HttpRequest.builder().method("PUT").endpoint(
|
||||
URI.create("http://localhost")).build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtendedPropertiesBind() {
|
||||
CFObject object = injector.getInstance(CFObject.Factory.class).create(null);
|
||||
SwiftObject object = injector.getInstance(SwiftObject.Factory.class).create(null);
|
||||
Payload payload = Payloads.newStringPayload("");
|
||||
payload.getContentMetadata().setContentLength(5 * 1024 * 1024 * 1024l);
|
||||
object.setPayload(payload);
|
||||
|
@ -76,80 +78,62 @@ public class BindCFObjectMetadataToRequestTest extends RestClientTest<CloudFiles
|
|||
object.getInfo().getMetadata().putAll(ImmutableMap.of("foo", "bar"));
|
||||
|
||||
HttpRequest request = HttpRequest.builder().method("PUT").endpoint(URI.create("http://localhost")).build();
|
||||
BindCFObjectMetadataToRequest binder = injector.getInstance(BindCFObjectMetadataToRequest.class);
|
||||
BindSwiftObjectMetadataToRequest binder = injector.getInstance(BindSwiftObjectMetadataToRequest.class);
|
||||
|
||||
assertEquals(
|
||||
binder.bindToRequest(request, object),
|
||||
HttpRequest.builder().method("PUT").endpoint(URI.create("http://localhost"))
|
||||
.headers(ImmutableMultimap.of("X-Object-Meta-foo", "bar")).build());
|
||||
assertEquals(binder.bindToRequest(request, object), HttpRequest.builder().method("PUT").endpoint(
|
||||
URI.create("http://localhost")).headers(ImmutableMultimap.of("X-Object-Meta-foo", "bar")).build());
|
||||
}
|
||||
|
||||
public void testNoContentLengthIsChunked() {
|
||||
CFObject object = injector.getInstance(CFObject.Factory.class).create(null);
|
||||
SwiftObject object = injector.getInstance(SwiftObject.Factory.class).create(null);
|
||||
Payload payload = Payloads.newStringPayload("");
|
||||
payload.getContentMetadata().setContentLength(null);
|
||||
object.setPayload(payload);
|
||||
object.getInfo().setName("foo");
|
||||
|
||||
HttpRequest request = HttpRequest.builder().method("PUT").endpoint(URI.create("http://localhost")).build();
|
||||
BindCFObjectMetadataToRequest binder = injector.getInstance(BindCFObjectMetadataToRequest.class);
|
||||
BindSwiftObjectMetadataToRequest binder = injector.getInstance(BindSwiftObjectMetadataToRequest.class);
|
||||
|
||||
assertEquals(
|
||||
binder.bindToRequest(request, object),
|
||||
HttpRequest.builder().method("PUT").endpoint(URI.create("http://localhost"))
|
||||
.headers(ImmutableMultimap.of("Transfer-Encoding", "chunked")).build());
|
||||
assertEquals(binder.bindToRequest(request, object), HttpRequest.builder().method("PUT").endpoint(
|
||||
URI.create("http://localhost")).headers(ImmutableMultimap.of("Transfer-Encoding", "chunked")).build());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testNoNameIsBad() {
|
||||
CFObject object = injector.getInstance(CFObject.Factory.class).create(null);
|
||||
SwiftObject object = injector.getInstance(SwiftObject.Factory.class).create(null);
|
||||
Payload payload = Payloads.newStringPayload("");
|
||||
payload.getContentMetadata().setContentLength(5368709120000l);
|
||||
object.setPayload(payload);
|
||||
|
||||
HttpRequest request = HttpRequest.builder().method("PUT").endpoint(URI.create("http://localhost")).build();
|
||||
BindCFObjectMetadataToRequest binder = injector.getInstance(BindCFObjectMetadataToRequest.class);
|
||||
BindSwiftObjectMetadataToRequest binder = injector.getInstance(BindSwiftObjectMetadataToRequest.class);
|
||||
binder.bindToRequest(request, object);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testOver5GBIsBad() {
|
||||
CFObject object = injector.getInstance(CFObject.Factory.class).create(null);
|
||||
SwiftObject object = injector.getInstance(SwiftObject.Factory.class).create(null);
|
||||
Payload payload = Payloads.newStringPayload("");
|
||||
payload.getContentMetadata().setContentLength(5 * 1024 * 1024 * 1024l + 1);
|
||||
object.setPayload(payload);
|
||||
object.getInfo().setName("foo");
|
||||
|
||||
HttpRequest request = HttpRequest.builder().method("PUT").endpoint(URI.create("http://localhost")).build();
|
||||
BindCFObjectMetadataToRequest binder = injector.getInstance(BindCFObjectMetadataToRequest.class);
|
||||
BindSwiftObjectMetadataToRequest binder = injector.getInstance(BindSwiftObjectMetadataToRequest.class);
|
||||
binder.bindToRequest(request, object);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testMustBeCFObject() {
|
||||
public void testMustBeSwiftObject() {
|
||||
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||
injector.getInstance(BindCFObjectMetadataToRequest.class).bindToRequest(request, new File("foo"));
|
||||
injector.getInstance(BindSwiftObjectMetadataToRequest.class).bindToRequest(request, new File("foo"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class })
|
||||
public void testNullIsBad() {
|
||||
BindCFObjectMetadataToRequest binder = injector.getInstance(BindCFObjectMetadataToRequest.class);
|
||||
BindSwiftObjectMetadataToRequest binder = injector.getInstance(BindSwiftObjectMetadataToRequest.class);
|
||||
HttpRequest request = HttpRequest.builder().method("GET").endpoint(URI.create("http://momma")).build();
|
||||
binder.bindToRequest(request, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkFilters(HttpRequest request) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TypeLiteral<RestAnnotationProcessor<CloudFilesAsyncClient>> createTypeLiteral() {
|
||||
return new TypeLiteral<RestAnnotationProcessor<CloudFilesAsyncClient>>() {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestContextSpec<?, ?> createContextSpec() {
|
||||
return new RestContextFactory().createContextSpec("cloudfiles", "identity", "credential", new Properties());
|
||||
}
|
||||
}
|
|
@ -17,38 +17,37 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore;
|
||||
package org.jclouds.openstack.swift.blobstore;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.blobstore.BlobRequestSigner;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.Blob.Factory;
|
||||
import org.jclouds.cloudfiles.CloudFilesAsyncClient;
|
||||
import org.jclouds.cloudfiles.config.CloudFilesRestClientModule;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rackspace.TestRackspaceAuthenticationRestClientModule;
|
||||
import org.jclouds.rest.RestClientTest;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
import org.jclouds.rest.RestContextSpec;
|
||||
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||
import org.jclouds.openstack.swift.SwiftClientTest;
|
||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code CloudFilesBlobRequestSigner}
|
||||
* Tests behavior of {@code CommonSwiftBlobRequestSigner}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
|
||||
@Test(groups = "unit", testName = "CloudFilesBlobRequestSignerTest")
|
||||
public class CloudFilesBlobRequestSignerTest extends RestClientTest<CloudFilesAsyncClient> {
|
||||
@Test(groups = "unit", testName = "SwiftBlobRequestSignerTest")
|
||||
public class SwiftBlobRequestSignerTest extends SwiftClientTest<CommonSwiftAsyncClient> {
|
||||
@Override
|
||||
protected TypeLiteral<RestAnnotationProcessor<CommonSwiftAsyncClient>> createTypeLiteral() {
|
||||
return new TypeLiteral<RestAnnotationProcessor<CommonSwiftAsyncClient>>() {
|
||||
};
|
||||
}
|
||||
|
||||
private BlobRequestSigner signer;
|
||||
private Factory blobFactory;
|
||||
|
@ -57,7 +56,7 @@ public class CloudFilesBlobRequestSignerTest extends RestClientTest<CloudFilesAs
|
|||
NoSuchMethodException, IOException {
|
||||
HttpRequest request = signer.signGetBlob("container", "name");
|
||||
|
||||
assertRequestLineEquals(request, "GET http://storageUrl/container/name HTTP/1.1");
|
||||
assertRequestLineEquals(request, "GET http://storage/container/name HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(request, "X-Auth-Token: testtoken\n");
|
||||
assertPayloadEquals(request, null, null, false);
|
||||
|
||||
|
@ -68,7 +67,7 @@ public class CloudFilesBlobRequestSignerTest extends RestClientTest<CloudFilesAs
|
|||
NoSuchMethodException, IOException {
|
||||
HttpRequest request = signer.signRemoveBlob("container", "name");
|
||||
|
||||
assertRequestLineEquals(request, "DELETE http://storageUrl/container/name HTTP/1.1");
|
||||
assertRequestLineEquals(request, "DELETE http://storage/container/name HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(request, "X-Auth-Token: testtoken\n");
|
||||
assertPayloadEquals(request, null, null, false);
|
||||
|
||||
|
@ -86,7 +85,7 @@ public class CloudFilesBlobRequestSignerTest extends RestClientTest<CloudFilesAs
|
|||
|
||||
HttpRequest request = signer.signPutBlob("container", blob);
|
||||
|
||||
assertRequestLineEquals(request, "PUT http://storageUrl/container/name HTTP/1.1");
|
||||
assertRequestLineEquals(request, "PUT http://storage/container/name HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(request, "X-Auth-Token: testtoken\n");
|
||||
assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 2l, new byte[] { 0, 2, 4, 8 });
|
||||
|
||||
|
@ -100,24 +99,4 @@ public class CloudFilesBlobRequestSignerTest extends RestClientTest<CloudFilesAs
|
|||
this.signer = injector.getInstance(BlobRequestSigner.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkFilters(HttpRequest request) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TypeLiteral<RestAnnotationProcessor<CloudFilesAsyncClient>> createTypeLiteral() {
|
||||
return new TypeLiteral<RestAnnotationProcessor<CloudFilesAsyncClient>>() {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module createModule() {
|
||||
return new CloudFilesRestClientModule(new TestRackspaceAuthenticationRestClientModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestContextSpec<?, ?> createContextSpec() {
|
||||
return new RestContextFactory().createContextSpec("cloudfiles", "identity", "credential", new Properties());
|
||||
}
|
||||
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore.functions;
|
||||
package org.jclouds.openstack.swift.blobstore.functions;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -31,9 +31,9 @@ import com.google.common.base.Function;
|
|||
@Singleton
|
||||
public class ListContainerOptionsToBlobStoreListContainerOptions
|
||||
implements
|
||||
Function<org.jclouds.cloudfiles.options.ListContainerOptions[], ListContainerOptions> {
|
||||
Function<org.jclouds.openstack.swift.options.ListContainerOptions[], ListContainerOptions> {
|
||||
public ListContainerOptions apply(
|
||||
org.jclouds.cloudfiles.options.ListContainerOptions[] optionsList) {
|
||||
org.jclouds.openstack.swift.options.ListContainerOptions[] optionsList) {
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
if (optionsList.length != 0) {
|
||||
if (optionsList[0].getPath() != null && !optionsList[0].getPath().equals("")) {
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.blobstore.functions;
|
||||
package org.jclouds.openstack.swift.blobstore.functions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -25,7 +25,8 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
import org.jclouds.blobstore.domain.internal.PageSetImpl;
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ResourceToObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author James Murty
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class SwiftBlobIntegrationLiveTest extends BaseBlobIntegrationTest {
|
||||
|
||||
@Override
|
||||
@Test(enabled = false)
|
||||
public void testGetTwoRanges() {
|
||||
// not supported in cloud files
|
||||
}
|
||||
|
||||
// not supported
|
||||
@Override
|
||||
protected void checkContentDisposition(Blob blob, String contentDisposition) {
|
||||
assert blob.getPayload().getContentMetadata().getContentDisposition() == null;
|
||||
assert blob.getMetadata().getContentMetadata().getContentDisposition() == null;
|
||||
}
|
||||
|
||||
// not supported
|
||||
@Override
|
||||
protected void checkContentLanguage(Blob blob, String contentLanguage) {
|
||||
assert blob.getPayload().getContentMetadata().getContentLanguage() == null;
|
||||
assert blob.getMetadata().getContentMetadata().getContentLanguage() == null;
|
||||
}
|
||||
|
||||
}
|
|
@ -17,22 +17,17 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.rackspace.config;
|
||||
package org.jclouds.openstack.swift.blobstore.integration;
|
||||
|
||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author James Murty
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RackspaceParserModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||
}
|
||||
@Test(groups = { "live" })
|
||||
public class SwiftBlobLiveTest extends BaseBlobLiveTest {
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobMapIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class SwiftBlobMapIntegrationLiveTest extends BaseBlobMapIntegrationTest {
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobSignerLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "live" })
|
||||
public class SwiftBlobSignerLiveTest extends BaseBlobSignerLiveTest {
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author James Murty
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class SwiftContainerIntegrationLiveTest extends BaseContainerIntegrationTest {
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author James Murty
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "live" })
|
||||
public class SwiftContainerLiveTest extends BaseContainerLiveTest {
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseInputStreamMapIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class SwiftInputStreamMapIntegrationLiveTest extends BaseInputStreamMapIntegrationTest {
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift.blobstore.integration;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseServiceIntegrationTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class SwiftServiceIntegrationLiveTest extends BaseServiceIntegrationTest {
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift.blobstore.integration;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.BlobStoreContextFactory;
|
||||
import org.jclouds.blobstore.integration.TransientBlobStoreTestInitializer;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class SwiftTestInitializer extends TransientBlobStoreTestInitializer {
|
||||
|
||||
public SwiftTestInitializer() {
|
||||
provider = "swift";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiversion,
|
||||
String app, String identity, String credential) throws IOException {
|
||||
return new BlobStoreContextFactory().createContext(provider, ImmutableSet.of(configurationModule,
|
||||
new Log4JLoggingModule()), setupProperties(endpoint, apiversion, identity, credential));
|
||||
}
|
||||
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.domain.internal;
|
||||
package org.jclouds.openstack.swift.domain.internal;
|
||||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
|
@ -30,15 +30,17 @@ import java.util.Set;
|
|||
import org.jclouds.crypto.CryptoStreams;
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.cloudfiles.functions.ParseObjectInfoListFromJsonResponse;
|
||||
import org.jclouds.cloudfiles.options.ListContainerOptions;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.functions.ParseObjectInfoListFromJsonResponse;
|
||||
import org.jclouds.openstack.swift.options.ListContainerOptions;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
|
@ -50,7 +52,14 @@ import com.google.inject.Injector;
|
|||
@Test(groups = "unit")
|
||||
public class ParseObjectInfoListFromJsonResponseTest {
|
||||
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||
}
|
||||
|
||||
}, new GsonModule());
|
||||
|
||||
public void testApplyInputStream() {
|
||||
InputStream is = getClass().getResourceAsStream("/test_list_container.json");
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.functions;
|
||||
package org.jclouds.openstack.swift.functions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
|
@ -27,12 +27,12 @@ import javax.ws.rs.core.UriBuilder;
|
|||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.rackspace.RackspaceAuthAsyncClient.AuthenticationResponse;
|
||||
import org.jclouds.rackspace.functions.ParseAuthenticationResponseFromHeaders;
|
||||
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
|
||||
import org.jclouds.openstack.functions.ParseAuthenticationResponseFromHeaders;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
|
@ -61,16 +61,12 @@ public class ParseAuthenticationResponseFromHeadersTest {
|
|||
|
||||
public void testReplaceLocalhost() {
|
||||
ParseAuthenticationResponseFromHeaders parser = i.getInstance(ParseAuthenticationResponseFromHeaders.class);
|
||||
HttpRequest request = new HttpRequest("GET", URI.create("http://realhost:11000/v1.0"));
|
||||
parser.setContext(request);
|
||||
|
||||
HttpResponse response = new HttpResponse(204, "No Content", null, ImmutableMultimap.<String, String> of(
|
||||
"X-Auth-Token", "token", "X-Storage-Token", "token", "X-Storage-Url", "http://127.0.0.1:8080/v1/token"));
|
||||
|
||||
AuthenticationResponse md = parser.apply(response);
|
||||
assertEquals(
|
||||
md,
|
||||
new ParseAuthenticationResponseFromHeaders.AuthenticationResponseImpl("token", null, null, URI
|
||||
.create("http://realhost:8080/v1/token")));
|
||||
assertEquals(md, new AuthenticationResponse("token", ImmutableMap.<String, URI> of("X-Storage-Url", URI
|
||||
.create("http://127.0.0.1:8080/v1/token"))));
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.functions;
|
||||
package org.jclouds.openstack.swift.functions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
|
@ -28,8 +28,7 @@ import org.jclouds.http.HttpResponse;
|
|||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudfiles.domain.ContainerMetadata;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.jclouds.openstack.swift.domain.ContainerMetadata;
|
||||
import org.jclouds.util.Strings2;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -46,7 +45,7 @@ import com.google.inject.TypeLiteral;
|
|||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ParseContainerListFromJsonResponseTest {
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new GsonModule());
|
||||
|
||||
@Test
|
||||
public void testApplyInputStream() {
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.functions;
|
||||
package org.jclouds.openstack.swift.functions;
|
||||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
|
@ -30,7 +30,8 @@ import org.jclouds.Constants;
|
|||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.functions.ParseObjectInfoFromHeaders;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.testng.annotations.Test;
|
||||
|
|
@ -1,4 +1,23 @@
|
|||
package org.jclouds.cloudfiles.handlers;
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack.swift.handlers;
|
||||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.reportMatcher;
|
||||
|
@ -15,6 +34,7 @@ import org.jclouds.http.HttpCommand;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.openstack.swift.handlers.ParseSwiftErrorFromHttpResponse;
|
||||
import org.jclouds.util.Strings2;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -23,7 +43,7 @@ import org.testng.annotations.Test;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = { "unit" })
|
||||
public class ParseCloudFilesErrorFromHttpResponseTest {
|
||||
public class ParseSwiftErrorFromHttpResponseTest {
|
||||
|
||||
@Test
|
||||
public void test404SetsKeyNotFoundExceptionMosso() {
|
||||
|
@ -61,7 +81,7 @@ public class ParseCloudFilesErrorFromHttpResponseTest {
|
|||
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
|
||||
String content, Class<? extends Exception> expected) {
|
||||
|
||||
ParseCloudFilesErrorFromHttpResponse function = new ParseCloudFilesErrorFromHttpResponse();
|
||||
ParseSwiftErrorFromHttpResponse function = new ParseSwiftErrorFromHttpResponse();
|
||||
|
||||
HttpCommand command = createMock(HttpCommand.class);
|
||||
HttpRequest request = new HttpRequest(method, uri);
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.internal;
|
||||
package org.jclouds.openstack.swift.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||
|
@ -39,21 +39,21 @@ import org.jclouds.blobstore.domain.BlobMetadata;
|
|||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions;
|
||||
import org.jclouds.blobstore.options.ListContainerOptions;
|
||||
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
|
||||
import org.jclouds.cloudfiles.options.ListCdnContainerOptions;
|
||||
import org.jclouds.concurrent.Futures;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.cloudfiles.CloudFilesAsyncClient;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ListContainerOptionsToBlobStoreListContainerOptions;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ObjectToBlob;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ResourceToObjectInfo;
|
||||
import org.jclouds.cloudfiles.blobstore.functions.ResourceToObjectList;
|
||||
import org.jclouds.cloudfiles.domain.AccountMetadata;
|
||||
import org.jclouds.cloudfiles.domain.CFObject;
|
||||
import org.jclouds.cloudfiles.domain.ContainerCDNMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ContainerMetadata;
|
||||
import org.jclouds.cloudfiles.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.cloudfiles.domain.ObjectInfo;
|
||||
import org.jclouds.cloudfiles.options.ListCdnContainerOptions;
|
||||
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ListContainerOptionsToBlobStoreListContainerOptions;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ObjectToBlob;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ResourceToObjectInfo;
|
||||
import org.jclouds.openstack.swift.blobstore.functions.ResourceToObjectList;
|
||||
import org.jclouds.openstack.swift.domain.AccountMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ContainerMetadata;
|
||||
import org.jclouds.openstack.swift.domain.MutableObjectInfoWithMetadata;
|
||||
import org.jclouds.openstack.swift.domain.ObjectInfo;
|
||||
import org.jclouds.openstack.swift.domain.SwiftObject;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
@ -61,15 +61,15 @@ import com.google.common.collect.Sets;
|
|||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* Implementation of {@link CloudFilesAsyncClient} which keeps all data in a local Map object.
|
||||
* Implementation of {@link SwiftAsyncClient} which keeps all data in a local Map object.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class StubCloudFilesAsyncClient implements CloudFilesAsyncClient {
|
||||
public class StubSwiftAsyncClient implements CommonSwiftAsyncClient {
|
||||
private final HttpGetOptionsListToGetOptions httpGetOptionsConverter;
|
||||
private final TransientAsyncBlobStore blobStore;
|
||||
private final CFObject.Factory objectProvider;
|
||||
private final SwiftObject.Factory objectProvider;
|
||||
private final ObjectToBlob object2Blob;
|
||||
private final BlobToObject blob2Object;
|
||||
private final ResourceToObjectInfo blob2ObjectInfo;
|
||||
|
@ -79,9 +79,9 @@ public class StubCloudFilesAsyncClient implements CloudFilesAsyncClient {
|
|||
private final ExecutorService service;
|
||||
|
||||
@Inject
|
||||
private StubCloudFilesAsyncClient(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
||||
private StubSwiftAsyncClient(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
||||
TransientAsyncBlobStore blobStore, ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs,
|
||||
CFObject.Factory objectProvider, HttpGetOptionsListToGetOptions httpGetOptionsConverter,
|
||||
SwiftObject.Factory objectProvider, HttpGetOptionsListToGetOptions httpGetOptionsConverter,
|
||||
ObjectToBlob object2Blob, BlobToObject blob2Object, ResourceToObjectInfo blob2ObjectInfo,
|
||||
ListContainerOptionsToBlobStoreListContainerOptions container2ContainerListOptions,
|
||||
ResourceToObjectList resource2ContainerList) {
|
||||
|
@ -130,7 +130,7 @@ public class StubCloudFilesAsyncClient implements CloudFilesAsyncClient {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public ListenableFuture<CFObject> getObject(String container, String key, GetOptions... options) {
|
||||
public ListenableFuture<SwiftObject> getObject(String container, String key, GetOptions... options) {
|
||||
org.jclouds.blobstore.options.GetOptions getOptions = httpGetOptionsConverter.apply(options);
|
||||
return Futures.compose(blobStore.getBlob(container, key, getOptions), blob2Object, service);
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ public class StubCloudFilesAsyncClient implements CloudFilesAsyncClient {
|
|||
}
|
||||
|
||||
public ListenableFuture<? extends Set<ContainerMetadata>> listContainers(
|
||||
org.jclouds.cloudfiles.options.ListContainerOptions... options) {
|
||||
org.jclouds.openstack.swift.options.ListContainerOptions... options) {
|
||||
return immediateFuture(Sets.newHashSet(Iterables.transform(blobStore.getContainerToBlobs().keySet(),
|
||||
new Function<String, ContainerMetadata>() {
|
||||
public ContainerMetadata apply(String name) {
|
||||
|
@ -163,12 +163,12 @@ public class StubCloudFilesAsyncClient implements CloudFilesAsyncClient {
|
|||
}
|
||||
|
||||
public ListenableFuture<PageSet<ObjectInfo>> listObjects(String container,
|
||||
org.jclouds.cloudfiles.options.ListContainerOptions... optionsList) {
|
||||
org.jclouds.openstack.swift.options.ListContainerOptions... optionsList) {
|
||||
ListContainerOptions options = container2ContainerListOptions.apply(optionsList);
|
||||
return Futures.compose(blobStore.list(container, options), resource2ObjectList, service);
|
||||
}
|
||||
|
||||
public ListenableFuture<String> putObject(String container, CFObject object) {
|
||||
public ListenableFuture<String> putObject(String container, SwiftObject object) {
|
||||
return blobStore.putBlob(container, object2Blob.apply(object));
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ public class StubCloudFilesAsyncClient implements CloudFilesAsyncClient {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public CFObject newCFObject() {
|
||||
public SwiftObject newSwiftObject() {
|
||||
return objectProvider.create(null);
|
||||
}
|
||||
|
|
@ -17,19 +17,19 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.cloudfiles.options;
|
||||
package org.jclouds.openstack.swift.options;
|
||||
|
||||
import static org.jclouds.cloudfiles.options.ListContainerOptions.Builder.afterMarker;
|
||||
import static org.jclouds.cloudfiles.options.ListContainerOptions.Builder.underPath;
|
||||
import static org.jclouds.cloudfiles.options.ListContainerOptions.Builder.maxResults;
|
||||
import static org.jclouds.cloudfiles.options.ListContainerOptions.Builder.withPrefix;
|
||||
import static org.jclouds.openstack.swift.options.ListContainerOptions.Builder.afterMarker;
|
||||
import static org.jclouds.openstack.swift.options.ListContainerOptions.Builder.maxResults;
|
||||
import static org.jclouds.openstack.swift.options.ListContainerOptions.Builder.underPath;
|
||||
import static org.jclouds.openstack.swift.options.ListContainerOptions.Builder.withPrefix;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.jclouds.cloudfiles.reference.CloudFilesConstants;
|
||||
import org.jclouds.http.options.HttpRequestOptions;
|
||||
import org.jclouds.openstack.swift.reference.SwiftConstants;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
|
@ -51,8 +51,7 @@ public class ListContainerOptionsTest {
|
|||
public void testPrefix() throws UnsupportedEncodingException {
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
options.withPrefix("test");
|
||||
assertEquals(options.buildQueryParameters().get(CloudFilesConstants.PREFIX), Collections
|
||||
.singletonList("test"));
|
||||
assertEquals(options.buildQueryParameters().get(SwiftConstants.PREFIX), Collections.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -94,14 +93,13 @@ public class ListContainerOptionsTest {
|
|||
@Test
|
||||
public void testNullPrefix() {
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
assertEquals(options.buildQueryParameters().get(CloudFilesConstants.PREFIX), Collections.EMPTY_LIST);
|
||||
assertEquals(options.buildQueryParameters().get(SwiftConstants.PREFIX), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrefixStatic() throws UnsupportedEncodingException {
|
||||
ListContainerOptions options = withPrefix("test");
|
||||
assertEquals(options.buildQueryParameters().get(CloudFilesConstants.PREFIX), Collections
|
||||
.singletonList("test"));
|
||||
assertEquals(options.buildQueryParameters().get(SwiftConstants.PREFIX), Collections.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
|
@ -113,21 +111,19 @@ public class ListContainerOptionsTest {
|
|||
public void testMarker() throws UnsupportedEncodingException {
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
options.afterMarker("test");
|
||||
assertEquals(options.buildQueryParameters().get(CloudFilesConstants.MARKER), Collections
|
||||
.singletonList("test"));
|
||||
assertEquals(options.buildQueryParameters().get(SwiftConstants.MARKER), Collections.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullMarker() {
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
assertEquals(options.buildQueryParameters().get(CloudFilesConstants.MARKER), Collections.EMPTY_LIST);
|
||||
assertEquals(options.buildQueryParameters().get(SwiftConstants.MARKER), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMarkerStatic() throws UnsupportedEncodingException {
|
||||
ListContainerOptions options = afterMarker("test");
|
||||
assertEquals(options.buildQueryParameters().get(CloudFilesConstants.MARKER), Collections
|
||||
.singletonList("test"));
|
||||
assertEquals(options.buildQueryParameters().get(SwiftConstants.MARKER), Collections.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
|
@ -139,21 +135,19 @@ public class ListContainerOptionsTest {
|
|||
public void testMaxKeys() {
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
options.maxResults(1000);
|
||||
assertEquals(options.buildQueryParameters().get(CloudFilesConstants.LIMIT), Collections
|
||||
.singletonList("1000"));
|
||||
assertEquals(options.buildQueryParameters().get(SwiftConstants.LIMIT), Collections.singletonList("1000"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullMaxKeys() {
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
assertEquals(options.buildQueryParameters().get(CloudFilesConstants.LIMIT), Collections.EMPTY_LIST);
|
||||
assertEquals(options.buildQueryParameters().get(SwiftConstants.LIMIT), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxKeysStatic() {
|
||||
ListContainerOptions options = maxResults(1000);
|
||||
assertEquals(options.buildQueryParameters().get(CloudFilesConstants.LIMIT), Collections
|
||||
.singletonList("1000"));
|
||||
assertEquals(options.buildQueryParameters().get(SwiftConstants.LIMIT), Collections.singletonList("1000"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
|
@ -165,22 +159,19 @@ public class ListContainerOptionsTest {
|
|||
public void testPath() throws UnsupportedEncodingException {
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
options.underPath("test");
|
||||
assertEquals(options.buildQueryParameters().get(CloudFilesConstants.PATH), Collections
|
||||
.singletonList("test"));
|
||||
assertEquals(options.buildQueryParameters().get(SwiftConstants.PATH), Collections.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullPath() {
|
||||
ListContainerOptions options = new ListContainerOptions();
|
||||
assertEquals(options.buildQueryParameters().get(CloudFilesConstants.PATH),
|
||||
Collections.EMPTY_LIST);
|
||||
assertEquals(options.buildQueryParameters().get(SwiftConstants.PATH), Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPathStatic() throws UnsupportedEncodingException {
|
||||
ListContainerOptions options = underPath("test");
|
||||
assertEquals(options.buildQueryParameters().get(CloudFilesConstants.PATH), Collections
|
||||
.singletonList("test"));
|
||||
assertEquals(options.buildQueryParameters().get(SwiftConstants.PATH), Collections.singletonList("test"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
|
@ -33,7 +33,6 @@ import javax.ws.rs.Produces;
|
|||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||
import org.jclouds.rackspace.CloudServers;
|
||||
import org.jclouds.cloudservers.binders.BindAdminPassToJsonPayload;
|
||||
import org.jclouds.cloudservers.binders.BindBackupScheduleToJsonPayload;
|
||||
import org.jclouds.cloudservers.binders.BindConfirmResizeToJsonPayload;
|
||||
|
@ -54,8 +53,8 @@ import org.jclouds.cloudservers.options.CreateServerOptions;
|
|||
import org.jclouds.cloudservers.options.CreateSharedIpGroupOptions;
|
||||
import org.jclouds.cloudservers.options.ListOptions;
|
||||
import org.jclouds.cloudservers.options.RebuildServerOptions;
|
||||
import org.jclouds.rackspace.filters.AddTimestampQuery;
|
||||
import org.jclouds.rackspace.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.filters.AddTimestampQuery;
|
||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.Endpoint;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
|
@ -85,7 +84,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
*/
|
||||
@SkipEncoding( { '/', '=' })
|
||||
@RequestFilters( { AuthenticateRequest.class, AddTimestampQuery.class })
|
||||
@Endpoint(CloudServers.class)
|
||||
@Endpoint(ServerManagement.class)
|
||||
public interface CloudServersAsyncClient {
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.rackspace;
|
||||
package org.jclouds.cloudservers;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
@ -36,6 +36,6 @@ import javax.inject.Qualifier;
|
|||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||
@Qualifier
|
||||
public @interface CloudServers {
|
||||
public @interface ServerManagement {
|
||||
|
||||
}
|
|
@ -19,19 +19,28 @@
|
|||
|
||||
package org.jclouds.cloudservers.config;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.cloudservers.CloudServersAsyncClient;
|
||||
import org.jclouds.cloudservers.CloudServersClient;
|
||||
import org.jclouds.cloudservers.ServerManagement;
|
||||
import org.jclouds.cloudservers.handlers.ParseCloudServersErrorFromHttpResponse;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.cloudservers.CloudServersAsyncClient;
|
||||
import org.jclouds.cloudservers.CloudServersClient;
|
||||
import org.jclouds.cloudservers.handlers.ParseCloudServersErrorFromHttpResponse;
|
||||
import org.jclouds.rackspace.config.RackspaceAuthenticationRestModule;
|
||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
|
||||
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
|
||||
import org.jclouds.openstack.reference.AuthHeaders;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -39,34 +48,38 @@ import com.google.inject.Module;
|
|||
*/
|
||||
@ConfiguresRestClient
|
||||
@RequiresHttp
|
||||
public class CloudServersRestClientModule extends
|
||||
RestClientModule<CloudServersClient, CloudServersAsyncClient> {
|
||||
public class CloudServersRestClientModule extends RestClientModule<CloudServersClient, CloudServersAsyncClient> {
|
||||
|
||||
private Module authModule;
|
||||
private final OpenStackAuthenticationModule module;
|
||||
|
||||
public CloudServersRestClientModule() {
|
||||
this(new RackspaceAuthenticationRestModule());
|
||||
public CloudServersRestClientModule(OpenStackAuthenticationModule module) {
|
||||
super(CloudServersClient.class, CloudServersAsyncClient.class);
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
public CloudServersRestClientModule(Module authModule) {
|
||||
super(CloudServersClient.class, CloudServersAsyncClient.class);
|
||||
this.authModule = authModule;
|
||||
public CloudServersRestClientModule() {
|
||||
this(new OpenStackAuthenticationModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(authModule);
|
||||
install(module);
|
||||
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||
super.configure();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
|
||||
ParseCloudServersErrorFromHttpResponse.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(
|
||||
ParseCloudServersErrorFromHttpResponse.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(
|
||||
ParseCloudServersErrorFromHttpResponse.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseCloudServersErrorFromHttpResponse.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseCloudServersErrorFromHttpResponse.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseCloudServersErrorFromHttpResponse.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@ServerManagement
|
||||
protected URI provideServerUrl(AuthenticationResponse response) {
|
||||
return response.getServices().get(AuthHeaders.SERVER_MANAGEMENT_URL);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.cloudservers.options;
|
|||
|
||||
import java.util.Date;
|
||||
|
||||
import org.jclouds.rackspace.options.BaseListOptions;
|
||||
import org.jclouds.openstack.options.BaseListOptions;
|
||||
|
||||
/**
|
||||
* Options used to control the amount of detail in the request.
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
package org.jclouds.cloudservers;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||
import static org.jclouds.cloudservers.options.CreateServerOptions.Builder.withFile;
|
||||
import static org.jclouds.cloudservers.options.CreateServerOptions.Builder.withMetadata;
|
||||
import static org.jclouds.cloudservers.options.CreateServerOptions.Builder.withSharedIpGroup;
|
||||
|
@ -26,21 +28,18 @@ import static org.jclouds.cloudservers.options.CreateSharedIpGroupOptions.Builde
|
|||
import static org.jclouds.cloudservers.options.ListOptions.Builder.changesSince;
|
||||
import static org.jclouds.cloudservers.options.ListOptions.Builder.withDetails;
|
||||
import static org.jclouds.cloudservers.options.RebuildServerOptions.Builder.withImage;
|
||||
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.functions.ReleasePayloadAndReturn;
|
||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.cloudservers.config.CloudServersRestClientModule;
|
||||
import org.jclouds.cloudservers.domain.BackupSchedule;
|
||||
import org.jclouds.cloudservers.domain.DailyBackup;
|
||||
|
@ -50,9 +49,17 @@ import org.jclouds.cloudservers.options.CreateServerOptions;
|
|||
import org.jclouds.cloudservers.options.CreateSharedIpGroupOptions;
|
||||
import org.jclouds.cloudservers.options.ListOptions;
|
||||
import org.jclouds.cloudservers.options.RebuildServerOptions;
|
||||
import org.jclouds.rackspace.TestRackspaceAuthenticationRestClientModule;
|
||||
import org.jclouds.rackspace.filters.AddTimestampQuery;
|
||||
import org.jclouds.rackspace.filters.AuthenticateRequest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.http.functions.ReleasePayloadAndReturn;
|
||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.openstack.TestOpenStackAuthenticationModule;
|
||||
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
|
||||
import org.jclouds.openstack.filters.AddTimestampQuery;
|
||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.RestClientTest;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
import org.jclouds.rest.RestContextSpec;
|
||||
|
@ -860,13 +867,38 @@ public class CloudServersAsyncClientTest extends RestClientTest<CloudServersAsyn
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module createModule() {
|
||||
return new CloudServersRestClientModule(new TestRackspaceAuthenticationRestClientModule());
|
||||
return new TestCloudServersRestClientModule();
|
||||
}
|
||||
|
||||
@ConfiguresRestClient
|
||||
@RequiresHttp
|
||||
protected static class TestCloudServersRestClientModule extends CloudServersRestClientModule {
|
||||
private TestCloudServersRestClientModule() {
|
||||
super(new TestOpenStackAuthenticationModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestContextSpec<CloudServersClient, CloudServersAsyncClient> createContextSpec() {
|
||||
return new RestContextFactory().createContextSpec("cloudservers", "user", "password", new Properties());
|
||||
protected URI provideServerUrl(AuthenticationResponse response) {
|
||||
return URI.create("http://serverManagementUrl");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String provider = "cloudservers";
|
||||
|
||||
@Override
|
||||
public RestContextSpec<CloudServersClient, CloudServersAsyncClient> createContextSpec() {
|
||||
return new RestContextFactory().createContextSpec(provider, "user", "password", new Properties());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Properties getProperties() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(PROPERTY_REGIONS, "US");
|
||||
properties.setProperty(PROPERTY_ENDPOINT, "https://auth");
|
||||
properties.setProperty(PROPERTY_API_VERSION, "1");
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,11 @@ import java.io.InputStream;
|
|||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.cloudservers.domain.Addresses;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudservers.domain.Addresses;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -46,7 +45,7 @@ import com.google.inject.TypeLiteral;
|
|||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ParseAddressesFromJsonResponseTest {
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new GsonModule());
|
||||
|
||||
public void testApplyInputStreamDetails() throws UnknownHostException {
|
||||
InputStream is = getClass().getResourceAsStream("/test_list_addresses.json");
|
||||
|
|
|
@ -24,14 +24,13 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.io.InputStream;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.jclouds.cloudservers.domain.BackupSchedule;
|
||||
import org.jclouds.cloudservers.domain.DailyBackup;
|
||||
import org.jclouds.cloudservers.domain.WeeklyBackup;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudservers.domain.BackupSchedule;
|
||||
import org.jclouds.cloudservers.domain.DailyBackup;
|
||||
import org.jclouds.cloudservers.domain.WeeklyBackup;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
|
@ -46,7 +45,7 @@ import com.google.inject.TypeLiteral;
|
|||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ParseBackupScheduleFromJsonResponseTest {
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new GsonModule());
|
||||
|
||||
public void testApplyInputStreamDetails() throws UnknownHostException {
|
||||
InputStream is = getClass().getResourceAsStream("/test_list_backupschedule.json");
|
||||
|
|
|
@ -23,12 +23,11 @@ import static org.testng.Assert.assertEquals;
|
|||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.jclouds.cloudservers.domain.Flavor;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudservers.domain.Flavor;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
@ -53,10 +52,9 @@ public class ParseFlavorFromJsonResponseTest {
|
|||
}
|
||||
|
||||
public static Flavor parseFlavor() {
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new GsonModule());
|
||||
|
||||
InputStream is = ParseFlavorFromJsonResponseTest.class
|
||||
.getResourceAsStream("/test_get_flavor_details.json");
|
||||
InputStream is = ParseFlavorFromJsonResponseTest.class.getResourceAsStream("/test_get_flavor_details.json");
|
||||
|
||||
UnwrapOnlyJsonValue<Flavor> parser = i.getInstance(Key.get(new TypeLiteral<UnwrapOnlyJsonValue<Flavor>>() {
|
||||
}));
|
||||
|
|
|
@ -25,12 +25,11 @@ import java.io.InputStream;
|
|||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.cloudservers.domain.Flavor;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudservers.domain.Flavor;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -47,7 +46,7 @@ import com.google.inject.TypeLiteral;
|
|||
@Test(groups = "unit")
|
||||
public class ParseFlavorListFromJsonResponseTest {
|
||||
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new GsonModule());
|
||||
|
||||
public void testApplyInputStream() {
|
||||
InputStream is = getClass().getResourceAsStream("/test_list_flavors.json");
|
||||
|
|
|
@ -24,16 +24,18 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.io.InputStream;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.jclouds.cloudservers.domain.Image;
|
||||
import org.jclouds.cloudservers.domain.ImageStatus;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudservers.domain.Image;
|
||||
import org.jclouds.cloudservers.domain.ImageStatus;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
|
@ -46,7 +48,14 @@ import com.google.inject.TypeLiteral;
|
|||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ParseImageFromJsonResponseTest {
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||
}
|
||||
|
||||
}, new GsonModule());
|
||||
|
||||
DateService dateService = i.getInstance(DateService.class);
|
||||
|
||||
|
@ -64,10 +73,16 @@ public class ParseImageFromJsonResponseTest {
|
|||
}
|
||||
|
||||
public static Image parseImage() {
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new AbstractModule() {
|
||||
|
||||
InputStream is = ParseImageFromJsonResponseTest.class
|
||||
.getResourceAsStream("/test_get_image_details.json");
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||
}
|
||||
|
||||
}, new GsonModule());
|
||||
|
||||
InputStream is = ParseImageFromJsonResponseTest.class.getResourceAsStream("/test_get_image_details.json");
|
||||
|
||||
UnwrapOnlyJsonValue<Image> parser = i.getInstance(Key.get(new TypeLiteral<UnwrapOnlyJsonValue<Image>>() {
|
||||
}));
|
||||
|
|
|
@ -25,17 +25,19 @@ import java.io.InputStream;
|
|||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.cloudservers.domain.Image;
|
||||
import org.jclouds.cloudservers.domain.ImageStatus;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudservers.domain.Image;
|
||||
import org.jclouds.cloudservers.domain.ImageStatus;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
|
@ -48,7 +50,14 @@ import com.google.inject.TypeLiteral;
|
|||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ParseImageListFromJsonResponseTest {
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||
}
|
||||
|
||||
},new GsonModule());
|
||||
DateService dateService = i.getInstance(DateService.class);
|
||||
|
||||
public void testApplyInputStream() {
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.jclouds.http.HttpResponse;
|
|||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -46,7 +45,7 @@ import com.google.inject.TypeLiteral;
|
|||
@Test(groups = "unit")
|
||||
public class ParseInetAddressListFromJsonResponseTest {
|
||||
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new GsonModule());
|
||||
|
||||
public void testPublic() throws UnknownHostException {
|
||||
InputStream is = getClass().getResourceAsStream("/test_list_addresses_public.json");
|
||||
|
|
|
@ -25,14 +25,13 @@ import java.io.InputStream;
|
|||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.cloudservers.domain.Addresses;
|
||||
import org.jclouds.cloudservers.domain.Server;
|
||||
import org.jclouds.cloudservers.domain.ServerStatus;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudservers.domain.Addresses;
|
||||
import org.jclouds.cloudservers.domain.Server;
|
||||
import org.jclouds.cloudservers.domain.ServerStatus;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
@ -71,7 +70,7 @@ public class ParseServerFromJsonResponseTest {
|
|||
}
|
||||
|
||||
public static Server parseServer() {
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new GsonModule());
|
||||
|
||||
InputStream is = ParseServerFromJsonResponseTest.class.getResourceAsStream("/test_get_server_detail.json");
|
||||
|
||||
|
|
|
@ -25,14 +25,13 @@ import java.io.InputStream;
|
|||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.cloudservers.domain.Addresses;
|
||||
import org.jclouds.cloudservers.domain.Server;
|
||||
import org.jclouds.cloudservers.domain.ServerStatus;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudservers.domain.Addresses;
|
||||
import org.jclouds.cloudservers.domain.Server;
|
||||
import org.jclouds.cloudservers.domain.ServerStatus;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -51,7 +50,7 @@ import com.google.inject.TypeLiteral;
|
|||
@Test(groups = "unit")
|
||||
public class ParseServerListFromJsonResponseTest {
|
||||
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new GsonModule());
|
||||
|
||||
public void testApplyInputStream() {
|
||||
InputStream is = getClass().getResourceAsStream("/test_list_servers.json");
|
||||
|
|
|
@ -24,12 +24,11 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.io.InputStream;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.jclouds.cloudservers.domain.SharedIpGroup;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudservers.domain.SharedIpGroup;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -46,7 +45,7 @@ import com.google.inject.TypeLiteral;
|
|||
@Test(groups = "unit")
|
||||
public class ParseSharedIpGroupFromJsonResponseTest {
|
||||
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new GsonModule());
|
||||
|
||||
public void testApplyInputStreamDetails() throws UnknownHostException {
|
||||
InputStream is = getClass().getResourceAsStream("/test_get_sharedipgroup_details.json");
|
||||
|
|
|
@ -25,12 +25,11 @@ import java.io.InputStream;
|
|||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.cloudservers.domain.SharedIpGroup;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.cloudservers.domain.SharedIpGroup;
|
||||
import org.jclouds.rackspace.config.RackspaceParserModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -47,7 +46,7 @@ import com.google.inject.TypeLiteral;
|
|||
@Test(groups = "unit")
|
||||
public class ParseSharedIpGroupListFromJsonResponseTest {
|
||||
|
||||
Injector i = Guice.createInjector(new RackspaceParserModule(), new GsonModule());
|
||||
Injector i = Guice.createInjector(new GsonModule());
|
||||
|
||||
public void testApplyInputStream() {
|
||||
InputStream is = getClass().getResourceAsStream("/test_list_sharedipgroups.json");
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.rackspace;
|
||||
package org.jclouds.openstack;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.openstack;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.HeaderParam;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.jclouds.openstack.functions.ParseAuthenticationResponseFromHeaders;
|
||||
import org.jclouds.openstack.reference.AuthHeaders;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* Provides access to Rackspace resources via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @see <a href="http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Path("/v" + OpenStackAuthAsyncClient.VERSION)
|
||||
public interface OpenStackAuthAsyncClient {
|
||||
public static final String VERSION = "1.0";
|
||||
|
||||
public static class AuthenticationResponse {
|
||||
private final String authToken;
|
||||
private Map<String, URI> services;
|
||||
|
||||
public AuthenticationResponse(String authToken, Map<String, URI> services) {
|
||||
this.authToken = checkNotNull(authToken, "authToken");
|
||||
this.services = ImmutableMap.copyOf(checkNotNull(services, "services"));
|
||||
}
|
||||
|
||||
public Map<String, URI> getServices() {
|
||||
return services;
|
||||
}
|
||||
|
||||
public void setEndpoints(Map<String, URI> services) {
|
||||
this.services = services;
|
||||
}
|
||||
|
||||
public String getAuthToken() {
|
||||
return authToken;
|
||||
}
|
||||
|
||||
// performance isn't a concern on a infrequent object like this, so using shortcuts;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(authToken, services);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (that == null)
|
||||
return false;
|
||||
return Objects.equal(this.toString(), that.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this).add("authToken", authToken).add("services", services).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@GET
|
||||
@ResponseParser(ParseAuthenticationResponseFromHeaders.class)
|
||||
ListenableFuture<AuthenticationResponse> authenticate(@HeaderParam(AuthHeaders.AUTH_USER) String user,
|
||||
@HeaderParam(AuthHeaders.AUTH_KEY) String key);
|
||||
}
|
|
@ -17,11 +17,11 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.rackspace.config;
|
||||
package org.jclouds.openstack.config;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
|
@ -32,33 +32,27 @@ import org.jclouds.Constants;
|
|||
import org.jclouds.concurrent.RetryOnTimeOutExceptionSupplier;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.rackspace.Authentication;
|
||||
import org.jclouds.rackspace.CloudFiles;
|
||||
import org.jclouds.rackspace.CloudFilesCDN;
|
||||
import org.jclouds.rackspace.CloudServers;
|
||||
import org.jclouds.rackspace.RackspaceAuthAsyncClient;
|
||||
import org.jclouds.rackspace.RackspaceAuthAsyncClient.AuthenticationResponse;
|
||||
import org.jclouds.openstack.Authentication;
|
||||
import org.jclouds.openstack.OpenStackAuthAsyncClient;
|
||||
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
|
||||
import org.jclouds.rest.AsyncClientFactory;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.base.Throwables;
|
||||
import java.util.concurrent.Future;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* Configures the Rackspace authentication service connection, including logging
|
||||
* and http transport.
|
||||
* Configures the Rackspace authentication service connection, including logging and http transport.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequiresHttp
|
||||
public class RackspaceAuthenticationRestModule extends AbstractModule {
|
||||
public class OpenStackAuthenticationModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new RackspaceParserModule());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,12 +73,13 @@ public class RackspaceAuthenticationRestModule extends AbstractModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
Supplier<AuthenticationResponse> provideAuthenticationResponseCache(final AsyncClientFactory factory,
|
||||
@Named(Constants.PROPERTY_IDENTITY) final String user, @Named(Constants.PROPERTY_CREDENTIAL) final String key) {
|
||||
@Named(Constants.PROPERTY_IDENTITY) final String user,
|
||||
@Named(Constants.PROPERTY_CREDENTIAL) final String key) {
|
||||
return Suppliers.memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier<AuthenticationResponse>(
|
||||
new Supplier<AuthenticationResponse>() {
|
||||
public AuthenticationResponse get() {
|
||||
try {
|
||||
Future<AuthenticationResponse> response = factory.create(RackspaceAuthAsyncClient.class)
|
||||
Future<AuthenticationResponse> response = factory.create(OpenStackAuthAsyncClient.class)
|
||||
.authenticate(user, key);
|
||||
return response.get(30, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
|
@ -114,24 +109,4 @@ public class RackspaceAuthenticationRestModule extends AbstractModule {
|
|||
return supplier.get();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@CloudFiles
|
||||
protected URI providestroageUrl(AuthenticationResponse response) {
|
||||
return response.getStorageUrl();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@CloudServers
|
||||
protected URI provideServerUrl(AuthenticationResponse response) {
|
||||
return response.getServerManagementUrl();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@CloudFilesCDN
|
||||
protected URI provideCDNUrl(AuthenticationResponse response) {
|
||||
return response.getCDNManagementUrl();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue