Issue 429: pulled cloudfiles-specific logic apart from swift

This commit is contained in:
Adrian Cole 2011-01-09 10:32:35 -08:00
parent e68a67042e
commit 17629960cd
136 changed files with 2034 additions and 1570 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@
* ====================================================================
*/
package org.jclouds.cloudfiles.blobstore.functions;
package org.jclouds.openstack.swift.blobstore.functions;
import javax.inject.Singleton;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@
* ====================================================================
*/
package org.jclouds.cloudfiles.domain;
package org.jclouds.openstack.swift.domain;
/**
*

View File

@ -17,7 +17,7 @@
* ====================================================================
*/
package org.jclouds.cloudfiles.domain;
package org.jclouds.openstack.swift.domain;
/**

View File

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

View File

@ -17,7 +17,7 @@
* ====================================================================
*/
package org.jclouds.cloudfiles.domain;
package org.jclouds.openstack.swift.domain;
import java.util.Date;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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]+_[^/]+/";

View File

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

View File

@ -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.
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@
* ====================================================================
*/
package org.jclouds.rackspace;
package org.jclouds.openstack;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;

View File

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

View File

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